车载Android应用开发与分析 - 初试 SystemUI Plugin

这篇具有很好参考价值的文章主要介绍了车载Android应用开发与分析 - 初试 SystemUI Plugin。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在前面的视频、文章中我们介绍完了整个车载Android应用开发所需要的基础知识:

  1. 【视频文稿】车载Android应用开发与分析 - 走进车载操作系统 - 掘金
  2. 【视频文稿】车载Android应用开发与分析 - AOSP的下载与编译 - 掘金
  3. 【视频文稿】车载Android应用开发与分析 - 开发系统应用 - 掘金
  4. 【视频文稿】车载Android应用开发与分析 - AIDL实践与封装(上) - 掘金
  5. 【视频文稿】车载Android应用开发与分析 - AIDL实践与封装(下) - 掘金

本期内容,我们介绍原生Android Automotive中车载应用的实现方式和它的原理。首先要介绍的就是车载应用开发中非常重要的一个系统应用,Android系统的UI - SystemUI

由于原生Android系统的SystemUI代码量很大、内容也非常庞杂,这里我会挑选出对车载SystemUI开发具有参考意义的模块进行介绍,大约会有4-5期的内容,主要分为以下几个模块:

  1. 车载Android应用开发与分析 - SystemUI 「功能」与「源码结构」分析 - 掘金
  2. 车载Android应用开发与分析 - 初试 SystemUI Plugin

SystemUI的源代码可能是所有Android原生应用中最复杂的一个,当我们需要定制SystemUI时,庞大的源码量会对的定制化开发带来巨大的潜在风险。所以目前车载SystemUI常见的做法就是,从原生SystemUI中移植少量必须的源码,然后从头定制一个源码、功能完全可控的SystemUI。

重新开发一个SystemUI就是唯一的选项吗?当然不是!Google官方早就注意到了这个问题,所以SystemUI中提供插件化的开发方式 - SystemUI Plugin。

本文源码地址:/frameworks/base/+/refs/heads/main/packages/SystemUI/plugin/ExamplePlugin/

本文源码环境基于Android 13

SystemUI Plugin

SystemUI plugin机制是一种让SystemUI的功能可以被动态替换或修改的方法,它可以让开发者快速创建和迭代SystemUI的原型,而尽可能少的修改SystemUI的主框架。

注意:使用Plugin并不能保证我们完全不需要修改SystemUI的主框架,毕竟需求永远是多变的。

Plugin Hooks

Plugin hooks是一些预定义的插件接口,它们可以让应用实现一些特定的功能,并通过Intent和注解来注册和声明插件的类型和版本。Plugin hooks有多种类型,例如OverlayPlugin, QSFactory, VolumeDialog等,每种类型都有一个对应的action和expected interface,用于标识插件的功能和要求。

