Android8. An idea of keeping 0 background service alive

Time:2022-5-18

Original address:Android8. An idea of keeping 0 background service alive | grocery nest of stars one

There is an MQ service in the project, which needs to be connected all the time. When receiving a message, it will send voice, and the mobile phone should also realize this function in the lock screen

At present, it is implemented by using the broadcast mechanism. Every time MQ receives a message, it triggers the service operation logic once

The above functions can be realized after successful testing in the Android 11 version

step

Specific process:

  1. Enter app
  2. Start background service
  3. Thread, MQ service, background connection
  4. MQ consumption event, send broadcast
  5. In the broadcast receiver, the function of starting the service (if the service has been turned off) and text voice playback are processed

1. Broadcast registration

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        //Match the previously defined action
        if ("OPEN_SERVICE".equals(action)) {
            if (!ServiceUtils.isServiceRunning(MqMsgService.class)) {
                Log. E ("-- Test", "if the service is not started, start the service first");
                Intent myIntent = new Intent(context, MqMsgService.class);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    context.startForegroundService(intent);
                } else {
                    context.startService(intent);
                }

            }

            String text = intent.getStringExtra("text");
            Log. E ("-- Test", "broadcast message" + text);

            EventBus.getDefault().post(new SpeakEvent(text));
        }
    }
}

The related operations of voice initialization are carried out in the service, which will not be repeated here (forwarding time events through eventbus)

It should be noted here that Android 8 0 version, broadcast cannot be directlystartService()Start the service, but throughstartForegroundService()Method, and calledstartForegroundService()Method, the service needs to call a method within 5SstartForeground()

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    Notification notification = NotifyUtil. Sendnotification (this, "tablet", "background MQ service running", notificationcompat. Priority_high);
    startForeground(1, notification);
}

The above code isWritten in oncreate method in servicePreviously, I found information that a notification bar is needed so that the service will not be shut down by the Android system, and I don’t know whether it works

It should also be noted that permission needs to be declared

Notifyutil tool class code
public class NotifyUtil {
    private static String channel_id="myChannelId";
    private static String channel_ Name = "new news";
    Private static string description = "new message notification";
    private static int notifyId = 0;
    private static NotificationManager notificationManager;

    public static void createNotificationChannel(){
        if (notificationManager != null) {
            return;
        }
        //Android8. The following methods need to be called above 0 (api26), but the lower version does not support calling because the support library is old
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel channel = new NotificationChannel(channel_id,channel_name,importance);
            channel.setDescription(description);
            notificationManager = (NotificationManager) ActivityUtils.getTopActivity().getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);
        }else{
            notificationManager = (NotificationManager) ActivityUtils.getTopActivity().getSystemService(Context.NOTIFICATION_SERVICE);
        }
    }

    public static void sendNotification(String title,String text){
        createNotificationChannel();
        Notification notification = new NotificationCompat.Builder(ActivityUtils.getTopActivity(),channel_id)
                .setContentTitle(title)
                .setContentText(text)
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(ResourceUtils.getMipmapIdByName("ic_launcher"))
                .setLargeIcon(BitmapFactory.decodeResource(ActivityUtils.getTopActivity().getResources(), ResourceUtils.getMipmapIdByName("ic_launcher")))
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .build();
        notificationManager.notify(notifyId++,notification);
    }

    public static Notification sendNotification(Context context,String title,String text,int priority){
        createNotificationChannel();
        Notification notification = new NotificationCompat.Builder(context,channel_id)
                .setContentTitle(title)
                .setContentText(text)
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(ResourceUtils.getMipmapIdByName("ic_launcher"))
                .setLargeIcon(BitmapFactory.decodeResource(ActivityUtils.getTopActivity().getResources(), ResourceUtils.getMipmapIdByName("ic_launcher")))
                .setPriority(priority)
                .build();
        notificationManager.notify(notifyId++,notification);
        return notification;
    }

    public static void sendNotification(String title, String text, int priority, PendingIntent pendingIntent){
        createNotificationChannel();
        Notification notification = new NotificationCompat.Builder(ActivityUtils.getTopActivity(),channel_id)
                .setContentTitle(title)
                .setContentText(text)
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(ResourceUtils.getMipmapIdByName("ic_launcher"))
                .setLargeIcon(BitmapFactory.decodeResource(ActivityUtils.getTopActivity().getResources(), ResourceUtils.getMipmapIdByName("ic_launcher")))
                .setPriority(priority)
                .setContentIntent(pendingIntent)
                .build();
        notificationManager.notify(notifyId++,notification);
    }
}

2. Services

Declare a service, and then start a thread in the service to connect MQ and send broadcast in MQ consumption events

//Send out a broadcast
String ALARM_ACTION_CODE = "OPEN_SERVICE";
Intent intent = new Intent(ALARM_ACTION_CODE);
//Adapt to the explicit declaration component above 8.0 (otherwise you can't send a broadcast)
if (DeviceUtils.getSDKVersionCode() > Build.VERSION_CODES.O) {
    intent.setComponent(new ComponentName(context, MyReceiver.class));
}
intent.putExtra("text", msg);
context.sendBroadcast(intent);

After that, it’s basically a test. Open the app and directly return to the desktop. After about 1 minute, the app can’t play voice

Using the above ideas, whether it is to lock the screen or return to the desktop (the test uses Android 11, Google’s official system), voice playback can be realized, but it has not been tried on mobile phones of other systems

The original on-site equipment is a Huawei tablet, and it is the product of Hongmeng system