2016-12-27 1 views
3

通常のアプリケーションフローではない特別なアクティビティによって処理される通知を表示しようとしていて、バックスタックの処理が「正しい」ことを意味します:通知でスタックを元に戻す方法

  1. 通知アクティビティがアプリケーションの実行中に処理される場合、通知アクティビティは現在のスタックに表示されるはずです。通知から戻って、アプリケーションのどこにいても残してください。これは、アプリケーションが開かれている可能性があることに注意してください。
  2. アプリケーションが実行されていない間に通知が処理される場合、通知アクティビティはアプリケーションのメイン(初期)アクティビティに表示されます。

はこれまでのところ、私は通知を提示するために使用しているコードは次のとおりです。明確にするため

/** 
* Show (or update) a notification for the current message set. 
* 
* @param showNotification true to use a high priority notification which will be immediately 
*       displayed (as opposed to just added to the status bar) 
*/ 
private void createOrUpdateNotification(boolean showNotification) { 
    Message oldest = messages.get(0); 
    Message newest = messages.get(messages.size() - 1); 

    // Create the notification 
    NotificationCompat.Builder builder = new NotificationCompat.Builder(context) 
      // Set notification data and appearance 
      .setContentTitle(title) 
      .setContentText(newest.message) 
      .setSmallIcon(smallIcon) 
      .setWhen(newest.when) 
      .setColor(ContextCompat.getColor(context, R.color.primary_color)) 

      // Set notification options 
      .setAutoCancel(true) 
      .setCategory(NotificationCompat.CATEGORY_MESSAGE) 
      .setPriority(showNotification ? NotificationCompat.PRIORITY_HIGH : NotificationCompat.PRIORITY_LOW) 
      .setDefaults(NotificationCompat.DEFAULT_VIBRATE) 
      .setOnlyAlertOnce(!showNotification); 

    // Set up the action if the first (oldest) message has an intent builder 
    if(oldest.intent != null) { 
     TaskStackBuilder stackBuilder = TaskStackBuilder.create(context.getApplicationContext()); 
     stackBuilder.addNextIntent(oldest.intent); 
     builder.setContentIntent(stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)); 
    } 

    NotificationManagerCompat.from(context).notify(notificationId, builder.build()); 

    Log.i("notification created"); 
} 

Message.intentは、通知処理アクティビティを開くように構成された単一の意図、です。

私の問題は、通知が開かれたときにアプリケーションが現在実行中で開いている場合、アプリケーションが閉じられ、空のスタックとアプリケーションのバックスタックに通知が表示されることです。

コンテンツのインテントが単一のインテントを含む保留中のインテントである場合は、ここでのケースであることが望ましいです。

私には何が欠けていますか?

+0

私はあなたの質問を正しく理解しましたか?あなたは、通知を表示し、通知されている間に通知を出したスレッドを停止したいでしょうか?それはあなたが欲しいものですか? – Distjubo

+0

いいえ通知はサービスによって生成されます。コンテンツアクションは、通常のアプリケーションフローから外れたアクティビティを開きます。そのアクティビティが終了すると、中断された所有アプリケーションアクティビティに戻りたいと思います。 –

答えて

1

TaskStackBuilder.createは、新しいタスクスタックを起動します。

builder.setContentIntent(
    PendingIntent.getActivity(
    context, 
    0, 
    oldest.intent, 
    PendingIntent.FLAG_UPDATE_CURRENT 
)); 
+0

ありがとう、これは非常に近いです!この時点で欠落している唯一の事は、通知が生成される前に(アプリケーションの外にある)起動画面まで戻って、アプリケーションがまったく開始されず、通知だけであるということです。 –

+0

通知アクティビティに対してonBackPressed()をオーバーライドし、isTaskRoot()を呼び出すことができます。通知アクティビティがタスクルートである場合、メインアクティビティを起動できます。 – Luis

+0

これは難しい部分ですが、これはすべてSDKのものです(私はホストアプリケーションを所有していません)アプリケーションのデフォルトのアクティビティを起動する便利な方法はありますか? –

0

がバンドルのキューを作成し、あなたの要件ごとにキューからバンドルオブジェクトを追加したり削除保つ:

ではなく、このようなコンテンツの意図を設定します。

/** 
    * Queue that holds notifications messages 
    */ 
    private Queue<Bundle> mNotificationQueue = new LinkedList<Bundle>(); 

/** 
* Method returning the singleton queue maintained in a static class 
*/ 
public Queue<Bundle> getNotificationQueue() { 
     return mNotificationQueue; 
    } 

今通知を受信したときにキューに通知メッセージを追加

// Fetching the message from intent and adding in bundle to add in the queue 

Bundle notificationMsgBundle = intent.getExtras(); 

notificationMsgBundle.getString(MyConstants.KEY_CHANNEL) + " :: " + notificationMsgBundle.getString(MyConstants.KEY_DATA)); 

DataManager.getInstance()。getmNotificationQueue()。(notificationMsgBundle)を追加

今、この静的キューでありますアプリケーション全体でメンテナンスされ、キューからメッセージを削除または追加できます。

// removing the node message in the queue as per requirement 
DataManager.getInstance().getmNotificationQueue().remove(); 
0

@ lecoの答えをちょっと拡張するために、私の最終的な解決策には2つの部分がありました。彼は推奨されているようPendingIntentを使用して、Notificationを構築する代わりに、直接のTaskStackBuilder使用しようとしている

最初:

builder.setContentIntent(
    PendingIntent.getActivity(
    context, 
    0, 
    oldest.intent, 
    PendingIntent.FLAG_UPDATE_CURRENT 
)); 

をこれは、(アプリケーションが実行された場合、私に正しい動作を得たが、現在開いていませんすなわち、

public void finish() { 
    if(isTaskRoot()) { 
     // If we're the task root, probably because we were launched from a notification with the 
     // application closed, we should just open the default activity 
     try { 
      String homeClassName = getPackageManager().queryIntentActivities(
        new Intent(Intent.ACTION_MAIN).setPackage(getApplicationContext().getPackageName()), 
        0 
      ).get(0).activityInfo.name; 

      Class homeClass = Class.forName(homeClassName); 

      getApplicationContext().startActivity(new Intent(getApplicationContext(), homeClass).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 
     } 
     catch(Exception exception) { 
      Log.w(String.format("Can't find the MAIN activity for package %s", getApplicationContext().getPackageName())); 
     } 
    } 
    super.finish(); 
} 

乱高下と:、アップユーザーまで、私はfinish()をオーバーライドして、私のNotification取り扱い活動を変更し、その時点で「正しい」動作を取得するには

)アプリケーションのうち、すべての道を戻って打ちますqueryIntentActivitiesなどは、実際にアプリケーション用のドロップインコンポーネントを開発しているため、実際にルート/ホーム/起動アクティビティが実際に何であるかはわかりません。私はちょうどHOME意図を構築する簡単な方法を試してみました:

startActivity(new Intent(Intent.ACTION_MAIN).setPackage(getApplicationContext().getPackageName()) 

が、何らかの理由でstartActivityは例外を投げていた。

android.content.ActivityNotFoundException: No Activity found to handle Intent 

queryIntentActivitiesアプローチはのための適切なActivityがあることを示しているにもかかわらず、 Intent

関連する問題