Android 13中Plugin hooks预定义接口主要有以下几种:

  • BcSmartspaceDataPlugin:这个plugin可以让应用提供自定义的数据给锁屏界面上的智能空间(BcSmartspace),例如天气、日历、新闻等。
  • ClockProviderPlugin:这个plugin可以让应用提供自定义的时钟样式给锁屏界面和始终应用。
  • DozeServicePlugin:这个plugin可以让应用自定义Doze模式的行为,例如控制屏幕亮度、显示内容、传感器等。
  • FalsingPlugin:这个plugin可以让应用自定义对误触(Falsing)事件的检测和处理,例如判断用户是否真的想滑动通知栏或解锁屏幕等。
  • GlobalActions:这个plugin可以让应用自定义全局操作(GlobalActions)对话框的外观和行为,例如添加新的操作按钮或改变对话框样式。
  • GlobalActionsPanelPlugin:这个plugin可以让应用在全局操作对话框中添加一个可展开的面板,用于显示更多的操作选项或信息。
  • IntentButtonProvider:这个plugin可以让应用在锁屏界面上添加一个自定义的按钮,用于启动一个指定的Intent。
  • NavigationEdgeBackPlugin:这个plugin可以让应用自定义导航栏边缘返回(NavigationEdgeBack)手势的行为,例如改变触发区域或动画效果。
  • NotificationListenerController:这个plugin可以让应用控制通知监听器(NotificationListener)服务的连接和断开,以及获取通知事件和数据。
  • NotificationMenuRowPlugin:这个plugin可以让应用自定义通知菜单栏(NotificationMenuRow)的外观和行为,例如添加新的菜单项或改变菜单样式。
  • NotificationPersonExtractorPlugin:这个plugin可以让应用自定义从通知中提取人物信息(NotificationPersonExtractor)的逻辑,例如识别通知中包含的联系人或头像等。
  • OverlayPlugin:这个plugin可以让应用自定义覆盖在通知栏上方的视图(OverlayView),用于显示一些额外的内容或功能。
  • PluginFragment:这个plugin可以让应用在SystemUI中嵌入一个Fragment,用于显示一些自定义的界面或功能。
  • QSFactory:这个plugin可以让应用提供自定义的快速设置工厂(QSFactory),用于创建快速设置图块或面板。
  • SensorManagerPlugin:这个plugin可以让应用使用SensorManager服务来注册和取消注册传感器监听器,以及获取传感器事件和数据。
  • ToastPlugin:这个plugin可以让应用自定义Toast消息(Toast)的外观和行为,例如改变Toast位置或持续时间等。
  • ViewProvider:这个plugin可以让应用提供一个自定义的视图(View),用于替换SystemUI中某些组件或功能。
  • VolumeDialog:这个plugin可以让应用自定义音量调节对话框(VolumeDialog)的外观和行为,例如添加新的音量控制选项或改变音量条的样式。

Plugin 上手

创建一个AndroidStudio的SystemUI plugin项目,可以参考以下的步骤:

1)编译SystemUIPluginLib.jar

使用Plugin之前我们需要编译出SystemUIPluginLib.jar,在AOSP源码根目录执行下面的指令。

make SystemUIPluginLib

然后就可以在下面的目录中得到SystemUIPluginLib.jar

out/target/product/emulator_x86/obj/JAVA_LIBRARIES/SystemUIPluginLib_intermediates/javalib.jar

在AOSP的文档中建议使用 frameworks/base/packages/SystemUI/plugin/update_plugin_lib.sh 脚本编译 SystemUIPluginLib.jar,不过我编译时出现了环境配置问题。

2)配置系统签名

在build.gradle中配置系统签名。

android {
    ...
    signingConfigs {
        sign {
            storeFile file('system.keystore')
            storePassword '123456'
            keyAlias 'cardemo'
            keyPassword '123456'
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            signingConfig signingConfigs.sign
        }
        debug {
            minifyEnabled false
            signingConfig signingConfigs.sign
        }
    }
}

关于如何制作系统签名,请参考:车载Android应用开发与分析 - 开发系统应用 - 掘金

3)创建一个Plugin

在plugin项目中定义一个类,实现自Plugin中已经提供的各种插件,并使用Requires注解声明target和version字段,这些字段用于标识插件的类型和版本。

@Requires(target = OverlayPlugin.class, version = OverlayPlugin.VERSION)
public class SampleOverlayPlugin implements OverlayPlugin {
    private static final String TAG = "SampleOverlayPlugin";
    private Context mPluginContext;

    private View mStatusBarView;
    private View mNavBarView;

    @Override
    public void onCreate(Context sysuiContext, Context pluginContext) {
        Log.d(TAG, "onCreate");
        mPluginContext = pluginContext;
    }

    @Override
    public void onDestroy() {
        if (mInputSetup) {
            mStatusBarView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
                    onComputeInternalInsetsListener);
        }
        Log.d(TAG, "onDestroy");
        if (mStatusBarView != null) {
            mStatusBarView.post(() -> ((ViewGroup) mStatusBarView.getParent()).removeView(mStatusBarView));
        }
        if (mNavBarView != null) {
            mNavBarView.post(() -> ((ViewGroup) mNavBarView.getParent()).removeView(mNavBarView));
        }
    }

