android自启动

    xiaoxiao2022-07-13  157

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

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

    先看效果图:

    注意:

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

    好了,到这里,程序的开机自启和退出自启动,都完成了,我们的程序后台服务5秒监听一下程序是否正在运行,如果不是,则重启程序,但是如果服务被杀死了,就没有更好的办法了,理论上,可以使用广播,启动服务,但是这个程序并没有做,以后有机会在补充。

     

     

    最新回复(0)