如何使通知意图恢复,而不是作出新的意图?

我在这里是一个简单的webview活动,加载时它会自动显示正在进行的通知。 这个想法是,人们可以离开这个活动,并通过拉下下拉菜单并select它,从任何他们想要的屏幕快速访问它。 然后,当他们想要的时候,他们可以通过点击菜单buttonclosures通知并点击退出,然后清除通知。 这一切工作正常。 但是,当通知被按下时,它启动一个新的活动实例。 我需要改变什么才能看到活动是否已经被销毁,我可以调用这个实例(恢复它),因此不需要再次加载它,也不需要添加另一个活动到我的堆栈。 有任何想法吗? 任何帮助将不胜感激。

package com.my.app; import com.flurry.android.FlurryAgent; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.webkit.CookieSyncManager; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; public class Chat extends Activity { private ProgressDialog progressBar; public WebView webview; private static final String TAG = "Main"; private NotificationManager mNotificationManager; private int SIMPLE_NOTFICATION_ID; @Override public void onStart() { super.onStart(); CookieSyncManager.getInstance().sync(); FlurryAgent.onStartSession(this, "H9QGMRC46IPXB43GYWU1"); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.chat); mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); final Notification notifyDetails = new Notification(R.drawable.chat_notification,"Chat Started",System.currentTimeMillis()); notifyDetails.flags |= Notification.FLAG_ONGOING_EVENT; Context context = getApplicationContext(); CharSequence contentTitle = "Chat"; CharSequence contentText = "Press to return to chat"; Intent notifyIntent = new Intent(context, Chat.class); PendingIntent intent = PendingIntent.getActivity(Chat.this, 0, notifyIntent, android.content.Intent.FLAG_ACTIVITY_NEW_TASK); notifyDetails.setLatestEventInfo(context, contentTitle, contentText, intent); mNotificationManager.notify(SIMPLE_NOTFICATION_ID, notifyDetails); CookieSyncManager.createInstance(this); CookieSyncManager.getInstance().startSync(); webview = (WebView) findViewById(R.id.webviewchat); webview.setWebViewClient(new chatClient()); webview.getSettings().setJavaScriptEnabled(true); webview.getSettings().setPluginsEnabled(true); webview.loadUrl("http://google.com"); progressBar = ProgressDialog.show(Chat.this, "", "Loading Chat..."); } private class chatClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { Log.i(TAG, "Processing webview url click..."); view.loadUrl(url); return true; } public void onPageFinished(WebView view, String url) { Log.i(TAG, "Finished loading URL: " +url); if (progressBar.isShowing()) { progressBar.dismiss(); } } } public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) { webview.goBack(); return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onCreateOptionsMenu (Menu menu) { super.onCreateOptionsMenu(menu); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.chatmenu, menu); return true; } @Override public boolean onOptionsItemSelected (MenuItem item) { switch (item.getItemId()) { case R.id.home: Intent a = new Intent(this, Home.class); startActivity(a); return true; case R.id.closechat: mNotificationManager.cancel(SIMPLE_NOTFICATION_ID); Intent v = new Intent(this, Home.class); startActivity(v); return true; } return false; } public void onStop() { super.onStop(); CookieSyncManager.getInstance().sync(); FlurryAgent.onEndSession(this); } } 

@Commonsware

只是为了确定我是否正确,这是你build议的吗?

我有点担心这一行,

 PendingIntent.getActivity(Chat.this, 0, notifyIntent, SIMPLE_NOTFICATION_ID); public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.chat); mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); final Notification notifyDetails = new Notification(R.drawable.chat_notification,"Chat Started",System.currentTimeMillis()); notifyDetails.flags |= Notification.FLAG_ONGOING_EVENT; Context context = getApplicationContext(); CharSequence contentTitle = "Chat"; CharSequence contentText = "Press to return to chat"; Intent notifyIntent = new Intent(context, Chat.class); PendingIntent intent = PendingIntent.getActivity(Chat.this, 0, notifyIntent, SIMPLE_NOTFICATION_ID); notifyDetails.setLatestEventInfo(context, contentTitle, contentText, intent); notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); mNotificationManager.notify(SIMPLE_NOTFICATION_ID, notifyDetails); CookieSyncManager.createInstance(this); CookieSyncManager.getInstance().startSync(); webview = (WebView) findViewById(R.id.webviewchat); webview.setWebViewClient(new chatClient()); webview.getSettings().setJavaScriptEnabled(true); webview.getSettings().setPluginsEnabled(true); webview.loadUrl("http://google.com"); progressBar = ProgressDialog.show(Chat.this, "", "Loading Chat..."); } 

这个想法是,人们可以离开这个活动,并通过拉下下拉菜单并select它,从任何他们想要的屏幕快速访问它。

请使此选项。

但是,当通知被按下时,它启动一个新的活动实例。

这将在默认情况下发生。

我需要改变什么才能看到活动是否已经被销毁,而且我可以调用这个实例(继续),因此不需要再次加载它,也不需要添加另一个活动到我的堆栈。

摆脱FLAG_ACTIVITY_NEW_TASK 。 添加notifyIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); – 看到这个示例项目 。

 Context context = getApplicationContext(); 

请不要这样做。 只要使用您的Activity作为Context

这是我的方法来显示通知。 我希望它可以帮助你。

 private static void generateNotification(Context context, String message){ Intent notificationIntent = new Intent(context, YOUR_ACTIVITY.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle(context.getString(R.string.app_name)) .setContentIntent(intent) .setPriority(PRIORITY_HIGH) //private static final PRIORITY_HIGH = 5; .setContentText(message) .setAutoCancel(true) .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS); NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(0, mBuilder.build()); } 

以防万一别人有同样的困难,我有….

我尝试了上面的所有代码,但都没有成功 – 即使已经运行了一个通知项目,我仍然会启动一个全新的应用程序实例。 (我只想在任何时候都有一个实例可用)。最后注意到这个其他线程( https://stackoverflow.com/a/20724199/4307281 ),在清单中有一个简单的附加条目:

android:launchMode="singleInstance"

我把它放在我的应用程序的主要活动部分的清单中,然后通知项目重用已经在进行的实例。

没有解决scheme为我工作,所以我find了自己的方式。 我的所有活动都是从BaseActivity扩展而来的。 我遵循一系列简单的步骤来使我的推送通知单击恢复应用程序:

第1步:常量logging当前活动:

 public static Context currentContext; 

第2步:在由BaseActivity扩展的活动的onCreate()onResume()

 currentContext = this; 

第3步:创build通知时的Intent

 Class activity = BaseActivity.commonContext.getClass(); Intent intent = new Intent(this, activity); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); //FLAG_UPDATE_CURRENT is important PendingIntent pendingIntent = PendingIntent.getActivity(this, (int)System.currentTimeMillis(), intent, PendingIntent.FLAG_UPDATE_CURRENT); 

我发现没有任何答案适用于多任务应用程序。 看起来可以理解的是,Intent.FLAG_ACTIVITY_CLEAR_TOP和Intent.FLAG_ACTIVITY_SINGLE_TOP在多任务的情况下并不完全相同。 在我的应用程序中,有多个任务根活动。 在某个时刻,用户将会看到一个通知,说明在这些任务中有一项工作要做。 与OP不同的是,我只需要回到这些任务之一的顶部,而不是一个特定的活动,这些活动可能被埋在这些任务之一中。 我认为这与被问到的问题类似,可能对其他人有用。

我的解决scheme由一个静态任务ID组成,以跟踪当前的任务,一个处理未决意图的广播接收器,一个新的使用权限标签,以及一些ActivityManager的简单使用。

 private static int taskID; public static void setResumeTask(int tID) { Log.e("TaskReturn", "Setting Task ID: " + tID); taskID = tID; } public static PendingIntent getResumeTask(Context appContext) { return PendingIntent.getBroadcast(appContext, 0, new Intent(appContext, TaskReturn.class).putExtra(TaskReturn.EXTRA_TASK_ID, taskID), PendingIntent.FLAG_UPDATE_CURRENT); } 

 public void onReceive(Context context, Intent intent) { Log.e("TaskReturn", "Task Return!"); if (intent.hasExtra(EXTRA_TASK_ID)) { int taskToStart = intent.getIntExtra(EXTRA_TASK_ID, -1); Log.e("TaskReturn", "Returning To Task: " + taskToStart); ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.AppTask> allAppTasks = activityManager.getAppTasks(); for (ActivityManager.AppTask task : allAppTasks) { Log.e("TaskReturn", "AllTasks: " + task.getTaskInfo().id + " " + task.getTaskInfo().affiliatedTaskId + " " + task.getTaskInfo().persistentId); } activityManager.moveTaskToFront(taskToStart, ActivityManager.MOVE_TASK_WITH_HOME); } else { Log.e("TaskReturn", "WHERE IS MY EXTRA!?!?!"); //Boo... } } 

 <uses-permission android:name="android.permission.REORDER_TASKS"/> 

 <receiver android:name=".TaskReturn"/> 

基本上这个想法是,你将Activity.getTaskId()调用的结果标记为状态。 稍后,在创build通知以恢复到该活动的任务时,请抓住任务ID并将其添加到额外的位置。 然后,设置挂起的意图,指向一个广播接收器,拉出任务ID并启动该任务。

看起来这需要使用API​​ 21,并且我怀疑它可能需要一些额外的错误检查,如果任务已经退出,但它符合我的目的。