我正在使用此解决方案:How to make notification intent resume rather than making a new intent?
当我正常运行我的应用程序时,我工作正常..但是我的应用程序具有共享功能。
当我选择要从图库应用程序共享的图像并在我的活动中打开它时,我会在活动中创建通知。我希望当用户点击通知时,它会打开现有活动(由图库应用程序打开)
问题在于,当我点击通知时,它不会恢复该活动,而是打开活动的新实例或之前已打开的另一个实例
修改: 更多解释
我的应用程序名为ShareApp,活动名为ShareActivity 问题是,当我通过图库应用程序打开ShareActivity时,会在图库应用程序任务的堆栈顶部创建一个ShareActivity实例。现在,当我创建指向我的ShareActivity的通知时,我使用了intent:
Intent intent = new Intent(this, ShareActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
问题是,当我点击通知时,它指向ShareApp任务堆栈中的ShareActivity实例,而不是gallery app任务的堆栈..
任何想法如何指向正确的任务的堆栈??
编辑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] }
答案 0 :(得分:24)
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());
只需复制代码并将其粘贴到主启动器活动中即可。
答案 1 :(得分:7)
如果您有多个ShareActivity
个实例在不同的任务中处于活动状态,则无法通过启动您的活动告诉Android重新激活哪个任务。听起来像你想做的事情,在这种情况下,不是启动你的活动,而是启动Gallery应用程序。如果Gallery应用程序已在运行且您的活动位于任务堆栈的顶部,那么您需要做的就是将Gallery应用程序置于前台。为此,创建一个"启动Intent"对于Gallery应用程序,请确保在Intent上设置Intent.FLAG_ACTIVITY_NEW_TASK
。你应该能够得到一个"启动Intent"使用PackageManager
getLaunchIntentForPackage()
开始
编辑:使用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()
,但这并不意味着它不适合您的目的。
EDIT为意图添加了操作/类别
注意:我实际上构建了一个小应用程序来测试它。我需要将ACTION = MAIN和CATEGORY = LAUNCHER添加到Intent(如果你使用了PackageManager.getLaunchIntentForPackage()
,它会在那里。)我有一个HTC One S,所以在我的设备上&#34; Gallery& #34; app实际上被称为com.htc.album/.AlbumMain.ActivityMainDropList
,但这仍然适用于你。
答案 2 :(得分:4)
集
android:launchMode="singleTop"
在您的主要活动manifest.xml
中,看看是否有帮助。
答案 3 :(得分:1)
这是我多年来一直使用的解决方案。
您的问题是您的PendingIntent从无应用内容中启动了它的目标。
您的第一步是将Intent的结果带入您的应用上下文中。要执行此操作,请将通知呼叫广播到&#34; ForwardingReceiver&#34;
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);
现在,有趣的部分。您需要从公共活动父级扩展所有应用程序活动。您可能已经执行此操作以进行日志记录或分析。在此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()中取消注册)
这意味着,如果您的应用位于前台,它会收到通知点击(间接)并允许您执行操作。
但是,如果您的活动在后台,则不会注册此接收者。没问题,你的&#34; GenericReceiver&#34;应该看起来像这样
@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()代码,以检测它是否为root任务。如果它不是立即关闭(因此用户永远不可见)。这有效地迫使最后一个打开的任务进入前台:
@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 - 您的应用程序现在将表现为通知点击实际上是您应用内的点击。所需要的只是一大堆工作!
希望某人有一种不太复杂的方式来做这件事。
答案 4 :(得分:0)
有关其他信息,请不要忘记添加待处理的Intent标志以使onNewIntent起作用!
true:
PendingIntent.getActivity(context, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT)
false:
PendingIntent.getActivity(context, 0, resultIntent, 0)
如果对您有好处,请投票支持!