从通知启动的活动中按下返回/主页键退出应用程序

4
我有一个通过通知启动的活动。我使用TaskStackBuilder设置后台堆栈,以便当用户按下返回键或操作栏标题按钮时,可以返回到应用程序。然而,它并没有以这种方式工作,相反,按下返回键或操作栏标题按钮总是导致应用程序关闭。
值得一提的是,我的项目结构组织方式使所有UI组件都在Android库(com.be.commotion)中,而外部"包装"项目使用该库。
这是我构建通知的方法:
// This is the activity that will be launched when tapping the notification
Intent intentNotification = new Intent(this, NowPlaying.class);
intentNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

// Create the back stack so the user can get back to the main activity when pressing the back button
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(NowPlaying.class);
stackBuilder.addNextIntent(intentNotification);
PendingIntent pendingNowPlayingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

// Setup the custom notification view
RemoteViews notificationContent = new RemoteViews(getPackageName(), R.layout.notification_now_playing);
....

// Setup the intent that will play/stop music when the stop button is tapped
Intent musicControlIntent = new Intent(this, CommotionMediaPlayer.class);

PendingIntent musicPendingIntent = PendingIntent.getService(this, 0, musicControlIntent, PendingIntent.FLAG_UPDATE_CURRENT);

notificationContent.setOnClickPendingIntent(R.id.ibMediaControl, musicPendingIntent);

// Update the notification with this info
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                    .setSmallIcon(R.drawable.ic_launcher)
                    .setContentTitle(song.text)
                    .setContentText(song.artist)
                    .setContentIntent(pendingNowPlayingIntent)
                    .setLargeIcon(artwork)
                    .setContent(notificationContent)
                    .setOngoing(true);

NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

// Using the nowPlayingNotificationId allows the notification to be updated with later calls instead of causing a new notification to show up
mNotificationManager.notify(nowPlayingNotificationId, builder.build());

以下是我的AndroidManifest.xml(用于包装项目)中适用的定义:

这里是需要翻译的内容。

    <activity android:name="com.be.commotion.ui.StartupActivity"
            android:label="@string/app_name"
            android:noHistory="true"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.Holo.NoActionBar" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

    <activity android:name="com.be.commotion.ui.NowPlaying"
              android:label="Now Playing"
              android:parentActivityName="com.be.commotion.ui.StartupActivity"
              android:screenOrientation="portrait">

        <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.be.commotion.ui.StartupActivity" />

    </activity>

为什么操作栏按钮会这样做,我不知道 - 并且在这里没有看到任何代码。但是我想指出,您想要使用返回按钮所做的事情违反了Android流程,并且会妨碍用户体验。 返回按钮应该返回到用户之前所在的位置。 将他们带到主活动意味着他们正在向前而不是向后。 - Navarr
此外,听起来你正在使用主页按钮来触发“返回”,而你应该让主页按钮启动MainActivity或ParentActivity(这并不总是意味着返回)。 - Navarr
@Navarr - 感谢您的评论...我不确定我是否同意您关于后退按钮的说法。如果我使用Gmail应用程序并从我的通知栏中打开一封电子邮件,则按下后退按钮会将我带出电子邮件并显示收件箱视图。这对我来说感觉很自然,也是我想在我的应用程序中实现的。 - bugfixr
根据返回键,为什么不直接在NowPlaying中重写onBackPressed()并启动StartupActivity呢? - ozbek
@bugfixr你解决了吗?我也遇到了同样的问题,昨天开始一直在搜索。按照stackoverflow上提供的所有帮助,我和你做的一样,但无法解决。你能帮帮我吗? - Gaurav Arora
3个回答

3

您可以通过两个步骤来完成此操作,而无需使用TaskStackBuilder
1/ 为您的Intent设置标志

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

2/ 为您的PendingIntent设置标记

pendingIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_CANCEL_CURRENT);

对我有效,祝你们好运


需要建议。所有都是正确的,但当我点击设备的返回按钮并从应用程序退出时,单击事件(播放/暂停/前进/关闭)按钮不起作用。请帮帮我。 - Helal Khan
只有在用户在应用程序运行时打开通知时,这才能解决问题。 - Mohamed Nageh
@MohamedNageh 我同意。只有在应用程序运行时才有效。有什么办法可以使它通用化? - tsik
需要一些运气,因为如果应用程序没有运行,这不起作用。 - Oush

2

在添加所需的活动(直接在通知被单击时调用的活动)之前将主要活动添加到堆栈中。

例如:
stackBuilder.addNextIntent(new Intent(this,MainActivity.class));
stackBuilder.addNextIntent(new Intent(this,DesiredActivity.class));

0
也许我们正在解决一个略微不同的问题,但归根结底是相同的问题。对于我们来说,解决方案是使用:
startActivityForResult(intent, 0);

我们想要做的是有一个通知,点击通知可以跳转到Activity B,当点击返回按钮时可以回到Activity A。
有两种方法可以实现:

从B启动A:适用于所有在您的应用中的活动

  1. 在通知包中发送一个参数,以定义该活动是从通知启动的
  2. 覆盖活动B的OnBack并使其使用CLEAR_TOP标志启动活动A(以便返回不会带回到B)

从A启动B:适用于不同应用程序中的活动(例如打开电子邮件客户端)

  1. 使通知指向Activity A(传递必要的参数以了解该活动是从通知启动的)
  2. 使用startActivityForResult启动活动B(例如电子邮件客户端)。如果使用正常的startActivity,则“返回”按钮将无法正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接