Search code examples
androidwidgetlaunching-application

Android widget launch App and detect App Not found


I need a simple home Widget to launch an external app (ex: whatsapp).

In my MainActivity extends AppWidgetProvider (onUpdate) I use this code to create a pending intent and work great if the App is installed.

Intent intent = new Intent();
ComponentName cn = new ComponentName("com.whatsapp", "com.whatsapp.Main");
intent.setComponent(cn);

PendingIntent pending = PendingIntent.getActivity(context, 0, intent, 0);

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.activity_main);
views.setOnClickPendingIntent(R.id.imageView, pending);

appWidgetManager.updateAppWidget(currentWidgetId, views);

In the (onReceive) section i use this code for detect if the App is installed

 PackageManager pm = context.getPackageManager();

        List<ApplicationInfo> list = pm.getInstalledApplications(0);

        for (int aa = 0; aa < list.size(); aa++) {         
            if(list.get(aa).packageName.equals("com.whatsapp")){  
                 //app istalled
                noapp = 0;
            }
            else{
                //app not istalled
                noapp1 = 1;         
            }
        }         
    if(noapp1==1){
    Toast.makeText(context, "Whatsapp not installed", Toast.LENGTH_SHORT).show();
  }

My problem is: This code detect if the App is not installed and display the Toast message but only the first time the widget is positioned in the home. I need to display the message any time the imageview is touched if the App is not installed. Please Help!

Karakuri I try to apply your suggestion. This is my code in the main activity for attach the intent to the imageView:

public class MainActivity extends AppWidgetProvider{

public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {
    for(int i=0; i<appWidgetIds.length; i++){
        int currentWidgetId = appWidgetIds[i];

        Intent intent = new Intent(LaunchExternalAppReceiver.ACTION);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.activity_main);
        views.setOnClickPendingIntent(R.id.imageView, pendingIntent); 
        // Tell the AppWidgetManager to perform an update on the current App Widget
        appWidgetManager.updateAppWidget(currentWidgetId, views);

    }      
  }   
}

And this the new class with BroadcastReceiver (I put inside my simpele code to check if the App is installed, just for test):

public class LaunchExternalAppReceiver extends BroadcastReceiver {
public static final String ACTION = "control";

@Override
public void onReceive(Context context, Intent intent) {

    PackageManager pm = context.getPackageManager();

    List<ApplicationInfo> list = pm.getInstalledApplications(0);

    for (int aa = 0; aa < list.size(); aa++) {  

        if(list.get(aa).packageName.equals("com.whatsapp")){  
            //app istalled

        }
        else{
            //app not istalled             
            Toast.makeText(context, "Whatsapp not installed", Toast.LENGTH_SHORT).show();
        }
    }             
  }
}

This is my Manifest:

 <uses-sdk
    android:minSdkVersion="11"
    android:targetSdkVersion="19" /><application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <receiver android:name=".MainActivity" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>

        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/mywidget" />
    </receiver>
    <receiver android:name=".LaunchExternalAppReceiver" >
        <intent-filter>
            <action android:name="control" >
            </action>
        </intent-filter>
    </receiver>
</application>

Thanks a lot for your help.


Solution

  • I found an alternative solution. Work greet but have an annoying little problem. I attach an intent to the imageView in my main activity to launch a new class "control" in this class i check if the app is installed and launch her or send a message and offer a download button. The problem is...if the app is installed the control class launch her but for a second appear the activity (control) screen before App open. Very annoying. Someone can help me to make this final fix? Thanks.

    In onUpdate (main activity):

        Intent controlIntent = new Intent(context, Control.class);          
        PendingIntent pendingc1 = PendingIntent.getActivity(context, 0, controlIntent, 0);
        RemoteViews views1 = new RemoteViews(context.getPackageName(), R.layout.activity_main);
        views1.setOnClickPendingIntent(R.id.imageView, pendingc1);
        appWidgetManager.updateAppWidget(currentWidgetId, views1); 
    

    My new class (control):

    public class Control extends Activity {
    private TextView testo;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        PackageManager pm = this.getPackageManager();
    
        List<ApplicationInfo> list = pm.getInstalledApplications(0);
    
        for (int aa = 0; aa < list.size(); aa++) {
    
            if (list.get(aa).packageName.equals("com.whatsapp")) {
                // app istalled
    
                Intent launchIntent = getPackageManager()
                        .getLaunchIntentForPackage("com.whatsapp");
                startActivity(launchIntent);
                Control.this.finish();
    
            } else {
                setContentView(R.layout.control);
                // app not istalled
                testo = (TextView) findViewById(R.id.message);
                String text = "WhatsApp is Not Installed\nPlease Download Whatsapp from Play Store";
                testo.setText(text);
    
                Button button = (Button) findViewById(R.id.exit);
                button.setOnClickListener(new View.OnClickListener() {
    
                    public void onClick(View v) {
                        Control.this.finish();
                    }
                });
    
                Button button2 = (Button) findViewById(R.id.download);
                button2.setOnClickListener(new View.OnClickListener() {
    
                    public void onClick(View v) {
                        startActivity(new Intent(Intent.ACTION_VIEW, Uri
                                .parse("market://details?id=" + "com.whatsapp")));
                        Control.this.finish();
                    }
                });
    
            }
        }
      }
    }