Method for Android to detect whether Activity or Service is running

  • 2021-08-28 21:18:40
  • OfStack

Requirements: Suppose our APP has three pages AActivity, BActivity, CActivity, Our APP needs 1 to run directly in the foreground (special equipment). Require to implement a monitoring service, To monitor whether APP is running. If there are three pages that are not running, it means that APP has been hung up. Otherwise, it means that APP is running and not processed. After hanging up, we need to restart App to let it continue to process the running status, and expose one to stop the broadcast of monitoring service, so that when we want to stop monitoring service, we can send one broadcast.

Idea: Realize a dual-process monitoring service, write a timer Timer in the service to repeatedly detect whether it is running, and if not, restart APP directly.

1. Define a monitoring service


package com.anloq.nfcservice;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;

import com.anloq.MyApplication;
import com.anloq.activity.AdActivity;
import com.anloq.utils.DetectionASUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by xpf on 2017/6/3 :)
 *  Detection APP Page whether 1 Direct running , Start directly without running 
 */

public class MonitoringService extends Service {

 private final static String TAG = "MonitoringService";

 private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
   if ("kill_self".equals(intent.getAction())) {
    Log.e(TAG, "onReceive: Kill your own process! ");
    killMyselfPid(); //  Kill your own process 
   }
  }
 };

 private Timer timer = new Timer();
 private TimerTask task = new TimerTask() {
  @Override
  public void run() {
   checkIsAlive();
  }
 };

 /**
  *  Check if the application is alive 
  */
 private void checkIsAlive() {
  String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
    Locale.CHINA).format(new Date());
  Log.e(TAG, "CustodyService Run: " + format);

  boolean AIsRunning = CheckUtil.isClsRunning(
    MonitoringService.this, "com.xpf.monitor", "com.xpf.monitor.activity.AActivity");
  boolean BIsRunning = CheckUtil.isClsRunning(
    MonitoringService.this, "com.xpf.monitor", "com.xpf.monitor.activity.BActivity");
  boolean b = (AIsRunning || BIsRunning);
  boolean CIsRunning = CheckUtil.isClsRunning(
    MonitoringService.this, "com.xpf.monitor", "com.xpf.monitor.activity.CActivity");

  Log.e(TAG, "AIsRunning || BIsRunning is running:" + b + ",CIsRunning:" + CIsRunning);

  if (!CIsRunning) {
   if (!b) { // If the interface hangs up, start it directly AActivity
    Intent intent = new Intent();
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setClass(MonitoringService.this, AActivity.class);
    startActivity(intent);
   }
  }
 }


 @Override
 public void onCreate() {
  super.onCreate();
  Log.e(TAG, "onCreate:  Start the monitoring service ! ");
  IntentFilter intentFilter = new IntentFilter();
  intentFilter.addAction("kill_self");
  registerReceiver(broadcastReceiver, intentFilter);
  timer.schedule(task, 0, 10000);//  Set the time period for detection ( Milliseconds )
 }

 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
  return START_STICKY;
 }

 @Override
 public IBinder onBind(Intent arg0) {
  return null;
 }

 /**
  *  The process of killing itself 
  */
 private void killMyselfPid() {
  int pid = android.os.Process.myPid();
  String command = "kill -9 " + pid;
  Log.e(TAG, "killMyselfPid: " + command);
  stopService(new Intent(MonitoringService.this, MonitoringService.class));
  try {
   Runtime.getRuntime().exec(command);
   System.exit(0);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 @Override
 public void onDestroy() {
  super.onDestroy();
  unregisterReceiver(broadcastReceiver);
  if (task != null) {
   task.cancel();
  }
  if (timer != null) {
   timer.cancel();
  }
 }
}

2. Register dual-process Service


  <service
   android:name="com.xpf.monitor.MonitoringService"
   android:enabled="true"
   android:label="MonitoringService"
   android:process=":gray">
   <intent-filter>
    <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
   </intent-filter>
  </service>

3. Tool class CheckUtil for detecting whether it is alive


public class CheckUtil {
 // Detection service Is it running 
 public static boolean isServiceWorked(Context context, String serviceName) {
  ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
  ArrayList<ActivityManager.RunningServiceInfo> runningService = (ArrayList<ActivityManager.RunningServiceInfo>) myManager.getRunningServices(Integer.MAX_VALUE);
  for (int i = 0; i < runningService.size(); i++) {
   if (runningService.get(i).service.getClassName().toString().equals(serviceName)) {
    return true;
   }
  }
  return false;
 }

 // Detection activity Is there a restack top 
 public static boolean isForeground(Context context, String PackageName) {
  ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
  List<ActivityManager.RunningTaskInfo> task = myManager.getRunningTasks(1);
  ComponentName componentInfo = task.get(0).topActivity;
  if (componentInfo.getPackageName().equals(PackageName))
   return true;
  return false;
 }

 /**
  *  Judge a app Is the process running 
  *
  * @param context
  * @param appInfo
  * @return
  */
 public static boolean isRunningProcess(Context context, String appInfo) {
  ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
  List<ActivityManager.RunningAppProcessInfo> runningAppPs = myManager.getRunningAppProcesses();
  if (runningAppPs != null && runningAppPs.size() > 0) {
   if (runningAppPs.contains(appInfo)) {
    return true;
   }
  }
  return false;
 }

 /**
  *  Judge 1 A Activity Is it running 
  *
  * @param pkg  pkg Apply package name 
  * @param cls  cls Is the class name eg
  * @param context
  * @return
  */
 public static boolean isClsRunning(Context context, String pkg, String cls) {
  ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
  List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
  ActivityManager.RunningTaskInfo task = tasks.get(0);
  if (task != null) {
   return TextUtils.equals(task.topActivity.getPackageName(), pkg) &&
     TextUtils.equals(task.topActivity.getClassName(), cls);
  }
  return false;
 }
}

4. Start monitoring service in 4. MainActivity


 Intent intent = new Intent(MainActivity.this, MonitoringService.class);
 intent.setAction("android.intent.action.RESPOND_VIA_MESSAGE");
 startService(intent);

Step 5 Stop monitoring services

Just send a kill process broadcast, and the action value is as follows


 Intent intent = new Intent();
 intent.setAction("kill_self");
 sendOrderedBroadcast(intent, null);

Ok, that's all for today. . .


Related articles: