点击通知去当前活动

我正在使用这个解决scheme: 如何使通知意图恢复,而不是作出新的意图?

我工作正常,当我通常运行我的应用程序..但是我的应用程序有一个共享function。

当我从图库应用程序中select要分享的图像并在我的活动中打开它时,我在活动中创build一个通知。 我希望当用户点击通知时,它会打开现有的活动(由图库应用程序打开)

问题是,当我点击通知它不恢复该活动,而是打开一个新的活动实例或另一个已经打开的实例

编辑:更多的解释

我的应用程序被称为ShareApp和活动被称为ShareActivity的问题是,当我通过画廊的应用程序打开ShareActivity,ShareActivity的一个实例创build在画廊应用程序任务的堆栈的顶部。 现在,当我创build一个指向我的ShareActivity的通知时,我使用了这个意图:

Intent intent = new Intent(this, ShareActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

问题是,当我点击通知时,它指向ShareApp任务堆栈中的ShareActivity实例,而不是图库应用任务的堆栈。

任何想法如何指向正确的任务的堆栈?

编辑2:我的代码

  int defaults = Notification.FLAG_NO_CLEAR; NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle(getString(R.string.app_name)) .setContentText(text) .setDefaults(defaults); Intent intent = new Intent(this, this.getClass()); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); mBuilder.setContentIntent(pendingIntent); NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(_ID, mBuilder.build()); 

