天天看点

android自启动

最近碰到一个需求,需要让app一直在前台运行,退出app,自动重启,关机再开机,自动启动程序的

然后写了一个程序,完美实现了这个功能

先看效果图:

android自启动

注意:

1.我测试的手机是荣耀畅玩5c 系统是android6.0

2.去手机安全中心,开启软件自启动权限

3.android6.0以上需要做运行时权限,我这里是手动开启的存储权限,代码里没做这个,导致第一次开机自启失败,

开始吧

1.清单文件:申请权限,注册服务,activity,和广播

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.admin.ztest">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.GET_TASKS" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.example.admin.ztest.TwoActivity" />

        <service android:name="com.example.admin.ztest.MonitoringService" />
        <receiver
            android:name=".BootReceiver"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    </application>

</manifest>           

2.主界面开启监听服务:

public class MainActivity extends AppCompatActivity{
    private Button btn_save, btn_get, btn_clear, btn_all, btn_show, btn_hide;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first);

        startService(new Intent(MainActivity.this, MonitoringService.class));
    }
}
           

3.广播:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * Created by wrs on 2019/5/23,18:23
 * projectName: Ztest5
 * packageName: com.example.admin.ztest
 */
public class BootReceiver extends BroadcastReceiver {
    //这个广播应该与清单文件的保持一致
    final String ACTION = "android.intent.action.BOOT_COMPLETED";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(ACTION)) {
            //这个MainActivity是开机启动的界面 也可以写成当前项目的其他activity
            Intent mainActivityIntent = new Intent(context, MainActivity.class);
            //这个很重要,是开机自启动的广播 别写错了
            mainActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(mainActivityIntent);
        }
    }
}
           

4.服务,监听程序,是否正在运行,当你按系统的back键时,程序会自己启动,但是按home键或者在菜单栏关闭程序时,程序无法自己启动,按下home的时候,回到桌面,程序依然在运行,可以在这个地方让它强行打开界面

package com.example.admin.ztest;


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



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

/**
 * Created by xpf on 2017/6/3 :)
 * 检测APP页面是否一直运行,不运行就直接启动
 */

public class MonitoringService extends Service {

    private final static String TAG = "MonitoringService";
    public static final String CANCEL_MONITOR = "cancelMonitor";

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (CANCEL_MONITOR.equals(intent.getAction())) {
                Log.e(TAG, "onReceive:kill app process!");
                killMyselfPid(); // 杀死自己的进程
            }
        }
    };

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

    /**
     * 检测应用是否活着
     */
    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 = MonitorUtil.isClsRunning(
//                MonitoringService.this, "com.thirtydays.caruav", "com.thirtydays.caruav.");
//        boolean BIsRunning = MonitorUtil.isClsRunning(
//                MonitoringService.this, "com.xpf.monitor", "com.xpf.monitor.activity.BActivity");
//        boolean b = (AIsRunning || BIsRunning);
//        boolean CIsRunning = MonitorUtil.isClsRunning(
//                MonitoringService.this, "com.xpf.monitor", "com.xpf.monitor.activity.CActivity");
//
//        Log.e(TAG, "AIsRunning || BIsRunning is running:" + b + ",CIsRunning:" + CIsRunning);

        String pName = getApplicationContext().getPackageName();
        int uid = getPackageUid(getApplicationContext(), pName);
        if (uid > 0) {
            boolean rstA = isAppRunning(getApplicationContext(), pName);
            boolean rstB = isProcessRunning(getApplicationContext(), uid);
            Log.e(TAG, "rstA:" + rstA + ", rstB:" + rstB);
            if (rstA) {
                //指定包名的程序正在运行中
                Log.d(TAG, "App is running...");
            } else {
                //指定包名的程序未在运行中
                Intent intent = new Intent();
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setClass(MonitoringService.this, MainActivity.class);
                startActivity(intent);
            }
        } else {
            //应用未安装
            Log.e(TAG, "App is not installed.");
        }

    }


    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "onCreate: Start monitor! ");
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(CANCEL_MONITOR);
        registerReceiver(broadcastReceiver, intentFilter);  //这个
        timer.schedule(task, 0, 5000);// 设置检测的时间周期(毫秒数)
    }

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

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

    /**
     * 杀死自身的进程
     */
    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();
        }
    }

    /**
     * 方法描述:判断某一应用是否正在运行
     * Created by cafeting on 2017/2/4.
     *
     * @param context     上下文
     * @param packageName 应用的包名
     * @return true 表示正在运行,false 表示没有运行
     */
    public static boolean isAppRunning(Context context, String packageName) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(100);
        if (list.size() <= 0) {
            return false;
        }
        for (ActivityManager.RunningTaskInfo info : list) {
            if (info.baseActivity.getPackageName().equals(packageName)) {
                return true;
            }
        }
        return false;
    }

    //获取已安装应用的 uid,-1 表示未安装此应用或程序异常
    public static int getPackageUid(Context context, String packageName) {
        try {
            ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
            if (applicationInfo != null) {
                Log.d(TAG, "app uid:" + applicationInfo.uid);
                return applicationInfo.uid;
            }
        } catch (Exception e) {
            return -1;
        }
        return -1;
    }

    /**
     * 判断某一 uid 的程序是否有正在运行的进程,即是否存活
     * Created by cafeting on 2017/2/4.
     *
     * @param context 上下文
     * @param uid     已安装应用的 uid
     * @return true 表示正在运行,false 表示没有运行
     */
    public static boolean isProcessRunning(Context context, int uid) {
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> runningServiceInfos = am.getRunningServices(200);
        if (runningServiceInfos.size() > 0) {
            for (ActivityManager.RunningServiceInfo appProcess : runningServiceInfos) {
                if (uid == appProcess.uid) {
                    return true;
                }
            }
        }
        return false;
    }
}