Android 12.0 系统开机自启动第三方app

1.前言


在12.0的系统rom定制化开发中,由于有些第三方app,需要在接收到开机广播后,启动app,但是在10.0以后第三方app就接收不到开机广播了
只有系统app才可以接收到开机广播了,所以在app内通过接收开机广播自启动就没法实现了 这就需要在系统中添加 监听Q 开机完成广播的功能,然后在接收到开机广播后启动第三方app就可以了

2.系统开机自启动第三方app的核心类

 frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

3.系统开机自启动第三方app的核心功能分析和实现

3.1 app中常用的接收开机广播的方法

          <receiver
            android:name=".receiver.StartSelfReceiver"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
            <intent-filter android:priority="1000">
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </receiver>
在app中使用的范例
  import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
 
import com.pne.kotlin.ReplaceIconActivity;
 
public class StartSelfReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Log.e("Receiver","action:"+action);
        //Android设备开机时会发送一条开机广播:"android.intent.action.BOOT_COMPLETED"
        if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
            Intent selfIntent = new Intent(context, ReplaceIconActivity.class);
            selfIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(selfIntent);
        }
    }
}

这种方式会收不到开机广播的,所以对于启动app也是做不到的,接下来就只能在framework中某个功能模块里面接收到开机广播后,启动某个app了

3.2 PhoneWindowManager.java中启动第三方app的功能实现

    /** {@inheritDoc} */
      @Override
      public void systemReady() {
          // In normal flow, systemReady is called before other system services are ready.
          // So it is better not to bind keyguard here.
          mKeyguardDelegate.onSystemReady();
  
          mVrManagerInternal = LocalServices.getService(VrManagerInternal.class);
          if (mVrManagerInternal != null) {
              mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener);
          }
  
          readCameraLensCoverState();
          updateUiMode();
          mDefaultDisplayRotation.updateOrientationListener();
          synchronized (mLock) {
              mSystemReady = true;
              mHandler.post(new Runnable() {
                  @Override
                  public void run() {
                      updateSettings();
                  }
              });
              // If this happens, for whatever reason, systemReady came later than systemBooted.
              // And keyguard should be already bound from systemBooted
              if (mSystemBooted) {
                  mKeyguardDelegate.onBootCompleted();
              }
          }
  		//add code start
        IntentFilter intentFilter = new IntentFilter("android.intent.action.BOOT_COMPLETED");
        mContext.registerReceiver(mWallpaperChangedReceiver, intentFilter);
		//add code end
          mAutofillManagerInternal = LocalServices.getService(AutofillManagerInternal.class);
          mGestureLauncherService = LocalServices.getService(GestureLauncherService.class);
 
      }
  
      /** {@inheritDoc} */
      @Override
      public void systemBooted() {
          bindKeyguard();
          synchronized (mLock) {
              mSystemBooted = true;
              if (mSystemReady) {
                  mKeyguardDelegate.onBootCompleted();
              }
          }
          mSideFpsEventHandler.onFingerprintSensorReady();
          startedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
          finishedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
  
          int defaultDisplayState = mDisplayManager.getDisplay(DEFAULT_DISPLAY).getState();
          boolean defaultDisplayOn = defaultDisplayState == Display.STATE_ON;
          boolean defaultScreenTurningOn = mDefaultDisplayPolicy.getScreenOnListener() != null;
          if (defaultDisplayOn || defaultScreenTurningOn) {
              // Now that system is booted, wait for keyguard and windows to be drawn before
              // updating the orientation listener, stopping the boot animation and enabling screen.
              screenTurningOn(DEFAULT_DISPLAY, mDefaultDisplayPolicy.getScreenOnListener());
              screenTurnedOn(DEFAULT_DISPLAY);
          } else {
              // We're not turning the screen on, so don't wait for keyguard to be drawn
              // to dismiss the boot animation and finish booting
              mBootAnimationDismissable = true;
              enableScreen(null, false /* report */);
          }
      }
 
// add core start
    BroadcastReceiver mWallpaperChangedReceiver  = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
                              String action = intent.getAction();
			if (action.equals("android.intent.action.BOOT_COMPLETED")) {
			  Slog.d("WindowManager", "android.intent.action.BOOT_COMPLETED");
           Intent selfIntent = new Intent(context, ReplaceIconActivity.class);
            selfIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(selfIntent);
			}
        }
    };
//add core end

在上述的PhoneWindowManager.java中相关源码可以看出,在系统相关服务启动完毕后,在调用 systemReady()执行PhoneWindowManager.java的相关功能中,可以添加相关的开机启动完成广播的监听,然后在广播中,收到开机完成广播以后,启动第三方app就实现了功能的需求

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值