androidandroid-intentandroid-5.0-lollipopgoogle-app-invites

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


Unable to launch default sms activity in my application stack. Issue seen in nexus 6 lollipop and android one marshmallow.

I have tried to send intent of ACTION_VIEW, and set the smsto: and sms body.

I am able to launch sms application.

I have the following behaviour of my app.

  1. I have list of contact numbers in my app

  2. When user says invite, i want to launch default sms app, fill in to and sms body and default sms app should be in my activity task.

  3. On pressing back, I want to close messaging app.

Please see the reference images below 1. My app invite 2. on invite, launch sms

send sms, press back, check recent app list

What I am able to achieve. I am able to achieve above mentioned in kitkat. (default sms app finishes) but, not in lollipop and marshmallow. Default sms app goes to background.

  1. Launch default sms app and fill in data.
  2. On pressing back, messaging app goes to background.
  3. Now I will be able to launch sms app from recent app list, which again fills recipient with same number and body, which is not intended.

The problem is, app is launched in new activity task. I am unable to get that messaging app in my activity task. If I press back on that messaging app, I am able to come back to my app. But if I choose the messaging app from recent list, it shows the sms recipient and body filled activity every time.

Please find the code snippet below

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);
    }
}

This way of launching is messing with messaging app.

I have tried launching intent with no history, single instance, exclude from recents.

For reference I am attaching the whatsapp screenshots, which I am trying to have in my activity. I am not able to post more than 2 links in stack overflow, so keeping recent app list only.

  1. Launch whatsapp, go to contacts, scroll down, look for invite in green and invite.
  2. It will launch sms app.
  3. Check recents.

check in recent list


Solution

  • I think, i found answer. May not be ideal but works.

    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");
            } 
        } 
    }
    

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

    I request people to improve answer. Thanks.