编辑3:adb shell dumpsys活动(由David https://stackoverflow.com/a/16901603/1334268应用代码之后)

我的应用程序被称为shareApp,我的活动是ShareActivity

在点击通知之前:

 Main stack: TaskRecord{41965708 #6 A com.android.gallery3d} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.gallery3d/.app.Gallery bnds=[364,50][108,108]} Hist #2: ActivityRecord{417ccc28 com.yeahman.shareapp/.ShareActivity} Intent { act=android.intent.action.SEND_MULTIPLE typ=image/* cmp=com.yeahman.shareapp/.ShareActivity (has extras) } ProcessRecord{41c868d0 6088:com.yeahman.shareapp/10116} Hist #1: ActivityRecord{4135e540 com.android.gallery3d/.app.Gallery} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.gallery3d/.app.Gallery bnds=[364,50][108,108] } 

点击通知后:

  Main stack: TaskRecord{41965708 #6 A com.android.gallery3d} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.gallery3d/.app.Gallery bnds=[364,50][108,108]} Hist #3: ActivityRecord{4169f358 com.android.gallery3d/.app.Gallery} Intent { flg=0x20000000 cmp=com.android.gallery3d/.app.Gallery bnds=[0,205][480,301] } ProcessRecord{4175dd28 5808:com.android.gallery3d/10036} Hist #2: ActivityRecord{417ccc28 com.yeahman.shareapp/.ShareActivity} Intent { act=android.intent.action.SEND_MULTIPLE typ=image/* cmp=com.yeahman.shareapp/.ShareActivity (has extras) } ProcessRecord{41c868d0 6088:com.yeahman.shareapp/10116} Hist #1: ActivityRecord{4135e540 com.android.gallery3d/.app.Gallery} Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.gallery3d/.app.Gallery bnds=[364,50][108,108] } 

Solutions Collecting From Web of "点击通知去当前活动"

如果您有多个ShareActivity实例在不同的任务中处于活动状态,那么您无法通过启动活动来告知Android要重新激活哪个任务。 这听起来像你想要做的,在这种情况下,是发起不是你的活动,但画廊应用程序。 如果图库应用程序已经在运行,并且您的活动位于任务堆栈的顶部,那么您只需将图库应用程序置于前台即可。 为此,请为Gallery应用创build一个“启动意图”,并确保在Intent上设置Intent.FLAG_ACTIVITY_NEW_TASK 。 你应该能够通过使用getLaunchIntentForPackage()PackageManager获得“启动意图”

编辑:使用ActivityManager的示例代码

你可以试试这个:

 // Get the root activity of the task that your activity is running in ActivityManager am = (ActivityManager)getSystemService(ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1); ActivityManager.RunningTaskInfo task = tasks.get(0); // Should be my task ComponentName rootActivity = task.baseActivity; // Now build an Intent that will bring this task to the front Intent intent = new Intent(); intent.setComponent(rootActivity); // Set the action and category so it appears that the app is being launched intent.setAction(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); 

注意:您将需要GET_TASKS权限。 我没有尝试过这一点,不能保证它会工作。 文档不鼓励使用getRunningTasks() ,但这并不意味着它不适合你的目的。

编辑添加行动/类别的意图

注意:我实际上构build了一个小应用程序来testing这个。 我需要将ACTION = MAIN和CATEGORY = LAUNCHER添加到意图(如果您使用PackageManager.getLaunchIntentForPackage() ,那么将会有一个HTC One S,所以在我的设备上,“Gallery”应用程序实际上被称为com.htc.album/.AlbumMain.ActivityMainDropList ,但这应该仍然适合你。

  Notification.Builder mBuilder = new Notification.Builder(this) .setSmallIcon(R.drawable.cmplayer) .setContentTitle("CoderoMusicPlayer") .setContentText("PLayer0!"); Intent resultIntent = new Intent(this, AndroidBuildingMusicPlayerActivity.class); resultIntent.setAction(Intent.ACTION_MAIN); resultIntent.addCategory(Intent.CATEGORY_LAUNCHER); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, resultIntent, 0); mBuilder.setContentIntent(pendingIntent); NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); mNotificationManager.notify(1, mBuilder.build()); 

只需复制代码并将其粘贴到主启动器活动中。

 android:launchMode="singleTop" 

在您的主要活动的manifest.xml中,看看是否有帮助。

这是我多年来一直使用的解决scheme。

你的问题是你的PendingIntent从无用的内容开始它的目标。

您的第一步是将您的Intent的结果放入您的应用程序环境中。 要做到这一点你的通知调用广播“ForwardingReceiver”

 Intent newIntent = new Intent(context, ForwardingReceiver.class); ... mBuilder.setContentIntent(PendingIntent.getBroadcast(context, category, newIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 

ForwardingReceiver扩展了BroadcastReceiver ,在它的onReceive()方法中,你现在已经是应用程序的当前上下文了,可以像这样使用sendOrderedBroadcast()

 Intent forwardIntent = new Intent(); forwardIntent.putExtras(intent.getExtras()); forwardIntent.setAction(GenericReceiver.class.getCanonicalName()); context.sendOrderedBroadcast(forwardIntent, null); 

现在,有趣的部分。 您需要从一个普通的Activity父级扩展所有的应用程序活动。 您可能已经这样做了日志logging或分析。 在这个CommonActivityParent onResume()你需要注册接收广播优先级大于0(如10)

 mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { performActionUsingIntent(intent); } }; IntentFilter filter = new IntentFilter(); filter.addAction(GenericReceiver.class.getCanonicalName()); filter.setPriority(10); registerReceiver(mReceiver, filter); 

(记得在onPause()中取消注册)

这意味着如果您的应用程序处于前台,它将会收到通知单击(间接)并允许您执行操作。

但是,如果您的活动在后台,则不会注册该接收方。 没问题,你的“GenericReceiver”应该是这样的

 @Override public void onReceive(Context context, Intent intent) { PackageManager pm = context.getPackageManager(); Intent newIntent = pm.getLaunchIntentForPackage(context.getPackageName()); newIntent.putExtras(intent.getExtras()); context.startActivity(newIntent); } 

这将开始你的发射活动。 这个启动活动应该有onCreate()中的代码来检测它是否是任务的根。 如果不是,应该立即closures(因此用户永远不会看到)。 这有效地迫使上一个开放的任务进入前台:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!isTaskRoot() && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER) && getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_MAIN)) { // Use this space to add the intent to a static singleton. This will be used in CommonActivityParent to perform an action. CommonActivityParent.sIntent = getIntent(); finish(); return; } } 

要完成,请确保在CommonActivityParent的上述registerReceiver()调用之后,执行以下检查:

 if(sIntent != null) { Intent tempIntent = sIntent; sIntent = null; performActionUsingIntent(tempIntent); } 

嘿presto – 你的应用程序现在就像通知点击实际上是一个点击从你的应用程序内。 而这一切只是一个很多工作的地狱!

希望有人有这样做的一个不太复杂的方式。