使用服务启动可以执行操作的持续通知

Using a service to start an ongoing notification that can take an action

我已经创建了一个服务,以便我可以有一个持久的通知。我希望此通知有一个选项,可以将意图发送到我的另一个活动。

该选项将固有地停止应用程序产生的每个进程。因此,一旦按下操作,通知也需要关闭。

我正在尝试使用挂起的广播意图来完成此操作,但由于某种原因,广播接收器没有捕捉到意图。我在服务的 onCreate() 方法中动态注册接收器,并在服务的 onDestroy() 方法中注销它。

public class myService extends IntentService {
    private boolean shown = false;
    private ButtonReceiver buttonReceiver;

    //Side note: this is legacy code. Necessary?
    public myService() {
        super("myService");
    }

    @Override
    public void onCreate() {
        super.onCreate();

        IntentFilter filter = new IntentFilter("com.myapp.KILL_NOTIFICATION");
        this.buttonReceiver = new ButtonReceiver();
        this.registerReceiver(this.buttonReceiver, filter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(this.buttonReceiver);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        if(intent.getAction() == "com.myapp.START_SERVICE") {
            //generate a unique id for the notification
            int id = Integer.parseInt(new SimpleDateFormat("ddHHmmss", Locale.US).format(new Date()));

            //create a pending intent to send off when the kill action is pressed
            Intent buttonIntent = new Intent("com.myapp.KILL_NOTIFICATION");
            buttonIntent.putExtra("notificationId", id);
            PendingIntent btPendingIntent = PendingIntent.getBroadcast(this, 0, buttonIntent, 0);

            Notification.Builder builder = new Notification.Builder(getApplicationContext());
            builder.setAutoCancel(false);
            builder.setContentTitle("my app");
            //builder.setContentText("Press this notification to kill.");
            builder.setOngoing(true);
            builder.setSmallIcon(R.drawable.ic_launcher);
            //builder.setContentIntent(pendingIntent);
            builder.addAction(R.drawable.ic_clear_black_24dp, "Kill my app", btPendingIntent);
            builder.setWhen(0);
            builder.setPriority(Notification.PRIORITY_MAX);

            Notification notification = builder.build();
            NotificationManager notificationManager =
                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            //TODO need to find first unused notif id
            notificationManager.notify(id, notification);
        }
    }

    public class ButtonReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {

            int notificationId = intent.getIntExtra("notificationId", 0);

            Intent killIntent = new Intent("com.myapp.KILL_EVERYTHING");
            killIntent.addCategory(Intent.CATEGORY_DEFAULT);
            startActivity(killIntent);

            //cancel notification
            NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.cancel(notificationId);
        }
    }
}

IntentServiceonHandleIntent() 方法完成后自行停止,因此当它发生时,您动态注册的 Receiver 不再能接收广播。

您不需要 Service 来维持持续的 Notification。在您的情况下,您可以直接发出 Notification,而不是启动 Service 来执行此操作。然后在清单中静态注册您的接收器 class,并使用显式 IntentNotification.

向其广播

ButtonReceiver 移动到它自己的 class 文件,并像这样在清单中注册它:

<receiver android:name=".ButtonReceiver" />

您需要对传递给 onReceive()context 参数调用 startActivity(),就像您是 getSystemService() 一样。您还需要将以下标志添加到 Intent.

killIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

然后只需将 NotificationPendingIntentbuttonIntent 更改为:

Intent buttonIntent = new Intent(this, ButtonReceiver.class);

如果那是唯一的广播 ButtonReceiver 将处理,您将不再真正需要 KILL_NOTIFICATION 操作。