Xamarin.Android调用Intent.CreateChooser时获取PackageName的问题
为什么你在OnActivityResult中拿不到选中应用的包名?
核心问题出在你使用的Intent.CreateChooser():这个方法会启动系统自带的选择器Activity,而这个系统选择器不会将用户选中的目标应用信息返回给你的OnActivityResult方法。当用户选完应用后,系统直接启动目标分享应用,选择器本身就结束了,所以你拿到的data参数自然是null。
解决方案:自己实现应用选择逻辑
要获取用户选中的应用包名,你需要跳过系统选择器,自己查询可处理分享的应用,然后展示自定义选择列表,这样在用户选择时就能直接拿到包名。
步骤1:查询所有支持文本分享的应用
首先用PackageManager获取所有能处理ACTION_SEND且类型为text/plain的应用:
private List<ResolveInfo> GetShareableApps() { var shareIntent = new Intent(Intent.ActionSend); shareIntent.SetType("text/plain"); return PackageManager.QueryIntentActivities(shareIntent, PackageInfoFlags.MatchDefaultOnly).ToList(); }
步骤2:展示自定义选择列表
把查询到的应用转换成可展示的列表项(包含应用图标、名称和包名),用AlertDialog或者自定义RecyclerView展示:
public void ShareText(string text) { var shareableApps = GetShareableApps(); if (!shareableApps.Any()) { Toast.MakeText(this, "No apps available to share", ToastLength.Short).Show(); return; } // 构建选项列表:显示应用名称 var appNames = shareableApps.Select(info => info.LoadLabel(PackageManager).ToString()).ToArray(); new AlertDialog.Builder(this) .SetTitle("Share via") .SetItems(appNames, (sender, args) => { // 用户选中了第args.Which个应用 var selectedApp = shareableApps[args.Which]; string selectedPackageName = selectedApp.ActivityInfo.PackageName; // 这里可以先保存包名,比如存到类变量里 _selectedPackageName = selectedPackageName; // 启动对应的分享Intent var targetIntent = new Intent(Intent.ActionSend); targetIntent.SetType("text/plain"); targetIntent.PutExtra(Intent.ExtraText, text); // 指定目标应用的组件 targetIntent.SetComponent(new ComponentName(selectedPackageName, selectedApp.ActivityInfo.Name)); StartActivityForResult(targetIntent, 555); }) .Show(); }
步骤3:按需使用包名
因为在用户选择应用时你已经拿到了selectedPackageName,所以如果只是需要记录选中的应用包名,不需要等到OnActivityResult——直接在选择回调里处理即可。如果需要在分享完成后做后续操作,OnActivityResult里的resultCode可以告诉你分享是否成功,但包名你已经提前获取到了。
补充说明
如果你坚持想用系统选择器,很遗憾没有直接获取包名的方法——系统选择器的设计就不提供这个返回值。所以自定义选择列表是最可靠的方案。
内容的提问来源于stack exchange,提问作者Amit
相关产品推荐
相关产品推荐