@Override
public void setup(View notificationShadeWindowView, View navBar) {
    Log.d(TAG, "Setup");
    if (notificationShadeWindowView instanceof ViewGroup) {
        mStatusBarView = LayoutInflater.from(mPluginContext)
                .inflate(R.layout.colored_overlay, (ViewGroup) notificationShadeWindowView, false);
        ((ViewGroup) notificationShadeWindowView).removeAllViews();
        ((ViewGroup) notificationShadeWindowView).addView(mStatusBarView);
    }
    if (navBar instanceof ViewGroup) {
        mNavBarView = LayoutInflater.from(mPluginContext)
                .inflate(R.layout.colored_overlay, (ViewGroup) navBar, false);
        ((ViewGroup) navBar).removeAllViews();
        ((ViewGroup) navBar).addView(mNavBarView);
    }
}
}

注意:Android不同版本中SystemUI的代码存在不小的差异,例如:Android13中setup(View statusBar, View navBar)中返回的statusBar实际上是NotificationShadeWindowView。

4)注册Plugin

在plugin项目的AndroidManifest中注册一个service,使用action和permission属性指定插件的接口和权限,这样SystemUI就可以通过Intent找到插件。

<uses-permission android:name="com.android.systemui.permission.PLUGIN" />

<application>

    <service
        android:name=".SampleOverlayPlugin"
        android:exported="false"
        android:label="@string/plugin_label"
        tools:ignore="Instantiatable">
        <intent-filter>
            <action android:name="com.android.systemui.action.PLUGIN_OVERLAY" />
        </intent-filter>
    </service>

</application>

的name可以在我们实现的plugin接口中找到。

android systemui plugin,Android车载应用分析,车载应用开发视频文案,android

SystemUI为了保证系统安全,对于plugin的加载,构筑了两道防线:

第一道防线是Build.IS_DEBUGGABLE检查。SysUI 在扫描或加载设备上的任何插件之前,会检查Build.IS_DEBUGGABLE,以确保构建是可调试的。

第二道防线是就是签名权限。所有插件都必须被系统签名且持有com.android.systemui.permission.PLUGIN权限才能加载其任何代码,否则将记录违规行为,并忽略插件。

5)运行Plugin

将plugin.apk push 到Android 13 模拟器的/system/priv-app/ 目录下,重启。可以看到如下的效果:

  1. NavBar的所有子View被移除,并添加了一个红色的View;
  2. NotificationShadeWindowView的所有子View被移除,并添加了一个红色的View。

android systemui plugin,Android车载应用分析,车载应用开发视频文案,android

总结

本文初试了SystemUI插件机制,在编写本文时发现Plugin相关的资料少的可怜,即使是官方资料有的也过时了。所以就像标题那样,本文只是简单尝试了Plugin,如何使用Plugin来详细定制一个完全符合我们需求的SystemUI呢?这个我们放到以后再写,因为接下来需要先来分析SystemUI Plugin的原理,在资料如此稀少的情况下,不了解原理几乎无法写出符合需求的Plugin。在分析的原理的过程中,我们会逐步补完、理解一些Plugin的概念。

以上就是本文的所有内容,感谢你的阅读,希望对你所有帮助。

参考资料

Sysui plugin

SystemUI Plugin 简介及使用

/SystemUI/docs/plugins.md文章来源地址https://www.toymoban.com/news/detail-785620.html

