自定义意图选择器 - 为什么在 Android 6 上它显示空单元格?
Custom intent-chooser - why on Android 6 does it show empty cells?
背景
我希望展示本机 intent-chooser,同时能够对其进行一些自定义。
为此,我找到了下一个 Whosebug 线程:
How to customize share intent in Android?
问题
事情是,当我在 Android 5.x 及以下使用建议的代码时,一切似乎都很好,但是当我在 Android 6.0.1 上使用它时(经过测试在 Nexus 5 和模拟器上,当有多个应用程序与之共享内容时),我得到空单元格,有时甚至是空应用程序名称,例如:
使用非自定义的 intent-chooser 时不会出现:
startActivity(Intent.createChooser(intent, "default chooser"));
代码
看到解决方案,我创建了下一个代码:
private void test(Intent shareIntent) {
List<Intent> targetedShareIntents = new ArrayList<>();
final List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(shareIntent, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo resolveInfo : resInfo) {
Intent targetedShareIntent = new Intent(shareIntent);
targetedShareIntent.setClassName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
targetedShareIntents.add(targetedShareIntent);
}
Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(targetedShareIntents.size() - 1), "Select app to share");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[targetedShareIntents.size()]));
startActivity(chooserIntent);
}
}
private void prepareIntentToShare(Intent intent) {
intent.setAction(android.content.Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_STREAM, mUri);
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "title");
intent.putExtra(android.content.Intent.EXTRA_TEXT, "body");
}
以及测试方法:
Intent intent = new Intent();
prepareIntentToShare(intent);
test(intent);
我试过的
我试图改变意图中的各种东西,但没有任何运气。我也试图找出意图的顺序是什么(因为这可能很重要),但我没有找到。
最后,我决定 post 将其更改为 Google,假设这是一个错误:
https://code.google.com/p/android/issues/detail?id=202693
问题
为什么会发生?我可以以某种方式修复它,同时仍然使用本机意图选择器吗?怎么只出现在Android6及以上?
我怎样才能在其中为每个项目输入正确的名称,例如,我看到 "twitter" 两次,但其他应用程序确实显示了正确的名称(例如 qr -代码扫描仪)?
是否可以保留应用程序排序的本机行为,如使用显示意图选择器的简单方式所示?也许按照应有的顺序获取应用程序列表?
我花了一些时间阅读 ChooserActivity
和 ResolverActivity
并解决了这些问题。
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, 0);
if (resolveInfos != null && !resolveInfos.isEmpty()) {
List<Intent> targetIntents = new ArrayList<>();
for (ResolveInfo resolveInfo : resolveInfos) {
ActivityInfo activityInfo = resolveInfo.activityInfo;
// remove activities which packageName contains 'ttt' for example
if (activityInfo.packageName.contains("ttt")) {
continue;
}
Intent targetIntent = new Intent(Intent.ACTION_SEND);
targetIntent.setType("text/plain");
targetIntent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.setting_share_app_subject));
targetIntent.putExtra(Intent.EXTRA_TEXT, context.getString(R.string.setting_share_app_body));
targetIntent.setPackage(activityInfo.packageName);
targetIntent.setComponent(new ComponentName(activityInfo.packageName, activityInfo.name));
// wrap with LabeledIntent to show correct name and icon
LabeledIntent labeledIntent = new LabeledIntent(targetIntent, activityInfo.packageName, resolveInfo.labelRes, resolveInfo.icon);
// add filtered intent to a list
targetIntents.add(labeledIntent);
}
Intent chooserIntent;
// deal with M list seperate problem
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// create chooser with empty intent in M could fix the empty cells problem
chooserIntent = Intent.createChooser(new Intent(), context.getString(R.string.setting_share_app_title));
} else {
// create chooser with one target intent below M
chooserIntent = Intent.createChooser(targetIntents.remove(0), context.getString(R.string.setting_share_app_title));
}
if (chooserIntent == null) {
return;
}
// add initial intents
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[targetIntents.size()]));
try {
context.startActivity(chooserIntent);
} catch (ActivityNotFoundException e) {
Logger.e(TAG, e, e);
}
}
编辑:似乎出现在 Android Q (10 - API 29) 这已损坏,最多只显示 2 个项目而不是所有项目。又问了这个here.
编辑:做了一个选择要从共享中排除的项目的示例,,它应该适用于所有 Android 版本。
背景
我希望展示本机 intent-chooser,同时能够对其进行一些自定义。
为此,我找到了下一个 Whosebug 线程:
How to customize share intent in Android?
问题
事情是,当我在 Android 5.x 及以下使用建议的代码时,一切似乎都很好,但是当我在 Android 6.0.1 上使用它时(经过测试在 Nexus 5 和模拟器上,当有多个应用程序与之共享内容时),我得到空单元格,有时甚至是空应用程序名称,例如:
使用非自定义的 intent-chooser 时不会出现:
startActivity(Intent.createChooser(intent, "default chooser"));
代码
看到解决方案,我创建了下一个代码:
private void test(Intent shareIntent) {
List<Intent> targetedShareIntents = new ArrayList<>();
final List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(shareIntent, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo resolveInfo : resInfo) {
Intent targetedShareIntent = new Intent(shareIntent);
targetedShareIntent.setClassName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
targetedShareIntents.add(targetedShareIntent);
}
Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(targetedShareIntents.size() - 1), "Select app to share");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[targetedShareIntents.size()]));
startActivity(chooserIntent);
}
}
private void prepareIntentToShare(Intent intent) {
intent.setAction(android.content.Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_STREAM, mUri);
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "title");
intent.putExtra(android.content.Intent.EXTRA_TEXT, "body");
}
以及测试方法:
Intent intent = new Intent();
prepareIntentToShare(intent);
test(intent);
我试过的
我试图改变意图中的各种东西,但没有任何运气。我也试图找出意图的顺序是什么(因为这可能很重要),但我没有找到。
最后,我决定 post 将其更改为 Google,假设这是一个错误:
https://code.google.com/p/android/issues/detail?id=202693
问题
为什么会发生?我可以以某种方式修复它,同时仍然使用本机意图选择器吗?怎么只出现在Android6及以上?
我怎样才能在其中为每个项目输入正确的名称,例如,我看到 "twitter" 两次,但其他应用程序确实显示了正确的名称(例如 qr -代码扫描仪)?
是否可以保留应用程序排序的本机行为,如使用显示意图选择器的简单方式所示?也许按照应有的顺序获取应用程序列表?
我花了一些时间阅读 ChooserActivity
和 ResolverActivity
并解决了这些问题。
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(intent, 0);
if (resolveInfos != null && !resolveInfos.isEmpty()) {
List<Intent> targetIntents = new ArrayList<>();
for (ResolveInfo resolveInfo : resolveInfos) {
ActivityInfo activityInfo = resolveInfo.activityInfo;
// remove activities which packageName contains 'ttt' for example
if (activityInfo.packageName.contains("ttt")) {
continue;
}
Intent targetIntent = new Intent(Intent.ACTION_SEND);
targetIntent.setType("text/plain");
targetIntent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.setting_share_app_subject));
targetIntent.putExtra(Intent.EXTRA_TEXT, context.getString(R.string.setting_share_app_body));
targetIntent.setPackage(activityInfo.packageName);
targetIntent.setComponent(new ComponentName(activityInfo.packageName, activityInfo.name));
// wrap with LabeledIntent to show correct name and icon
LabeledIntent labeledIntent = new LabeledIntent(targetIntent, activityInfo.packageName, resolveInfo.labelRes, resolveInfo.icon);
// add filtered intent to a list
targetIntents.add(labeledIntent);
}
Intent chooserIntent;
// deal with M list seperate problem
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// create chooser with empty intent in M could fix the empty cells problem
chooserIntent = Intent.createChooser(new Intent(), context.getString(R.string.setting_share_app_title));
} else {
// create chooser with one target intent below M
chooserIntent = Intent.createChooser(targetIntents.remove(0), context.getString(R.string.setting_share_app_title));
}
if (chooserIntent == null) {
return;
}
// add initial intents
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[targetIntents.size()]));
try {
context.startActivity(chooserIntent);
} catch (ActivityNotFoundException e) {
Logger.e(TAG, e, e);
}
}
编辑:似乎出现在 Android Q (10 - API 29) 这已损坏,最多只显示 2 个项目而不是所有项目。又问了这个here.
编辑:做了一个选择要从共享中排除的项目的示例,