Android Framework之CarLauncher

460 阅读2分钟

CarLauncher

路径

/packages/apps/Car/Launcher

main文件

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.android.car.carlauncher">
​
    <!-- System permission to access the CarProjectionManager for projection status-->
    <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"/>
    <!-- Permission for the InCallController to bind the InCallService -->
    <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
    <!-- 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 permission to register TaskOrganizer -->
    <uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS"/>
    <!-- System permission to bring hosted maps activity to front on main display -->
    <uses-permission android:name="android.permission.REORDER_TASKS"/>
    <!-- System permission to remove a task -->
    <uses-permission android:name="android.permission.REMOVE_TASKS"/>
    <!-- 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"/>
    <!-- Permission to read contacts data. Needed to display contact name on dialer card -->
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <!-- Permission for read-only access to phone state, namely the status of any ongoing calls -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <queries>
        <intent>
            <action android:name="android.media.browse.MediaBrowserService" />
        </intent>
    </queries>
​
    <application
        android:icon="@drawable/ic_launcher_home"
        android:label="@string/app_title"
        android:theme="@style/Theme.Launcher"
        android:supportsRtl="true">
       <!--Launcher 页面  -->
        <activity
            android:name=".CarLauncher"
            android:configChanges="uiMode|mcc|mnc"
            android:launchMode="singleTask"
            android:clearTaskOnLaunch="true"
            android:stateNotNeeded="true"
            android:resumeWhilePausing="true"
            android:exported="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:launchMode="singleInstance"
            android:exported="true"
            android:theme="@style/Theme.Launcher.AppGridActivity">
            <meta-data android:name="distractionOptimized" android:value="true"/>
            <intent-filter>
                <action android:name="com.android.car.carlauncher.ACTION_APP_GRID"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>
        <!--电话服务 -->
        <service android:name=".homescreen.audio.telecom.InCallServiceImpl"
                 android:permission="android.permission.BIND_INCALL_SERVICE"
                 android:exported="true">
            <!-- The home app does not display the in-call UI. This is handled by the
            Dialer application.-->
            <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="false"/>
            <meta-data android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI" android:value="false"/>
            <intent-filter>
                <action android:name="android.telecom.InCallService"/>
            </intent-filter>
        </service>
    </application>
</manifest>

包结构

image.png

核心类

CarLauncher

启动见到的首页

car_launcher.xml
<?xml version="1.0" encoding="utf-8" ?>
<!--
  ~ Copyright (C) 2020 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:layoutDirection="ltr"
    tools:context=".CarLauncher">
​
  <!--> 天气区域</-->
    <com.android.car.ui.FocusArea
        android:id="@+id/top_card"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginRight="@dimen/main_screen_widget_margin"
        android:layoutDirection="locale"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/bottom_card"
        app:layout_constraintBottom_toTopOf="@+id/maps_card"/>
 <!--> 音乐交互区域</-->
    <com.android.car.ui.FocusArea
        android:id="@+id/bottom_card"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layoutDirection="locale"
        app:layout_constraintLeft_toRightOf="@+id/top_card"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/maps_card"/>
 <!--> 地图区域</-->
    <androidx.cardview.widget.CardView
        android:id="@+id/maps_card"
        style="@style/CardViewStyle"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="@dimen/main_screen_widget_margin"
        android:layoutDirection="locale"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/bottom_card"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

启动页

AppGridActivity

应用列表页

AppLauncherUtils

获取所有APP的方法在该类里

launcherApps.getActivityList //获取所有车载配置信息
LauncherActivityInfo
getComponentName()//获取app MainActivity信息
getLabel() //获取app的name
getBadgedIcon()//获取app图标
UsageStatsManager

设备使用情况和统计信息

getAppStandbyBucket()和queryEventsForSelf()// 不要权限 
  //其他方法都需要权限 android.permission.PACKAGE_USAGE_STATS

注意事项

签名类型 certificate

用于指定apk的签名方式,如果不指定,默认使用testkey签名

区别
  • testkey:普通APK,默认使用该签名。
  • platform:该APK完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的APK所在进程的UID为system。
  • shared:该APK需要和home/contacts进程共享数据。
  • media:该APK是media/download系统中的一环。

点击事件

xml中使用 android:onClick="xxx" 这种会失败,需要使用findViewById ,再添加点击事件的形式

<SurfaceView
    android:onClick="onclick"//这种方式编译不过去
    android:id="@+id/surface"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_constraintTop_toTopOf="parent" />