到了这里,关于车载Android应用开发与分析 - 初试 SystemUI Plugin的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AUTOSAR从入门到精通-【应用篇】基于Vector工具链车载总线自动化测试平台的研究与开发

    目录 车载总线发展现状 自动化测试平台的发展趋势 国内外研究现状

    2024年02月16日
    浏览(48)
  • Android 12 源码分析 —— 应用层 一(SystemUI准备篇)

    在接下来的时间中,将会使用Pixel 3(blueline)作为研究对象,选用AOSP的android-12.0.0_r34分支作源代码。 先从android的应用层进行探析,然后慢慢深入android的framework,接着进入android的hal层,最后以android的linux内核结束,期间可能会穿插一些其他文章如android的art虚拟机分析等。 本文

    2024年02月12日
    浏览(48)
  • Android 12 源码分析 —— 应用层 二(SystemUI大体组织和启动过程)

    在前一篇文章中,我们介绍了SystemUI怎么使用IDE进行编辑和调试。这是分析SystemUI的最基础,希望读者能尽量掌握。 本篇文章,将会介绍SystemUI的大概组织架构,以及它的启动过程。本篇文章读完,将会知道: SystemUI为什么选择使用Dagger2 SystemUI怎么新建一个模块 SystemUI的启动

    2024年02月06日
    浏览(81)
  • Android 12 源码分析 —— 应用层 四(SystemUI的基本布局设计及其基本概念)

    更新历史 日期 内容 1 2023-9-11 增加文中提及的渐变动画的效果图 在上两篇文章中,我们介绍SystemUI的启动过程,以及基本的组件依赖关系。基本的依赖关系请读者一定要掌握,因为后面的文章,将会时常出现这些依赖关系的使用,届时将会一笔带过,而不会详细说明他们的实

    2024年02月08日
    浏览(67)
  • Android应用开发(1)Android Studio开发环境搭建

    Android应用开发学习笔记——目录索引 本章介绍搭建Android Studio应用开发环境,创建并编译App工程,运行和调试App。 谷歌开发者网站可直接下载AndroidStudio,下载链接:https://developer.android.com/studio 点击【Download Android Studio Electric Eel】 勾选【I have read and agree with the above terms and

    2024年02月07日
    浏览(49)
  • Android应用开发(7)按键(Button)

    Android应用开发学习笔记——目录索引 本章介绍按钮(Button)控件的常见用法,结合前面Android应用开发(5)文本显示(TextView)介绍按钮(Button)监听点击和长按事件,禁用和启用等。 参考google官网:https://developer.android.com/reference/android/widget/Button 按钮控件Button由TextView派生

    2024年02月05日
    浏览(54)
  • Android移动应用开发的学习路线

    Android移动应用开发的学习路线。以下是一个基本的学习路线,供你参考: 1. Java基础 学习Java的基本语法和面向对象编程(OOP)的概念 了解Java的数据类型、变量和常量 学习控制结构(如条件语句、循环语句)和函数 2. Android基础 了解Android平台的基本概念和架构 学习Android的

    2024年02月11日
    浏览(53)
  • Android应用开发(4)视图布局基本属性

    Android应用开发学习笔记——目录索引 本章介绍视图(View)的基本概念及其用法,包括:如何设置视图的宽度和高度,如何设置视图的外部间距和内部间距,如何设置视图的外部对齐方式和内部对齐方式等。 在Android中,什么是视图(View)?View是Android中所有控件的基类,不

    2024年02月03日
    浏览(46)
  • 移动应用开发环境搭建Android Studio

    记得提前开启电脑虚拟化支持,具体方法可自行百度 查看是否启用虚拟化 JDK安装与卸载 由于Andriod开发使用的语言是javaKotlin,这里使用的是java语言所以需要先安装java的开发环境 所有开发 Android 应用程序需要的工具都是开源的,并且可以从互联网上下载 Android Studio 是谷歌推

    2023年04月08日
    浏览(71)
  • Android应用开发(6)TextView进阶用法

     Android应用开发学习笔记——目录索引 上一章Android应用开发(5)文本视图(TextView)介绍了文本视图(TextView)设置文本内容、设置文本大小、设置文本显示颜色。 TextView是最基础的文本显示控件,常用的基本属性和设置方法有: XML中的属性 TextView类的设置方法 说明 andro

    2024年02月14日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包