Tuesday, April 10, 2018

Understanding Android PendingIntent

To understand PendingIntent, first needs to see how activity is started by regular intent.

When using regular intent to start an activity, it requires two pieces of information, the first one is class name of activity to be started; the second one is context for calling the startActivity method.

In the below code Activity1 uses regular intent to starts Activity3
Intent in = new Intent(this, Main3Activity.class);
this.startActivity(in);

Now let think a case when Activity1 wants to let others to start Activity3, but still on Activity1's context (or permission scope). To do so, Activity needs to wrap the above two information in a PendingIntent object as below
Intent in = new Intent(this, Main3Activity.class);
PendingIntent pendingInt = PendingIntent.getActivity(this, 0, in, 0); 
Since PendingIntent has the full information (context and activity class name), so any caller (activity or a plain thread) can use it to start the target activity by calling the below code without even knowing who originally created the pending intent. 
pendingInt.send();
The way of passing the PendingIntent to other Activity or thread does not matters, it can be passed simply as a function parameter, or passed as Intent's Parcelable extra. Note the PendingIntent object can be used repeatedly by other activity and thread, for the purpose of passing the information to the target activity.

A typical use case of PendingIntent if notification. Assume there is an internal activity A in your app. which is not visible to external apps. Then in your app, creating a notification, when it is tapped by user, using PendingIntent to launch Activity A. Here the PendingIntent is used to tell Android OS, that when user taps the notification item, launching the activity A on your behalf, no matter your is running or not. Without using PendingIntent, this cannot be done, as the Activity is only visible to your app, Android OS and other apps does not even know its existence.  
public void onSetNotification(View v){
    Intent intent = new Intent(this, SecondActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, "My Notification CHANNEL_ID")
            .setSmallIcon(R.drawable.ic_stat_account_balance)
            .setContentTitle("My notificaiton Title")
            .setContentText("My notificaiton text Content")
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .setStyle(new NotificationCompat.BigTextStyle()
                    .bigText("Much longer text that cannot fit one line. long long long long long long long long long long long long "))
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);
    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);

    notificationManager.notify(notificationId, mBuilder.build());
}

No comments:

Post a Comment