我想像Intent.createChooser(intent)一样创建一些自定义的“意图选择器”。的事情。
所以我首先需要枚举所有与提供可选数据的意图相匹配的活动,例如EXTRA_TEXT或EXTRA_STREAM。请参阅代码中的注释以了解实际问题。基本上,他们是 1)返回的意图通常被枚举,但为null(不可用) 2)不采用传入的intent(构造函数)数据,因此新的intent在没有任何extras / flags / etc.的情况下启动。
public class IntentChooserDialog extends Dialog implements OnItemClickListener {
private ListView mListView;
private ResolveInfo[] mResolveInfos;
private Bundle mIntentBundle;
private Activity mActivity;
public IntentChooserDialog(Activity activity, Intent intent, int theme) {
super(activity, theme);
setContentView(R.layout.dlg_intentchooser);
mIntentBundle = intent.getExtras();
mActivity = activity;
mListView = (ListView) findViewById(R.id.dlg_intentchooser_list);
mListView.setOnItemClickListener(this);
enumerateApps(activity, intent);
}
private void enumerateApps(Context context, Intent intent) {
final PackageManager packageManager = context.getPackageManager();
final List<ResolveInfo> entries = packageManager.queryIntentActivities(intent, 0);
mResolveInfos = entries.toArray(new ResolveInfo[] {});
ArrayList<String> appNames = new ArrayList<String>(entries.size());
final int entriesSize = entries.size();
for (int i = 0; i < entriesSize; ++i) {
// We only add an item if it's executable
final Intent launchIntent = packageManager.getLaunchIntentForPackage(mResolveInfos[i].activityInfo.packageName);
if (launchIntent != null) {
final String appName = mResolveInfos[i].activityInfo.applicationInfo.loadLabel(packageManager).toString();
appNames.add(appName);
}
}
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, R.layout.dlg_intentchooser_list_item, appNames);
mListView.setAdapter(adapter);
}
rride
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
final PackageManager packageManager = getContext().getPackageManager();
final Intent intent = packageManager.getLaunchIntentForPackage(mResolveInfos[position].activityInfo.packageName);
// intent often is still null! -> NullPointerException; but why, Im testing it when adding them into the mResolveInfo
// I need to provide ALL information passed to the intent we get in the constructor. So things like "addFlags" and "setType" etc. must be passed too somehow!
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtras(mIntentBundle); // extras are not added, as the intents are opened as if no extras were added. The "foreign" apps are just opened as if I opened them in the Launcher.
getContext().startActivity(intent);
}
}
在Intent中传递的构造函数中传递给Intent.createChooser的任何其他Intent都可以,所以 例如:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, mActivity.getString(R.string.action_openin_extraSubject));
shareIntent.putExtra(Intent.EXTRA_TEXT, mActivity.getString(R.string.action_openin_extraText));
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + fileName));
new IntentChooserDialog(this, shareIntent, 0).show();