Last active
June 25, 2018 09:42
-
-
Save Nutomic/528ac465df545f34193b to your computer and use it in GitHub Desktop.
Create Intent Chooser with Application Whitelist. Based on https://gist.github.com/mediavrog/5625602
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package de.videmic.view; | |
import android.content.Intent; | |
import android.content.pm.PackageManager; | |
import android.content.pm.ResolveInfo; | |
import android.os.Parcelable; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.HashMap; | |
import java.util.List; | |
public class CustomChooserIntent { | |
/** | |
* Creates a chooser that only shows installed apps that are allowed by the whitelist. | |
* | |
* @param pm PackageManager instance. | |
* @param target The intent to share. | |
* @param title The title of the chooser dialog. | |
* @param whitelist A list of package names that are allowed to show. | |
* @return Updated intent, to be passed to {@link android.content.Context#startActivity}. | |
*/ | |
public static Intent create(PackageManager pm, Intent target, String title, | |
List<String> whitelist) { | |
Intent dummy = new Intent(target.getAction()); | |
dummy.setType(target.getType()); | |
List<ResolveInfo> resInfo = pm.queryIntentActivities(dummy, 0); | |
List<HashMap<String, String>> metaInfo = new ArrayList<>(); | |
for (ResolveInfo ri : resInfo) { | |
if (ri.activityInfo == null || !whitelist.contains(ri.activityInfo.packageName)) | |
continue; | |
HashMap<String, String> info = new HashMap<>(); | |
info.put("packageName", ri.activityInfo.packageName); | |
info.put("className", ri.activityInfo.name); | |
info.put("simpleName", String.valueOf(ri.activityInfo.loadLabel(pm))); | |
metaInfo.add(info); | |
} | |
if (metaInfo.isEmpty()) { | |
// Force empty chooser by setting a nonexistent target class. | |
Intent emptyIntent = (Intent) target.clone(); | |
emptyIntent.setPackage("your.package.name"); | |
emptyIntent.setClassName("your.package.name", "NonExistingActivity"); | |
return Intent.createChooser(emptyIntent, title); | |
} | |
// Sort items by display name. | |
Collections.sort(metaInfo, new Comparator<HashMap<String, String>>() { | |
@Override | |
public int compare(HashMap<String, String> map, HashMap<String, String> map2) { | |
return map.get("simpleName").compareTo(map2.get("simpleName")); | |
} | |
}); | |
// create the custom intent list | |
List<Intent> targetedIntents = new ArrayList<>(); | |
for (HashMap<String, String> mi : metaInfo) { | |
Intent targetedShareIntent = (Intent) target.clone(); | |
targetedShareIntent.setPackage(mi.get("packageName")); | |
targetedShareIntent.setClassName(mi.get("packageName"), mi.get("className")); | |
targetedIntents.add(targetedShareIntent); | |
} | |
Intent chooserIntent = Intent.createChooser(targetedIntents.get(0), title); | |
targetedIntents.remove(0); | |
Parcelable[] targetedIntentsParcelable = | |
targetedIntents.toArray(new Parcelable[targetedIntents.size()]); | |
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntentsParcelable); | |
return chooserIntent; | |
} | |
} |
I found that when calling targetedIntents.get(0)/targetedIntents.remove(0) that item is added back to the list of apps as the last one. Since there is the sort called, this will mess up the sorted list.
I, instead, used the following:
Intent chooserIntent = Intent.createChooser(targetedIntents.remove(targetedIntents.size() -1), title);
you can use the built-in comparator (ResolveInfo.DisplayNameComparator
) instead:
List<ResolveInfo> resInfo = pm.queryIntentActivities(dummy, 0);
Collections.sort(resInfo, new ResolveInfo.DisplayNameComparator(getPackageManager()));
List<HashMap<String, String>> metaInfo = new ArrayList<>();
for (ResolveInfo ri : resInfo) {
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, I'm currently working on an app and would like to use this code if possible?