2013-03-05 104 views
0

我正在创建在状态栏中显示通知图标的应用程序。当用户打开状态栏并点击图标时,应用程序应该启动。从状态栏启动应用程序而无需重新创建

我正在寻找一种避免在此次启动过程中重新创建应用程序的方法。我已经创建了测试应用程序,并向处理程序onCreate,onRestart,onResume,onStop和onDestroy添加日志消息。日志消息说明了问题:

  1. 用户启动应用程序 - 的onCreate,的onResume
  2. 用户按下HOME键 - 的onStop
  3. 用户打开的应用程序列表并重新开始应用 - onRestart,的onResume
  4. 用户按下HOME按钮 - onStop
  5. 用户打开最近的应用程序列表并选择应用程序 - onRestart,onResume
  6. 用户按HOME按钮 - onStop
  7. 用户打开状态栏并点击应用程序图标 - onDestroy,onCreate,onResume。

第7步有一个不同的行为,然后3)和5) - 这里有onDestroy。换句话说,应用程序的实例被重新创建。是否有可能避免这种娱乐?

这是我的测试活动的代码:

public class MainActivity extends Activity { 
    private final String LOG_TAG = "com.example.notificationtest"; 

    @Override protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     showNotification(this); 
     Log.d(LOG_TAG, "NotificationTest: OnCreate"); 
    } 

    @Override protected void onRestart() { 
     super.onRestart(); 
     Log.d(LOG_TAG, "NotificationTest: OnRestart"); 
    } 

    @Override protected void onResume() { 
     super.onResume(); 
     Log.d(LOG_TAG, "NotificationTest: OnResume"); 
    } 

    @Override protected void onDestroy() { 
     super.onDestroy(); 
     Log.d(LOG_TAG, "NotificationTest: OnDestroy"); 
    } 

    @Override protected void onStop() { 
     super.onStop(); 
     Log.d(LOG_TAG, "NotificationTest: OnStop"); 
    } 


    private static final int NOTIF_ID = 91371; 

    public static void showNotification(Context context) { 
     final Intent result_intent = new Intent(context, MainActivity.class); 
     result_intent.setAction(Intent.ACTION_MAIN); 
     result_intent.addCategory(Intent.CATEGORY_LAUNCHER); 
     //result_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     //result_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 
     //result_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);     

     TaskStackBuilder stack_builder = TaskStackBuilder.create(context); 
     stack_builder.addParentStack(MainActivity.class); 
     stack_builder.addNextIntent(result_intent); 

     PendingIntent pending_intent = stack_builder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); 

     android.support.v4.app.NotificationCompat.Builder builder = new android.support.v4.app.NotificationCompat.Builder(context); 

     Resources res = context.getResources(); 
     builder.setContentIntent(pending_intent) 
      .setSmallIcon(R.drawable.ic_launcher) 
      .setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher)) 
      .setTicker("test") 
      .setWhen(System.currentTimeMillis()) 
      .setAutoCancel(false) 
      .setContentTitle("title") 
      .setContentInfo("cinfo") 
      .setContentText("ctext"); 
     Notification n = builder.build(); 
     n.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR; 

     NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); 
     nm.notify(NOTIF_ID, n);  
    } 
} 

有一些标志,可以设置为result_intent,像FLAG_ACTIVITY_CLEAR_TOPFLAG_ACTIVITY_CLEAR_TASKFLAG_ACTIVITY_NEW_TASK。它们允许指定在启动时应重新启动活动(使用活动启动模式“singleTop”,“singleTask”等)。但是应该设置什么标志以避免重新启动?可能我应该以某种方式配置pending_intent?

任何帮助将不胜感激。

解决

非常感谢您的答案,问题就解决了。

同样的问题被描述为here。我检查了该主题的测试项目,发现与我的代码有差异。为了解决这个问题,我的代码应该如下方法改变:

final Intent result_intent = new Intent(context, MainActivity.class); 
//result_intent.setAction(Intent.ACTION_MAIN); // (1) 
//result_intent.addCategory(Intent.CATEGORY_LAUNCHER); // (2) 
result_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 

另一组标志工程太:

result_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 

主要观点是注释行(1)和(2)

+0

是的onSaveInstanceState'()'和'onRestoreInstance()'被称为?比尝试解决活动生命周期更好的选择可能是通过这些方法来恢复基本运行数据,这会使您存储的数据在onDestroy中保持不变。 – 2013-03-05 06:48:57

+1

看看这个SO帖子:http://stackoverflow.com/questions/3305088/how-to-make-notification-intent-resume-rather-than-making-a-new-intent – appsroxcom 2013-03-05 07:00:01

+0

是的,onSaveInstanceState()和onRestoreInstance () 叫做。我不'尝试解决生命周期。这里描述了问题的根源:http://forum.unity3d.com/threads/172700-open-Unity-application-using-notification-in-statusbar?p=1181292#post1181292 – dvpublic 2013-03-05 09:59:49

回答

0

补充一点:

result_intent..setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP 
            | Intent.FLAG_ACTIVITY_NEW_TASK); 

它就像

意图。FLAG_ACTIVITY_REORDER_TO_FRONT

还保持活性堆栈

+0

谢谢,但没有结果。它看起来像行为不依赖于意向标志集:( – dvpublic 2013-03-05 10:01:55

+0

纠正:这套标志工作正常,如果我评论Intent.ACTION_MAIN和CATEGORY_LAUNCHER,谢谢。 – dvpublic 2013-03-05 10:37:55

相关问题