Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Preferred/Default app on Android

I am trying to get the default/preferred application for a given Intent. For example, when the user installs a second web browser, then attempts to open a URL, he or she will get a dialog like this:

default browser selector

If the user then selects the Use by default for this action option, then the dialog box no longer opens when a URL is pressed.

I am working on an application that should be aware of what this default or preferred app/action is. How do I do this? I am currently using the code below, but getPreferredPackage doesn't return anything:

Intent i = (new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com"));
PackageManager pm = context.getPackageManager();
final List<ResolveInfo> list = pm.queryIntentActivities(i, 0);
IntentFilter ifilter = new IntentFilter(i.getAction());
if (i.getCategories() != null) {
    for(String category : i.getCategories()) {
        ifilter.addCategory(category);
    }
}
List<IntentFilter> filters = new ArrayList<IntentFilter>();
filters.add(ifilter);
List<ComponentName> preferredActivities = new ArrayList<ComponentName>();
pm.getPreferredActivities(filters, preferredActivities, null);
for (ComponentName activity : preferredActivities) {
    for (ResolveInfo rinfo : list) {
        if (rinfo.activityInfo.applicationInfo.packageName.equals(activity.getPackageName())) {
            try {
                final PackageInfo pi = pm.getPackageInfo(activity.getPackageName(), 0);
                Toast.makeText(context, pm.getApplicationLabel(pi.applicationInfo), Toast.LENGTH_SHORT).show();
            }
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }
    }
}

What am I doing wrong? Is this even the right approach?

like image 352
Phil Avatar asked Dec 24 '11 19:12

Phil


2 Answers

Well, the solution turned out to be much simpler than I made it (although this is very poorly documented). The following code is my solution:

Intent i = (new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com"));
PackageManager pm = context.getPackageManager();
final ResolveInfo mInfo = pm.resolveActivity(i, 0);
Toast.makeText(context, pm.getApplicationLabel(mInfo.activityInfo.applicationInfo), Toast.LENGTH_LONG).show();
like image 131
Phil Avatar answered Nov 13 '22 09:11

Phil


The method launchUrlInDefaultBrowser below launches a URL without displaying any selection query for the user. First, it tries to find the user's default browser app and launch the URL with it. Second, if there was no default app, it lists all the capable activities for launching the URL and picks up the first one. In case an activity was launched, the method returns true; otherwise, false.

boolean launchUrlInDefaultBrowser(Context context, String url) {
    final Intent browserIntent = new Intent(Intent.ACTION_VIEW);
    browserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    browserIntent.setData(Uri.parse(url));

    // 1: Try to find the default browser and launch the URL with it
    final ResolveInfo defaultResolution = context.getPackageManager().resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
    if (defaultResolution != null) {
        final ActivityInfo activity = defaultResolution.activityInfo;
        if (!activity.name.equals("com.android.internal.app.ResolverActivity")) {
            browserIntent.setClassName(activity.applicationInfo.packageName, activity.name);
            context.startActivity(launchIntent);
            return true;
        }
    }
    // 2: Try to find anything that we can launch the URL with. Pick up the first one that can.
    final List<ResolveInfo> resolveInfoList = context.getPackageManager().queryIntentActivities(browserIntent, PackageManager.MATCH_DEFAULT_ONLY);
    if (!resolveInfoList.isEmpty()) {
        browserIntent.setClassName(resolveInfoList.get(0).activityInfo.packageName, resolveInfoList.get(0).activityInfo.name);
        context.startActivity(browserIntent);
        return true;
    }
    return false;
}

Beware, the OEMs may have their own ResolverActivity implementation. E.g. Huawei has com.huawei.android.internal.app.HwResolverActivity.

like image 22
Juuso Ohtonen Avatar answered Nov 13 '22 11:11

Juuso Ohtonen