Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove app from IntentChooser in android

I have an android app which can open specific urls. So in my Manifest I add intent-filter section like this:

<intent-filter>
    <data andriod:host="someurl.com"/>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <action android:name="android.intent.action.VIEW" />
</intent-filter>

When user clicks on my links(outside of the app) my app is shown as one of the apps that can open url and it's fine.

But I have links inside my app that can started with "someurl.com" and in this situation I should remove my app from IntentChooser dialog. I do this like below:

public Intent generateCustomChooserIntent(Intent prototype) throws Exception {
    List<Intent> targetedShareIntents = new ArrayList<Intent>();
    List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(prototype, 0);

    if (!resInfo.isEmpty()) {
        for (ResolveInfo resolveInfo : resInfo) {
            // do not include my app in intent chooser dialog
            if (resolveInfo.activityInfo == null || resolveInfo.activityInfo.packageName.equals(getPackageName())) {
                continue;
            }

            // add Intent to intent chooser dialog
            Intent targetedShareIntent = (Intent) prototype.clone();
            targetedShareIntent.setPackage(resolveInfo.activityInfo.packageName);
            targetedShareIntent.setClassName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
            targetedShareIntents.add(targetedShareIntent);
        }

        if (!targetedShareIntents.isEmpty()) {
            // pass new Intent to create no chooser in first row
            Intent chooserIntent = Intent.createChooser(targetedShareIntents.get(0), getString(R.string.open_link_with));
            targetedShareIntents.remove(0);

            // pass extra intent chooser
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[targetedShareIntents.size()]));
            return chooserIntent;
        }
    }

    // there is no appropriate intent to run
    throw new Exception();
}

And it's fine too.

But in some android devices(like samsung A5 2016) when I ask for intents which can handle url, it just return my app as appropriate app(and doesn't include apps like google chrome), then I remove my app from IntentChooser dialog, and then nothing left to choose from.

How can I solve this?

like image 944
Hojjat Avatar asked Sep 07 '25 07:09

Hojjat


1 Answers

There is workaround here which you can use like this

public Intent generateCustomChooserIntent(Context context, String url) throws Exception {
        Uri fakeUri = Uri.parse("https://www.google.com");
        Uri realUri = Uri.parse(url);
        Intent shareIntent = new Intent(Intent.ACTION_VIEW, fakeUri);
        List<ResolveInfo> resInfo;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            resInfo = context.getPackageManager().queryIntentActivities(
                    shareIntent, PackageManager.MATCH_ALL);
        } else {
            resInfo = context.getPackageManager().queryIntentActivities(
                    shareIntent, 0);
        }

        if (!resInfo.isEmpty()) {
            List<Intent> targetedShareIntents = removeCurrentApp(context, realUri, resInfo);

            if (!targetedShareIntents.isEmpty()) {
                // pass new Intent to create no chooser in first row
                Intent chooserIntent = Intent.createChooser(
                    targetedShareIntents.get(0), context.getString(R.string.open_link_with));
                targetedShareIntents.remove(0);

                // pass extra intent chooser
                chooserIntent.putExtra(
                        Intent.EXTRA_INITIAL_INTENTS,
                        targetedShareIntents.toArray(new Parcelable[targetedShareIntents.size()]));
                return chooserIntent;
            }
        }

        // there is no appropriate intent to run
        throw new Exception();
    }

    @NonNull
    private List<Intent> removeCurrentApp(Context context, Uri realUri, List<ResolveInfo> resInfo) {
        List<Intent> targetedShareIntents = new ArrayList<>();
        String currentPackageName = context.getPackageName();
        for (ResolveInfo resolveInfo : resInfo) {
            // do not include my app in intent chooser dialog
            if (resolveInfo.activityInfo == null) {
                continue;
            }
            String packageName = resolveInfo.activityInfo.packageName;
            if (currentPackageName.equalsIgnoreCase(packageName)) {
                continue;
            }

            Intent intent = new Intent(Intent.ACTION_VIEW, realUri);

            intent.setClassName(
                    resolveInfo.activityInfo.applicationInfo.packageName,
                    resolveInfo.activityInfo.name);
            intent.setPackage(packageName);
            targetedShareIntents.add(intent);
        }
        return targetedShareIntents;
    }
like image 150
hadilq Avatar answered Sep 08 '25 19:09

hadilq