Android11 SystemUI clock plugin 插件入门

插件的编写

参照ExamplePlugin,需要系统签名。

需要先编译以下模块得到jar,引用在项目中。

m SystemUIPluginLib

com.android.systemui.permission.PLUGIN

PluginManager.addPluginListener

SystemUI 是如何发现 clock plugin 的?

SystemUI发现插件的处理流程:

apk安装的广播处理中调用handleQueryPlugins,如果发现有插件,
则handleQueryPlugins调用的PluginInstanceManager的handleLoadPlugin 发送 PLUGIN_CONNECTED 信息 给 listener 比如 ClockManager,ClockManager 通过addOnClockChangedListener发送给KeyguardClockSwitch。

何时会加载插件?

用户解锁的时候
PluginManager.addPluginListener的时候

PluginManager 的功能

开始监听:

    private void startListening() {
        if (mListening) return;
        mListening = true;
        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        filter.addAction(PLUGIN_CHANGED);
        filter.addAction(DISABLE_PLUGIN);
        filter.addDataScheme("package");
        mContext.registerReceiver(this, filter);
        filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
        mContext.registerReceiver(this, filter);
    }

PluginInstanceManager 就是一个具体的插件的管理类,比如Clock,或者Left button。

如何创建一个PluginInstanceManager

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

加载plugin的关键代码:

PluginManagerImpl:

   /** Returns class loader specific for the given plugin. */
    public ClassLoader getClassLoader(ApplicationInfo appInfo) {
        if (!isDebuggable && !isPluginPackageWhitelisted(appInfo.packageName)) {
            Log.w(TAG, "Cannot get class loader for non-whitelisted plugin. Src:"
                    + appInfo.sourceDir + ", pkg: " + appInfo.packageName);
            return null;
        }
        if (mClassLoaders.containsKey(appInfo.packageName)) {
            return mClassLoaders.get(appInfo.packageName);
        }

        List<String> zipPaths = new ArrayList<>();
        List<String> libPaths = new ArrayList<>();
        LoadedApk.makePaths(null, true, appInfo, zipPaths, libPaths);
        ClassLoader classLoader = new PathClassLoader(
                TextUtils.join(File.pathSeparator, zipPaths),
                TextUtils.join(File.pathSeparator, libPaths),
                getParentClassLoader());
        mClassLoaders.put(appInfo.packageName, classLoader);
        return classLoader;
    }

有哪些插件?

在这里插入图片描述

开机时的QUERY_ALL是怎么发送的?

取决于具体的PluginInstanceManager实例

com.android.systemui.action.PLUGIN_LOCKSCREEN_LEFT_BUTTON

在这里插入图片描述

KeyguardAffordanceView ,左边是Phone,右边是Camera.

拖到的圆形动画的实现:

在这里插入图片描述

控制是否显示:

   <!-- Show mic or phone affordance on Keyguard -->
    <bool name="config_keyguardShowLeftAffordance">false</bool>

    <!-- Show camera affordance on Keyguard -->
    <bool name="config_keyguardShowCameraAffordance">false</bool>

LeftButton 的实现效果

在这里插入图片描述

为什么显示的是白色?原因如下:

 val  loading = this.resources.getDrawable(R.drawable.loading_quan,this.theme)
        loading.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
        binding.imageView.setImageDrawable(loading)

插件apk需要push到system/app下

scp andy@192.168.16.128:android11/out/target/product/Tinker_Board_2/system/app/Left/Left.apk  .
adb root
adb remount
adb shell rm  -r /system/app/Left/
adb shell  mkdir  /system/app/Left
adb  push  Left.apk  /system/app/Left/
adb reboot
pause
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值