如何使用广播接收器停止前台服务

How to stop a foreground service using a Broadcast Receiver

现在我有一个创建通知的前台服务:

Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

        Intent broadcastIntent = new Intent(this, NotificationReceiver.class);
        broadcastIntent.putExtra("toastMessage", "Test message");
        PendingIntent actionIntent = PendingIntent.getBroadcast(this, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        String channelId = "fcm_default_channel";
        Bitmap largeIcon = BitmapFactory.decodeResource(getResources(), R.drawable.notification_uploading);
        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, channelId)
                        .setSmallIcon(R.drawable.animation_wifi)
                        .setContentTitle("Upload Photos")
                        .setContentText("1 photo uploading")
                        .setContentIntent(pendingIntent)
                        .addAction(R.drawable.icon_back_black_arrow, "Cancel", actionIntent);


        startForeground(1111, notificationBuilder.build());

它有一个调用我的广播接收器的取消按钮。我将如何停止广播接收器中的前台服务class?

public class NotificationReceiver extends BroadcastReceiver {
    private static final String TAG = "NotificationReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        String message = intent.getStringExtra("toastMessage");
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
        //When the foreground notification cancel button is clicked, this method is called
    }
}

stopForeground()方法可以停止服务,但它是服务class的一部分。它不能从接收器调用。

这里有两种解决方法,你可以体会一下。

一个解决方案,在你的服务class中,注册一个BroadcastReceiver,当目标BroadcastReceiver收到消息时,向服务接收者发送广播。

//the service class
private final BroadcastReceiver closeService = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
        /** here you can pass params, which you want to 
         * true use STOP_FOREGROUND_REMOVE,or directyly useing
         * STOP_FOREGROUND_REMOVE, you can also use  
         * remove nofitication 
         */
            stopForeground(int/boolean);
    };
IntentFilter filter = new IntentFilter(""my.close.service"");
registerReceiver(mYReceiver, iFilter);

public class NotificationReceiver extends BroadcastReceiver {
    private static final String TAG = "NotificationReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        String message = intent.getStringExtra("toastMessage");
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
        // here to send it to service
       sendBroadcast(new Intent("my.close.service"))
    }
}

另一种解决方法是在broadcastReceiver中重启服务,在onStartCommad方法中,根据action关闭它。

public class NotificationReceiver extends BroadcastReceiver {
    private static final String TAG = "NotificationReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        String message = intent.getStringExtra("toastMessage");
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
        // here to restart the service
       startService(new Intent(this, YourService.class).setAction("STOP_ACTION"));
    }
}

// in the Service.java onStartCommand method, check the action and stop it.
public void onStartCommand(){
  if(intent.getAction() != null && 
   intent.getAction().equals("STOP_ACTION")) {
     stopForeground(true);
  }
}

最后,如果您熟悉EventBus,您可以直接使用它向服务派发事件。或者你可以在Service里面把BroadcastReceiver定义成一个内在的class,那么你也可以直接调用