Android车载应⽤开发与分析(5)-CarLauncher(⼀)
在之前的中了解了如何下载以及编译⾯向车载IVI的Android系统,⼀切顺利的话,运⾏模拟器,等待启动动画播放完毕后,我们所能看到的第⼀个APP就是车载android的桌⾯,⽽这就是本篇⽂章的重点 - CarLauncher。
本篇⽂章中的功能以及源码分析基于android-11.0.0_r43,CarLauncher源码位于 packages/apps/Car/Launcher
Launcher 与 CarLauncher
Launcher是安卓系统中的桌⾯启动器,安卓系统的桌⾯UI统称为Launcher。Launcher是安卓系统中的主要程序组件之⼀,安卓系统中如果没有Launcher就⽆法启动,Launcher出错的时候,安卓系统会出现“进程 com.android.launcher 意外停⽌”的提⽰窗⼝。这时需要重新启动Launcher。
来⾃《百度百科 - launcher》
Launcher是android系统的桌⾯,是⽤户接触到的第⼀个带有界⾯的APP。它本质上就是⼀个系统级APP,和普通的APP⼀样,它界⾯也是在Activity上绘制出来的。
安卓intent用法虽然Launcher也是⼀个APP,但是它涉及到的技术点却⽐⼀般的APP要多。CarLauncher作为IVI系统的桌⾯,需要显⽰系统中所有⽤户可⽤app的⼊⼝,显⽰最近⽤户使⽤的APP,同时还需要⽀持在桌⾯上动态显⽰如地图、⾳乐在内各个APP内部的信息,在桌⾯显⽰地图并与之进⾏简单的交互。地图开发的⼯作量极⼤,Launcher显然不可能引⼊地图的SDK再开发⼀个地图应⽤,那么如何在不扩⼤⼯作量的前提下动态的显⽰地图就成了CarLauncher的⼀个技术难点(该内容涉及的知识点多且杂,还没整理好=_=||就放到之后再介绍吧)。
CarLauncher 功能分析
原⽣的Carlaunher代码并不复杂,主要是协同SystemUI完成以下两个功能。
显⽰ 可以快捷操作的 『⾸页』
显⽰ 所有APP⼊⼝的 『桌⾯』
需要注意的是,只有红框中的内容才属于CarLauncher的内容,红框之外的属于SystemUI的内容。虽然SystemUI在下⽅的NaviBar有6个按钮,但是只有点击⾸页和App桌⾯才会进⼊CarLauncher,点击其它按钮都会进⼊其它APP,所以都不在本篇⽂章的分析范围。
CarLauncher 源码分析
CarLauncher的源码结构如下:
Android.dp
CarLauncher的android.bp相对⽐较简单,定义了CarLauncher的源码结构,和依赖的类库。如果你对android.bp完全不了解,可以先看⼀下 学习⼀下基础的语法,再来回过头来看CarLauncher的android.bp相信会容易理解很多。
android_app {
name: "CarLauncher",
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
// 允许使⽤系统的hide api
platform_apis: true,
required: ["privapp_whitelist_com.android.car.carlauncher"],
// 签名类型: platform
certificate: "platform",
// 设定apk安装路径为priv-app
privileged: true,
// 覆盖其它类型的Launcher
overrides: [
"Launcher2",
"Launcher3",
"Launcher3QuickStep",
],
optimize: {
enabled: false,
},
dex_preopt: {
enabled: false,
},
// 引⼊静态库
static_libs: [
"androidx-constraintlayout_constraintlayout-solver",
"androidx-constraintlayout_constraintlayout",
"androidx.lifecycle_lifecycle-extensions",
"car-media-common",
"car-ui-lib",
]
,
libs: ["android.car"],
product_variables: {
pdk: {
enabled: false,
},
},
}
上述Android.bp中我们需要注意⼀个属性overrides,它表⽰覆盖的意思。在系统编译时Launcher2、Launcher3和Launcher3QuickStep都会被CarLauncher取代,前⾯三个Launcher是⼿机系统的桌⾯,车载系统中会⽤CarLauncher这个定制新的桌⾯取代掉⼿机系统桌⾯。同样的,如果我们不想使⽤系统中⾃带的CarLauncher,那么也需要在overrides中覆盖掉CarLauncher。在⾃主开发的车载Android
系统中这个属性我们会经常⽤到,⽤我们⾃⼰定制的各种APP来取代系统中默认的APP,⽐如系统设置等等。
Manifest⽂件中我们可以看到CarLauncher所需要的权限,以及⼊⼝Activity。
<manifest xmlns:android="schemas.android/apk/res/android"
package="com.android.car.carlauncher">
<uses-permission android:name="android.car.permission.ACCESS_CAR_PROJECTION_STATUS" /> <!-- System permission to host maps activity -->
<uses-permission android:name="android.permission.ACTIVITY_EMBEDDING" />
<!-- System permission to send events to hosted maps activity -->
<uses-permission android:name="android.permission.INJECT_EVENTS" />
<!-- System permission to use internal system windows -->
<uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
<!-- System permissions to bring hosted maps activity to front on main display -->
<uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
<!-- System permission to query users on device -->
<uses-permission android:name="android.permission.MANAGE_USERS" />
<!-- System permission to control media playback of the active session -->
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
<!-- System permission to get app usage data -->
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<!-- System permission to query all installed packages -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.REORDER_TASKS" />
<!-- To connect to media browser services in other apps, media browser clients
that target Android 11 need to add the following in their manifest -->
<queries>
<intent>
<action android:name="dia.browse.MediaBrowserService" />
</intent>
</queries>
<application
android:icon="@drawable/ic_launcher_home"
android:label="@string/app_title"
android:supportsRtl="true"
android:theme="@style/Theme.Launcher">
<activity
android:name=".CarLauncher"
android:clearTaskOnLaunch="true"
android:configChanges="uiMode|mcc|mnc"
android:launchMode="singleTask"
android:resumeWhilePausing="true"
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan">
<meta-data
android:name="distractionOptimized"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".AppGridActivity"
android:exported="true"
android:launchMode="singleInstance"
android:theme="@style/Theme.Launcher.AppGridActivity">
<meta-data
android:name="distractionOptimized"
android:value="true" />
</activity>
</application>
</manifest>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论