1. 程式人生 > >android-Notification點選跳轉指定的Activity

android-Notification點選跳轉指定的Activity

今天專案中有這樣的一個需求,當程式還沒被程序“殺死”的時候,後臺推送來了一則訊息,這時候不管是程式在前臺執行,還是後臺中,需要我們以通知欄的方式來通知使用者。
對於通知欄,使用者操作後有兩種情況。
1.當程式在前臺執行的時候,點選後,直接跳到目標Activity,此時,點選返回鍵是回到上個頁面
2.點選通知欄後,先啟動App,然後再跳到目標頁面,此時,按下返回鍵是回到App的首頁,而不至於退出App

第一種情況實現:
這種情況比較容易,只要直接在PendingIntent 中指定Activity中即可

Intent intent = new Intent(getApplicationContext(), SplashActivity.class
); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

因此第一種情況,結合建立一個通知欄的程式碼結合就是:

  NotificationManager barmanager=(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notice;
        Notification.Builder
builder = new Notification.Builder(contxt).setTicker(message) .setSmallIcon(R.drawable.ic_launcher).setWhen(System.currentTimeMillis()); Intent appIntent=null; appIntent = new Intent(context,ActivitySplash.class); appIntent.setAction
(Intent.ACTION_MAIN); appIntent.addCategory(Intent.CATEGORY_LAUNCHER); appIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);//關鍵的一步,設定啟動模式 PendingIntent contentIntent =PendingIntent.getActivity(context, 0,appIntent,PendingIntent.FLAG_UPDATE_CURRENT); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { notice = builder.setContentIntent(contentIntent).setContentTitle(title).setContentText(content).build(); notice.flags=Notification.FLAG_AUTO_CANCEL; barmanager.notify(10,notice); }

我們在建立PendingIntent的時候需要注意引數PendingIntent.FLAG_CANCEL_CURRENT
這個標誌位用來指示:如果當前的Activity和PendingIntent中設定的intent一樣,那麼就要先取消當前的Activity,用PendingIntent中指定的Activity取代之。
另外,需要在Manifest中對指定的Activity設定屬性

<activity android:name=".SplashActivity.class"  
        android:launchMode="singleTask"  
        android:taskAffinity=""  
        android:excludeFromRecents="true">  
</activity>  

相對於第一種情況,第二種情況稍微複雜點,因為如果只打開目標頁面,DetaitActivity,程式並沒辦法知道他的上一級Activity是誰,所以需要在點選Notification時開啟一組Activity,但是我們並不需要一個個去呼叫startActivity方法,PendingIntent提供了個靜態方法getActivities,裡面可以設定一個Intent陣列,用來指定一系列的Activity。
所以我們首先寫一個函式建立一個Activity陣列

 //任務棧
    Intent[] makeIntentStack(Context context) {
        Intent[] intents = new Intent[2];
        intents[0] = Intent.makeRestartActivityTask(new ComponentName(context, com.example.root.activity.MainActivity.class));
        intents[1] = new Intent(context,  com.example.activity.ActiveDetailActivity.class);
        return intents;
    }

其中需要注意的是Intent.makeRestartActivityTask方法,這個方法用來建立activity棧的根activity
接下來,我們需要建立並顯示通知欄:

 NotificationManager barmanager=(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notice;
        Notification.Builder builder = new Notification.Builder(contxt).setTicker(message)
                .setSmallIcon(R.drawable.ic_launcher).setWhen(System.currentTimeMillis());
  Intent[] appIntent=null;
                    appIntent=makeIntentStack(context);//上面有改方法
                    appIntent[1].setAction(Intent.ACTION_MAIN);
                    appIntent[1].addCategory(Intent.CATEGORY_LAUNCHER);
                    appIntent[1].setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);//關鍵的一步,設定啟動模式
                    PendingIntent contentIntent =PendingIntent.getActivities(context, 0,appIntent,PendingIntent.FLAG_UPDATE_CURRENT);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                        notice = builder.setContentIntent(contentIntent).setContentTitle(title).setContentText(content).build();
                        notice.flags=Notification.FLAG_AUTO_CANCEL;
                        barmanager.notify(10,notice);
                    }

然後功能基本是這樣實現了,很感謝這篇部落格的啟發: