Android Studio分享至WhatsApp时如何弹出应用选择弹窗
需求场景
当用户设备安装了两个WhatsApp客户端(普通版、商业版/双开版)时,需要在应用内分享内容到WhatsApp前弹出应用选择弹窗,效果如下:
原有代码可正常触发WhatsApp分享,但会直接打开指定客户端,不弹出选择框。
问题根因
原有代码通过setPackage()方法给分享Intent硬编码绑定了唯一包名:优先绑定普通版WhatsApp(com.whatsapp),仅当普通版不存在触发异常时,才在catch逻辑中绑定商业版WhatsApp(com.whatsapp.w4b)。
当Intent已经绑定固定包名时,Intent.createChooser()会直接匹配唯一对应应用启动,不会弹出多应用选择列表。
实现方案
步骤1:适配Android 11+包可见性
在AndroidManifest.xml中添加以下配置,否则Android 11及以上系统无法查询到设备上已安装的WhatsApp应用:
<queries> <package android:name="com.whatsapp" /> <package android:name="com.whatsapp.w4b" /> <intent> <action android:name="android.intent.action.SEND" /> <data android:mimeType="image/*" /> </intent> </queries>
步骤2:替换分享逻辑代码
不再硬编码绑定单个包名,先查询设备上所有安装的、支持图片分享的WhatsApp客户端,将所有匹配的应用传入选择器,即可弹出选择弹窗:
private void shareToWhatsApp(Bitmap bitmap, File file, NewsModel newsModel) { try { // 统一处理图片文件写入,移除重复代码 FileOutputStream outputStream = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); outputStream.flush(); outputStream.close(); // 构建基础分享参数 Intent baseIntent = new Intent(Intent.ACTION_SEND); baseIntent.setType("image/*"); Uri imageUri = Uri.fromFile(file); baseIntent.putExtra(Intent.EXTRA_STREAM, imageUri); String shareText = newsModel.getTitle() + "\n\n" + "That's Awesome...👀 \n\n Install Now!☺☺ \n\n"; shareText += "https://play.google.com/store/apps/details?id=" + BuildConfig.APPLICATION_ID + "\n\n"; baseIntent.putExtra(Intent.EXTRA_TEXT, shareText); PackageManager pm = getPackageManager(); List<ResolveInfo> appList = pm.queryIntentActivities(baseIntent, 0); ArrayList<Intent> whatsAppIntents = new ArrayList<>(); // 过滤所有WhatsApp系客户端 for (ResolveInfo appInfo : appList) { String pkgName = appInfo.activityInfo.packageName; if (pkgName.equals("com.whatsapp") || pkgName.equals("com.whatsapp.w4b")) { Intent targetIntent = new Intent(baseIntent); targetIntent.setComponent(new ComponentName(pkgName, appInfo.activityInfo.name)); targetIntent.setPackage(pkgName); whatsAppIntents.add(targetIntent); } } if (whatsAppIntents.isEmpty()) { Toast.makeText(this, "请先安装WhatsApp客户端", Toast.LENGTH_SHORT).show(); return; } // 构建应用选择器 Intent chooser = Intent.createChooser(whatsAppIntents.remove(0), "Share News from " + getString(R.string.app_name)); chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, whatsAppIntents.toArray(new Intent[0])); chooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(chooser); } catch (Exception e) { e.printStackTrace(); } }
补充说明
- 如果需要兼容系统双开产生的WhatsApp分身,只需要在包名过滤逻辑中加入对应分身的包名即可
- 若应用
targetSdkVersion >= 24,直接使用Uri.fromFile()会触发FileUriExposedException,需要通过FileProvider生成content类型Uri,该适配属于分享功能通用配置,和选择弹窗逻辑无关。
内容的提问来源于stack exchange,提问作者ZIBRAN KHAN
相关产品推荐
相关产品推荐

