使用通知恢复单实例活动

时间:2019-03-10 20:32:37

标签: android android-activity android-notifications single-instance

我有一个正常的活动,我们称它为A,这是打开应用程序时向用户显示的第一个活动。活动A有一个用于启动活动的按钮,我们称它为B,清单中的launchMode设置为singleInstance。活动B进行了一些处理。

用户可以按下主屏幕按钮,然后再次打开应用程序,这将向他们显示开始活动,也就是活动A。如果用户再次单击按钮(在活动A中),则将向他们显示活动B。在这种情况下,活动B将不会重新启动,即不会调用onCreate,因为它是我想要的singleInstance

我希望用户一旦按下主屏幕按钮,便可以更轻松地回到活动B。因此,我创建了一个持续的通知,使用户可以将活动B带回来。活动B完成后,正在进行的通知将被取消。

由于该问题,单击正在进行的通知会再次重新创建活动B,即,再次调用onCreate。我不知道为什么这里的行为与单击活动A上的按钮不同。这是我创建通知的方式:

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>

2 个答案:

答案 0 :(得分:1)

在您写的评论中:

  

我实际上正在开发一个调用应用程序。活动A是主屏幕,   而B是呼叫活动。我想让用户回头   通话期间转到主屏幕,所以我有意和有意   选择在最近的应用程序中创建该应用程序的两个实例(您可以看到   Android上默认电话应用中的确切行为)

在这种情况下,您可能确实希望有两个可以在两个任务之间切换的任务。为此,您需要使用taskAffinity。您的CallActivity的启动模式应该为singleTasksingleInstance,并且您应该设置android:taskAffinity="call"或类似的名称。为了避免混淆用户,您还应该为android:label提供不同的android:icon和不同的CallActivity,以便当此任务出现在最近任务列表中时,它看起来与应用的其余部分。确保在启动CallActivity时也设置FLAG_ACTIVITY_NEW_TASK。构建Notification时,还应该设置此标志。

答案 1 :(得分:0)

在创建FLAG_ACTIVITY_SINGLE_TOP对象之前,需要将Intent设置为notifyIntent实例(在您的情况下为PendingIntent)。

换句话说:

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());