使用通知恢复 singleInstance Activity
Bring a singleInstance Activity Back Using a Notification
我有一个普通的activity,姑且称它为A,它是打开应用程序时呈现给用户的第一个activity。 Activity A 有一个启动 activity 的按钮,我们称它为 B,launchMode
在清单中设置为 singleInstance
。 Activity B 做了一些处理。
用户可以按下主页按钮并再次打开应用程序,这将向他们展示开始的 activity,又名 activity A. 如果用户再次单击该按钮(在 activity A),它们将显示为 activity B。在这种情况下,activity B 将不会重新启动,即不会调用 onCreate
,因为它是 singleInstance
,这就是我想要的。
我想让用户在按下主页按钮后更容易返回到activity B。因此,我创建了一个持续通知,让用户带回 activity B。一旦 activity B 完成,正在进行的通知将被取消。
现在的问题是,单击正在进行的通知会再次重新创建 activity B,即再次调用 onCreate
。我不知道为什么这里的行为与单击 activity 上的按钮不一样。这是我创建通知的方式:
Intent notifyIntent = new Intent(mContext, CallActivity.class);
PendingIntent notifyPendingIntent = PendingIntent.getActivity(
mContext, 0, notifyIntent, PendingIntent.FLAG_NO_CREATE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, CHANNEL_ID)
.setSmallIcon(R.drawable.baseline_call_white_18)
.setContentTitle(title)
.setContentText(text)
.setOngoing(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(notifyPendingIntent);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mContext);
notificationManager.notify(NOTIFICATION_ID, builder.build());
谁能告诉我为什么这不起作用,我怎样才能让它按照我描述的方式工作?
编辑
这是我的清单的片段:
<application
android:name="com.mnm.caller.IMApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name="com.mnm.caller.activities.SplashActivity"
android:configChanges="orientation|keyboardHidden"
android:noHistory="true"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.mnm.caller.activities.LoginActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="@style/AppTheme.NoTitleBar"
android:screenOrientation="portrait" />
<activity
android:name="com.mnm.caller.activities.HomeActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="@style/AppTheme.NoTitleBar"
android:screenOrientation="portrait" />
<activity
android:name="com.mnm.caller.activities.CallActivity"
android:configChanges="orientation|keyboardHidden"
android:launchMode="singleInstance"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoTitleBar" />
<service
android:name="com.mnm.caller.services.IMFirebaseMessagingService"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
在创建 PendingIntent
对象之前,您需要将 FLAG_ACTIVITY_SINGLE_TOP
设置为 Intent
实例(在您的例子中是 notifyIntent
)。
换句话说:
Intent notifyIntent = new Intent(mContext, CallActivity.class).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent notifyPendingIntent = PendingIntent.getActivity(
mContext, 0, notifyIntent, PendingIntent.FLAG_NO_CREATE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, CHANNEL_ID)
.setSmallIcon(R.drawable.baseline_call_white_18)
.setContentTitle(title)
.setContentText(text)
.setOngoing(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(notifyPendingIntent);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mContext);
notificationManager.notify(NOTIFICATION_ID, builder.build());
在您写的评论中:
I'm actually developing a calling app. Activity A is the home screen,
while B is the calling activity. I want to let the users navigate back
to the home screen during a call, so I intentionally and knowingly
chose to create two instances of the app in recent apps (you can see
the exact behavior in the default phone app on Android)
如果是这种情况,您可能确实希望有 2 个可以在它们之间切换的独立任务。为此,您需要使用 taskAffinity
。你的 CallActivity
应该有 singleTask
或 singleInstance
的启动模式,你应该设置 android:taskAffinity="call"
或类似的东西。为了不混淆您的用户,您还应该为 CallActivity
提供不同的 android:label
和不同的 android:icon
,这样当此任务出现在最近任务列表中时,它看起来与你的应用程序的其余部分。确保在启动 CallActivity
时也设置了 FLAG_ACTIVITY_NEW_TASK
。您还应该在构建 Notification
.
时设置此标志
我有一个普通的activity,姑且称它为A,它是打开应用程序时呈现给用户的第一个activity。 Activity A 有一个启动 activity 的按钮,我们称它为 B,launchMode
在清单中设置为 singleInstance
。 Activity B 做了一些处理。
用户可以按下主页按钮并再次打开应用程序,这将向他们展示开始的 activity,又名 activity A. 如果用户再次单击该按钮(在 activity A),它们将显示为 activity B。在这种情况下,activity B 将不会重新启动,即不会调用 onCreate
,因为它是 singleInstance
,这就是我想要的。
我想让用户在按下主页按钮后更容易返回到activity B。因此,我创建了一个持续通知,让用户带回 activity B。一旦 activity B 完成,正在进行的通知将被取消。
现在的问题是,单击正在进行的通知会再次重新创建 activity B,即再次调用 onCreate
。我不知道为什么这里的行为与单击 activity 上的按钮不一样。这是我创建通知的方式:
Intent notifyIntent = new Intent(mContext, CallActivity.class);
PendingIntent notifyPendingIntent = PendingIntent.getActivity(
mContext, 0, notifyIntent, PendingIntent.FLAG_NO_CREATE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, CHANNEL_ID)
.setSmallIcon(R.drawable.baseline_call_white_18)
.setContentTitle(title)
.setContentText(text)
.setOngoing(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(notifyPendingIntent);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mContext);
notificationManager.notify(NOTIFICATION_ID, builder.build());
谁能告诉我为什么这不起作用,我怎样才能让它按照我描述的方式工作?
编辑
这是我的清单的片段:
<application
android:name="com.mnm.caller.IMApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name="com.mnm.caller.activities.SplashActivity"
android:configChanges="orientation|keyboardHidden"
android:noHistory="true"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.mnm.caller.activities.LoginActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="@style/AppTheme.NoTitleBar"
android:screenOrientation="portrait" />
<activity
android:name="com.mnm.caller.activities.HomeActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="@style/AppTheme.NoTitleBar"
android:screenOrientation="portrait" />
<activity
android:name="com.mnm.caller.activities.CallActivity"
android:configChanges="orientation|keyboardHidden"
android:launchMode="singleInstance"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoTitleBar" />
<service
android:name="com.mnm.caller.services.IMFirebaseMessagingService"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
在创建 PendingIntent
对象之前,您需要将 FLAG_ACTIVITY_SINGLE_TOP
设置为 Intent
实例(在您的例子中是 notifyIntent
)。
换句话说:
Intent notifyIntent = new Intent(mContext, CallActivity.class).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent notifyPendingIntent = PendingIntent.getActivity(
mContext, 0, notifyIntent, PendingIntent.FLAG_NO_CREATE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, CHANNEL_ID)
.setSmallIcon(R.drawable.baseline_call_white_18)
.setContentTitle(title)
.setContentText(text)
.setOngoing(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentIntent(notifyPendingIntent);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mContext);
notificationManager.notify(NOTIFICATION_ID, builder.build());
在您写的评论中:
I'm actually developing a calling app. Activity A is the home screen, while B is the calling activity. I want to let the users navigate back to the home screen during a call, so I intentionally and knowingly chose to create two instances of the app in recent apps (you can see the exact behavior in the default phone app on Android)
如果是这种情况,您可能确实希望有 2 个可以在它们之间切换的独立任务。为此,您需要使用 taskAffinity
。你的 CallActivity
应该有 singleTask
或 singleInstance
的启动模式,你应该设置 android:taskAffinity="call"
或类似的东西。为了不混淆您的用户,您还应该为 CallActivity
提供不同的 android:label
和不同的 android:icon
,这样当此任务出现在最近任务列表中时,它看起来与你的应用程序的其余部分。确保在启动 CallActivity
时也设置了 FLAG_ACTIVITY_NEW_TASK
。您还应该在构建 Notification
.