Whatsapp 喜欢通过短信实施邀请,只是短信,而不是通过意图选择器

Whatsapp like invite via sms implementation, just sms, not via intent chooser

无法在我的应用程序堆栈中启动默认短信 activity。在 nexus 6 lollipop 和 android one marshmallow 中发现问题。

我已经尝试发送 ACTION_VIEW 的意图,并设置了 smsto: 和 sms body。

我可以启动短信应用程序。

我的应用程序有以下行为。

  1. 我的应用程序中有联系电话列表

  2. 当用户说邀请时,我想启动默认短信应用程序,填写短信正文和默认短信应用程序应该在我的 activity 任务中。

  3. 按返回键,我想关闭消息应用程序。

请看下面的参考图片 1.我的应用邀请 2. 收到邀请后,发送短信

send sms, press back, check recent app list

我能达到什么。 我能够在 kitkat 中实现上述目标。 (默认短信应用程序完成) 但是,不是棒棒糖和棉花糖。默认短信应用进入后台。

  1. 启动默认短信应用程序并填写数据。
  2. 按返回键后,消息应用程序进入后台。
  3. 现在我将能够从最近的应用程序列表中启动短信应用程序,这再次为收件人填充了相同的号码和正文,这不是预期的。

问题是,应用程序是在新的 activity 任务中启动的。我无法在我的 activity 任务中获取该消息传递应用程序。如果我在该消息传递应用程序上按回键,我就可以返回到我的应用程序。但是,如果我从最近的列表中选择消息应用程序,它每次都会显示短信收件人和正文填充 activity。

请在下面找到代码片段

private void sendTextMessage(String to)
{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) // At least KitKat
    { 
        String defaultSmsPackageName = Telephony.Sms.getDefaultSmsPackage(mActivity); // Need to change the build to API 19
        Logger.log_error(TAG + "sendTextMessage() above KITKAT");
        Intent sendIntent = new Intent(Intent.ACTION_SEND);
        sendIntent.setType("text/plain");
        sendIntent.putExtra("address", to); 
        sendIntent.putExtra("sms_body", "sms body");
        sendIntent.putExtra(Intent.EXTRA_TEXT, "sms body");

        if (defaultSmsPackageName != null)// Can be null in case that there is no default, then the user would be able to choose
        // any app that support this intent. 
        { 
            sendIntent.setPackage(defaultSmsPackageName);
            Logger.log_error(TAG + "sendTextMessage() defaultSmsPackageName = " + defaultSmsPackageName);
        }
        getContext().startActivity(sendIntent);
        } 
        else // For early versions, do what worked for you before. 
        { 
            Intent smsIntent = new Intent(android.content.Intent.ACTION_VIEW);
            Logger.log_error(TAG + "sendTextMessage() below KITKAT");
            smsIntent.setType("vnd.android-dir/mms-sms");
            smsIntent.putExtra("address", to);         
            smsIntent.putExtra("sms_body", getString(R.string.str_share_app_short_text));
            startActivity(smsIntent);
    }
}

这种启动方式会扰乱消息传递应用程序。

我试过启动没有历史记录的意图,单个实例,从最近的排除。

作为参考,我附上了 whatsapp 截图,我想把它放在我的 activity 中。 我无法在堆栈溢出中 post 超过 2 个链接,因此只保留最近的应用程序列表。

  1. 启动 whatsapp,转到联系人,向下滚动,寻找绿色邀请 并邀请。
  2. 它将启动短信应用程序。
  3. 检查最近。

check in recent list

我想,我找到了答案。可能不理想但有效。

private void shareEx() {
    List<Intent> targetShareIntents=new ArrayList<Intent>();
    PackageManager packageManager = getContext().getPackageManager();
    Intent shareIntent=new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.setType("text/plain");
    List<ResolveInfo> resInfos= getContext().getPackageManager().queryIntentActivities(shareIntent, 0);
    if(!resInfos.isEmpty()){
        Logger.log_error( TAG + "sharenew Have package");
        for(ResolveInfo resInfo : resInfos){
            String packageName = resInfo.activityInfo.packageName;

            Intent intent = new Intent();
            intent.setComponent(new ComponentName(packageName, resInfo.activityInfo.name));
            intent.setAction(Intent.ACTION_SEND);
            intent.setType("text/plain");

            intent.setPackage(resInfo.activityInfo.parentActivityName);

            //ignore list
            if(packageName.contains("wifi") || packageName.contains("bluetooth") || packageName.contains("nfc") || packageName.contains("connect") || packageName.contains("memo") || packageName.contains("translate") || packageName.contains("gps") 
                    || packageName.contains("file") || packageName.contains("File") || packageName.contains("drive") || packageName.contains("office") || packageName.contains("docs") || packageName.contains("dropbox") || packageName.contains("beam")
                    || packageName.contains("keep")) {
                Logger.log_error( TAG + "sharenew IGNORE Package packageName = " + packageName);
                continue;
            }

            Logger.log_error( TAG + "sharenew Package packageName = " + packageName);
            if (packageName.contains("sms") || packageName.contains("mms") || packageName.contains("talk") || packageName.contains("messaging") || packageName.contains("twitter") || packageName.contains("com.facebook.orca")) {                  
                intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.str_share_app_short_text));
                intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.str_share_app_subject));
            } else if(packageName.contains("whatsapp")) {
                // dont add subject for whatsapp
                intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.str_share_app_long_text));
            } else {
                intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.str_share_app_long_text));
                intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.str_share_app_subject));                   
            }
            targetShareIntents.add(new LabeledIntent(intent, packageName, resInfo.loadLabel(packageManager), resInfo.icon));
        } 
        if(!targetShareIntents.isEmpty()){
            Logger.log_error( TAG +"sharenew Have Intent");
            Intent chooserIntent=Intent.createChooser(targetShareIntents.remove(0), "Choose app to share");
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetShareIntents.toArray(new Parcelable[]{}));
            startActivity(chooserIntent);
        }else{ 
            Logger.log_error( TAG +"sharenew nothing");
        } 
    } 
}

参考: How to filter specific apps for ACTION_SEND intent (and set a different text for each app)

我请求人们改进答案。谢谢