欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

android 定义新的开机广播

程序员文章站 2022-06-18 10:36:51
接着这篇 [CSDN博客_android 开机广播是在哪里发出的] ,(https://blog.csdn.net/weixin_44021334/article/details/107966966)找到了开机广播发出的地方,就可以添加一个自定义的开机广播了。自定义开机广播的目的,一是防止所有的应用都接收开机广播启动,消耗太多系统内存;二是开机广播较慢,在进入主页后大概 1 分钟后才收到。AN 9.0 ,在 frameworks/base/services/core/java/com/androi...

接着这篇 android 定义新的开机广播_weixin_44021334的博客-CSDN博客
https://blog.csdn.net/weixin_44021334/article/details/108170034

找到了开机广播发出的地方,就可以添加一个自定义的开机广播了。

自定义开机广播的目的,
一是去掉原生开机广播,防止所有的应用都接收原生开机广播启动,消耗太多系统内存;
二是开机广播较慢,在进入主页后大概 1 分钟后才收到。

AN 9.0 ,在 frameworks/base/services/core/java/com/android/server/am/UserController.java 中,
修改 finishUserUnlockedCompleted 函数,

private void finishUserUnlockedCompleted(UserState uss) {
        final int userId = uss.mHandle.getIdentifier();
        synchronized (mLock) {
            // Bail if we ended up with a stale user
            if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
        }
        UserInfo userInfo = getUserInfo(userId);
        if (userInfo == null) {
            return;
        }
        // Only keep marching forward if user is actually unlocked
        if (!StorageManager.isUserKeyUnlocked(userId)) return;

        // Remember that we logged in
        mInjector.getUserManager().onUserLoggedIn(userId);

        if (!userInfo.isInitialized()) {
            if (userId != UserHandle.USER_SYSTEM) {
                Slog.d(TAG, "Initializing user #" + userId);
                Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
                intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
                        | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
                mInjector.broadcastIntent(intent, null,
                        new IIntentReceiver.Stub() {
                            @Override
                            public void performReceive(Intent intent, int resultCode,
                                    String data, Bundle extras, boolean ordered,
                                    boolean sticky, int sendingUser) {
                                // Note: performReceive is called with mService lock held
                                mInjector.getUserManager().makeInitialized(userInfo.id);
                            }
                        }, 0, null, null, null, AppOpsManager.OP_NONE,
                        null, true, false, MY_PID, SYSTEM_UID, userId);
            }
        }

        Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);
        // Do not report secondary users, runtime restarts or first boot/upgrade
        if (userId == UserHandle.USER_SYSTEM
                && !mInjector.isRuntimeRestarted() && !mInjector.isFirstBootOrUpgrade()) {
            int uptimeSeconds = (int) (SystemClock.elapsedRealtime() / 1000);
            MetricsLogger.histogram(mInjector.getContext(), "framework_boot_completed",
                    uptimeSeconds);
        }
        
		// modify begin 
		Intent myIntent = new Intent("android.intent.action.MY_BOOT_COMPLETED");
		myIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
		myIntent.setPackage("com.test.mypackage");
		mInjector.getContext().sendBroadcast(myIntent);
		Slog.d(UserController.TAG, "send forground MY_BOOT_COMPLETED");
		// modify end
		
        final Intent bootIntent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
        bootIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
        bootIntent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT
                | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
        mInjector.broadcastIntent(bootIntent, null, new IIntentReceiver.Stub() {
                    @Override
                    public void performReceive(Intent intent, int resultCode, String data,
                            Bundle extras, boolean ordered, boolean sticky, int sendingUser)
                            throws RemoteException {
                        Slog.i(UserController.TAG, "Finished processing BOOT_COMPLETED for u" + userId);
                    }
                }, 0, null, null,
                new String[]{android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
                AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId);
    } 

具体的修改说明,

  1. 声明为前台广播,比后台广播快
    myIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
  2. 指定的应用可以接收。如果需要作为全局广播则去掉
    myIntent.setPackage(“com.test.mypackage”);

指定的应用既接收开机广播,也接收自定义的开机广播;
经过测试,自定义的开机广播比原生开机广播早1分钟左右。

本文地址:https://blog.csdn.net/weixin_44021334/article/details/108170034

相关标签: Android framework