【问题标题】:How to stop a foreground service using a Broadcast Receiver如何使用广播接收器停止前台服务
【发布时间】:2020-01-23 12:51:45
【问题描述】:

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

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

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

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
    }
}

【问题讨论】:

    标签: android broadcastreceiver foreground-service


    【解决方案1】:

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

    这里有两种解决方案,你可以意识到这一点。

    一种解决方案,在您的服务类中注册一个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,您可以使用它直接向服务分发事件。或者你可以将BroadcastReceiver定义为Service中的一个内部类,那么你也可以直接调用它

    【讨论】:

    • 是否可以通过在.addAction 上使用来停止当前服务?而不是使用广播接收器
    • @Lenoarod,stopForeground() 方法不采用 Notification_ID。它需要一个布尔值或 int(标志),但不是 notificationID。
    • @user3410835,是的,我用它作为一些参数。我修改它。谢谢
    • @Lenoarod,stopForeground() 和 stopSelf() 有什么区别?我们是否需要调用这两种方法来停止前台服务?截至目前,我只使用 stopSelf() 并且它正在工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多