Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Android

Custom App Chooser in Android

4.83/5 (3 votes)
4 May 2016CPOL4 min read 22.9K  
How to develop a custom App Chooser to show SMS and Whatsapp in Chooser dialog

Introduction

You must have seen in your Android devices, when you click on a URL that you have received in an SMS, mail or whatsapp message or from some other means, if there is more than one application which can open the URL, it opens up a dialog that asks you which application you want to open it up with. The application which opens up this dialog is called Chooser Application. In this case, the applications which are shown in the dialog happen to be all the browsers that you have in your device along with any other application which is registered to open up the URL of this kind. Any application can register itself to handle or open up the URL and there is a way of doing it. But that is not the scope of this article. Here, we will focus on how to ensure that when a chooser dialog is opened up, you have only those applications that you want in it - not less not more.

You will find similar articles on the various platforms/blogs on the internet, but they do not explain clearly how it works. This post aims to clearly explain what it is doing.

Using the Code

In an Android application, suppose we want to send an SMS. Since there are other text applications which have become popular, we might want to give an option of those applications also to the end user. What we do is that we create an Intent, set the action type as Intent.ACTION_SEND, set the type as "text/plain" and start the activity passing this intent. This all works very well, it will open up a number of applications which might be used for opening up this intent. Just to iterate - Messaging, mail, notes, copy to clipboard, Google drive, Facebook, bluetooth are few of the applications that would be offered by chooser app to handle this intent. But our intention was to show only messaging app and whatsapp app in this chooser. This tip describes how we accomplish this.

The method sendMesaage is written down to do the same. The basic idea is as below:

First of all, we create an intent with the action ACTION_SEND and type as "text/plain" in smsIntent. The purpose of this intent is twofold - one is that we actually want the Messaging app to come up in the chooser dialog, and another one is that this will be used to create the ChooserIntent. This is explained below in the subsequent steps. You must have noticed that we are specifically keeping the package as "com.android.mms", this is to ensure that only SMS application is targeted else it will show the other apps like clipboard, gdrive and bluetooth.

Next, we create another intent of the same kind in another variable queryIntent, which will be used to query the package manager for similar activities which are target for this intent or system will resolve the intent to. The result from this query is taken in the list resolveInfo.

Remember, as we discussed earlier in the article, this list will consists of a number of applications from which we have to filter out unwanted ones. Here, we want only messaging and whatsapp applications to appear. This is what we are doing in the for loop. We are iterating through the list of all the resolve instances, checking with the package name to find out the resolves belonging to whatsapp.

We identify the whatsapp resolve by comparing the package name against "com.whatsap". Once, we get this resolve, creating an intent with the appropriate data, i.e. action, type, package and component and adding to the otherAppIntent list. This list is the which contains all the intents for the apps that we want to appear apart from SMS app. Here, we want only whatsapp.

Once out of the for loop, we need to create an intent, namely chooserIntent in code, to open up the Chooser app. This is done by passing the smsIntent that we have already created and setting the list of extra intents corresponding to the other apps that we want to be presented in the chooser dialog. In our case, we have the list in otherAppIntentList. This list is first required to be converted to a list of LabledIntents to be set into intent.

Then we send the chooserIntent to start an activity. This will open up the chooser dialog with messaging and whatsapp apps.

Java
/**
     * It shows the chooser app to send the message. It filters out other apps
     * on the chooser dialog and shows only Messaging and whatsapp apps.
     * @param message
     */
    public void sendMessage(String message) {        
        
        int SEND_MSG_REQUEST = 10;

        //Create primary intent to be used for chooser intent
        Intent smsIntent = new Intent();
        smsIntent.setAction(Intent.ACTION_SEND);
        smsIntent.setType("text/plain");
        //need to limit the scope of this intent to SMS app only. If we don't set the 
        //package here, it will target apps like bluetooth, clipboard etc also.
        smsIntent.setPackage("com.android.mms");
        smsIntent.putExtra("sms_body", message);

        //intent for adding other apps
        Intent queryIntent = new Intent(Intent.ACTION_SEND);
        queryIntent.setType("text/plain");

        PackageManager pm = getPackageManager();
        List<ResolveInfo> resolveInfos = pm.queryIntentActivities(queryIntent, 0);

        List<LabeledIntent> otherAppIntentList = new ArrayList<LabeledIntent>(); 
        //filter out all the other intents which we want to keep
        for (int i = 0; i < resInfo.size(); i++) {
            ResolveInfo ri = resolveInfos.get(i);
            String packageName = ri.activityInfo.packageName;
            Intent intentToAdd = new Intent();
            if (packageName.contains("com.whatsapp")) {
                //this is the intent we are interested in
                intentToAdd.setComponent(new ComponentName(packageName, ri.activityInfo.name));
                intentToAdd.setAction(Intent.ACTION_SEND);
                intentToAdd.setType("text/plain");
                intentToAdd.setPackage(packageName);
                intentToAdd.putExtra(Intent.EXTRA_TEXT, message);
                //add this intent to the list 
                otherAppIntentList.add(new LabeledIntent(intentToAdd, packageName, 
                     ri.loadLabel(pm), ri.icon)); 
            }
        }

        // convert intentList to array
        LabeledIntent[] extraIntents = otherAppIntentList.toArray(
                new LabeledIntent[ otherAppIntentList.size() ]);

        //create and add all the intents to chooser
        Intent chooserIntent = Intent.createChooser(smsIntent, getResources().getString(
                R.string.choose_activity_select_app_for_sending_msg));
        
        //add all the extra intents that we have created
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
        startActivityForResult(chooserIntent, SEND_MSG_REQUEST);
    }

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)