当应用程序关闭时,点击通知按钮打开活动

3

当用户在我的通知中点击按钮时,我正在尝试打开MainActivity,而应用程序仅在后台运行服务。当点击按钮时,这些代码将在Service类中触发:

Intent openApp = new Intent(this, MainActivity.class);
openApp.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(openApp);

我已经检查过了,这些行被触发了,所以在响应按钮的点击方面没有问题,唯一的问题是Activity没有打开。
你有什么建议吗?为什么对我不起作用,我该如何使其奏效?
编辑
有人要求我提供更多代码,在我的ServiceonStartCommand()中,如果它启动的操作包含一个停止操作,我会调用killService()方法来终止Service,启动MainActivity并执行一些其他操作。
if (action != null && action.equals(ACTION_STOP_SERVICE)) {
    killService();
}

为了设置“通知”按钮,我使用以下代码:Notification
Intent stopActionIntent = new Intent(this, TimerService.class);
        stopActionIntent.setAction(ACTION_STOP_SERVICE);
        PendingIntent stopActionPendingIntent = PendingIntent.getService(this, 1, stopActionIntent, PendingIntent.FLAG_IMMUTABLE);

timerNotificationBuilder.addAction(R.drawable.stop, "Stop", stopActionPendingIntent);

正如我所说,按钮已经对用户的点击做出了反应,所以这不是问题。


你尝试过使用 Intent.FLAG_IMMUTABLE 吗? - Sambhav Khandelwal
在哪里?在按钮的意图上吗?是的。 - Nitzan Daloomy
thisService 的上下文,我也尝试使用 getAppContext()getBaseContext(),但都没有成功。 - Nitzan Daloomy
咦?你是从“BroadcastReceiver”还是从“Service”中尝试打开它的?我现在有点困惑。 - Sambhav Khandelwal
抱歉,我有急事去了一下。现在回来了。所以,你想在按下停止按钮时打开主活动吗? - Sambhav Khandelwal
显示剩余15条评论
2个回答

4

您可以尝试在 BroadcastReceiver 中接收点击事件,然后从那里打开活动。

  1. 尝试使用以下方法向通知添加操作按钮:
timerNotificationBuilder.addAction(createNotificationActionButton("STOP");

createNotificationActionButton 方法在哪里:

public NotificationCompat.Action createNotificationActionButton(String text){
        Intent intent = new Intent(this, StopwatchNotificationActionReceiver.class);

        @SuppressLint("InlinedApi") PendingIntent pendingIntent = PendingIntent.getBroadcast(this, new Random().nextInt(100), intent, PendingIntent.FLAG_IMMUTABLE);

        return new NotificationCompat.Action(0, text, pendingIntent);
    }
  1. 创建一个名为 StopwatchNotificationActionReceiver 的类,并使其扩展 BroadcastReceiver。以下是该类的代码:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class StopwatchNotificationActionReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        PrefUtil.setIsRunningInBackground(context, false);
        PrefUtil.setTimerSecondsPassed(context, 0);
        PrefUtil.setWasTimerRunning(context, false);
        context.stopService(MainActivity.serviceIntent);
        Intent activityIntent = new Intent(context, MainActivity.class);
        activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActvity(activityIntent);
    }
}

同时,您需要在清单文件中注册该接收器,如下所示:

<receiver android:name="StopwatchNotificationActionReceiver"/>
  1. 其中MainActivity.serviceIntent是一个公共静态变量,看起来像这样:
public static Intent serviceIntent;

而这个意图仅用于像这样启动服务:

//In onCreate
serviceIntent = new Intent(this, TimerService.class);

//In onPause
PrefUtil.setTimerSecondsPassed(this,seconds);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForegroundService(serviceIntent);
            }

或者你可以尝试简单的方法:

if (action != null && action.equals(ACTION_STOP_SERVICE)) {
    Context context = this;
    Intent activityIntent = new Intent(context, MainActivity.class);
        activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActvity(activityIntent);
    killService();
}

编辑


另一个解决方案在这里。你需要参考我的repo,因为我已经修改了文件以完成你的任务。在服务类中,参考this方法。在那里,如果动作是重置(r),我就启动活动。否则,它会打开广播接收器。然后,在活动中,我在onResume()方法中接收额外的内容。如果没有点击重置按钮,它会打开接收器类

一如既往地,您可以从这里查看应用程序的结果。

希望这段代码能够完成您的工作。


让我编辑一下并给出另一个答案。 - Sambhav Khandelwal
阅读了您的建议后,我不明白 - 开启活动的代码在哪里? - Nitzan Daloomy
不仅如此,我发现很难理解正在发生的事情——createNotificationActionButton()方法是用来做什么的?为什么它比我之前的方法更好?它是如何工作的?你在哪里注册了广播?我真的迷失在这里了。 - Nitzan Daloomy
现在,我想知道您是否希望在单击停止按钮时停止计时器?如果要停止,则使用我提到的广播接收器,否则只需使用挂起意图即可。 - Sambhav Khandelwal
与此同时,如果我找不到一种使用停止按钮打开应用的方法,我就不会显示按钮,用户将不得不进入应用程序然后停止服务。虽然对用户来说最好能够只单击停止按钮,剩下的就可以自动完成,这就是我提出这个问题的原因。 - Nitzan Daloomy
显示剩余29条评论

-1
我找到了!请查看这个答案
这个答案建议启用ScreeanOverlay设置,因为从Android 10开始,您不能仅通过调用我使用的代码行来从后台打开活动。
要使其工作,您需要通过您的Manifest.xml添加此权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

然后用户必须启用“显示在其他应用程序上方”设置。
我搜索了一个更容易让用户进入此设置的选项,找到了this answer
这个答案提供了一个代码,可以将用户重定向到“显示在其他应用程序上方”设置。

if (!Settings.canDrawOverlays(this)) {
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, 0);
}

然后我通过通知内容(文本)指导用户如何启用设置。
一旦启用了该设置,我之前使用的行将起作用。

所以,问题解决了吗?

并未完全解决

上述整个配置是有效的,但仅在应用程序未被杀死时才有效。
如果应用程序已被杀死并且我尝试上述方法,则应用程序将加入最近使用的应用程序列表,但不会打开或显示。
解决此问题的解决方案将被接受为答案,而不是此解决方案。


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