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