[英]Notification Intent - How to resume the activity in a notification without resetting?
[英]How to make notification intent resume rather than making a new intent?
我在這里有一個簡單的webview活動,加載后它會自動顯示正在進行的通知。 我們的想法是,人們可以遠離此活動,並通過下拉菜單並選擇它,從他們想要的任何屏幕再次快速訪問它。 然后,當他們想要時,他們可以通過點擊菜單按鈕並點擊退出關閉通知,然后清除通知。 一切正常。 但是,當按下通知時,它會啟動活動的新實例。 我需要更改什么才能看到活動是否尚未被銷毀,我可以回調用該實例(恢復它),因此不需要再次加載它,也不需要在我的堆棧中添加其他活動。 有任何想法嗎? 任何幫助將不勝感激。
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
只是為了確保我說得對,這是你的建議嗎?
我有點擔心這條線,
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...");
}
我們的想法是,人們可以遠離此活動,並通過下拉菜單並選擇它,從他們想要的任何屏幕再次快速訪問它。
請選擇此選項。
但是,當按下通知時,它會啟動活動的新實例。
這將默認發生。
我需要更改什么才能看到活動是否尚未被銷毀,我可以回調用該實例(恢復它),因此不需要再次加載它,也不需要在我的堆棧中添加其他活動。
擺脫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"
我將它放在我的應用程序的主要活動部分下的清單中,然后通知項重用已經在進行中的實例。
沒有解決方案適合我,所以我找到了自己的方式。 我的所有活動都是從BaseActivity
擴展而來的。 我按照一系列簡單的步驟使我的推送通知點擊恢復應用程序:
第1步:記錄當前活動的常量:
public static Context currentContext;
第2步:在BaseActivity
擴展的活動的onCreate()
或onResume()
中
currentContext = this;
第3步:創建通知時的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不同,我只需要返回其中一個任務的頂部,而不是特定的活動,這些活動可能隱藏在其中一個任務中。 我認為這與提出的問題類似,可能對其他人有用。
我的解決方案包括一個用於跟蹤當前任務的靜態任務id,一個用於處理待處理意圖的廣播接收器,一個新的uses-permission標簽,以及一些簡單的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()的調用結果標記為狀態。 稍后,在創建恢復到該活動任務的通知時,抓取任務ID並將其投入額外的任務ID。 然后,將待定意圖設置為指向拉出任務ID並啟動該任務的廣播接收器。
看起來這需要API 21和我使用的調用,我懷疑它可能需要一些額外的錯誤檢查,如果任務已經退出,但它符合我的目的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.