Android: Sending a Mail/SMS/Tweet with Intent.ACTION_SEND / requestCode / resultCode

androidsendmailsendmessage

I'm using the following code :

Intent sendMailIntent = new Intent(Intent.ACTION_SEND); 
        sendMailIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.Share_Mail_Subject));
        sendMailIntent.putExtra(Intent.EXTRA_TEXT, getString(R.string.Share_Mail_Text)); 
        sendMailIntent.setType("text/plain");

startActivity(Intent.createChooser(sendMailIntent, "Email / SMS / Tweet ?"));

Then I would like to be able to make the difference between:
1. my user has indeed sent en email/SMS … OR
2. my user has in fact pushed the BACK BUTTON … and didn't send anything.

Is there a way to make this difference ?

=> Should I launch the activity with startActivityForResult ? and catch the requestCode/resultCode with onActivityResult …

=> What king of resultCode should I expect ? how to grab it correctly ? Where should I put these lines of code ? Any snippet of code would be very helpful here.

thanks in advance.

Hub

Best Answer

I realize it has been quite a while since you asked this question and Android has changed quite a bit during this time. I'm not sure if you are still looking for an answer, but if you are, you can do this with the new Intent.createChooser() method, which takes a third PendingIntent.getIntentSender() argument, and a BroadcastReceiver. Here's how you do it:

Intent sendMailIntent = new Intent(Intent.ACTION_SEND); 
sendMailIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.Share_Mail_Subject));
sendMailIntent.putExtra(Intent.EXTRA_TEXT, getString(R.string.Share_Mail_Text)); 
sendMailIntent.setType("text/plain");

Intent receiver = new Intent(this, BroadcastTest.class);
receiver.putExtra("test", "test");

PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, receiver, PendingIntent.FLAG_UPDATE_CURRENT);
Intent chooser = Intent.createChooser(intent, "test", pendingIntent.getIntentSender());
startActivity(chooser);

Note that the target for my receiver intent was the BroadcastTest class which extends BroadcastReceiver. When the user chooses an application from the chooser, the onReceive method in BroadcastTest will be called and if the user presses back, onReceive will not be called. This way, you can check whether the user indeed sent an email/sms/tweet or if they pressed back. For example, if this is my BroadcastTest class:

public class BroadcastTest extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        for (String key : intent.getExtras().keySet()) {
            Log.d(getClass().getSimpleName(), " " + intent.getExtras().get(key));
        }
    }
}

you would get something like ComponentInfo{org.telegram.messenger/org.telegram.ui.LaunchActivity} in your log if the user selected the application Telegram. Using the key android.intent.extra.CHOSEN_COMPONENT, you should be able to find what the user picked. Also, don't forget to declare the BroadcastReceiver in your manifest.

Another way is to use PackageManager and queryIntentActivities() to make your own chooser. This would allow you to programmatically get the user selection. The method is described in this StackOverflow post.

To address your question about startActivityForResult, from Android's source, you can see that the Activity that chooses among Intents doesn't setResult() at all. Thus, if you try to catch a result code in onActivityResult, it will always be 0 (RESULT_CANCELED). Thus, using startActivityForResult, you cannot determine whether the user selected an option or pressed back.