Android16定制SearchLauncher新增投屏Cast桌面快捷图标完整实现

一、前言

在Android16车载定制项目中,产品需求:在应用列表新增独立投屏快捷图标,点击直达系统投屏设置;若系统裁剪投屏模块,自动降级跳转到WiFi/蓝牙无线设置。 本次通过新增中转Activity+注册桌面入口的轻量方案实现,改动仅5个文件,无侵入原有桌面逻辑,兼容原生AOSP、精简车载固件。

二、Patch整体变更清单

  1. 新增矢量图标:ic_cast.xml(未连接投屏)、ic_cast_connected.xml(投屏已连接)
  2. 新增中转页面:CastShortcutActivity.java(无UI,仅做跳转分发)
  3. 修改AndroidManifest.xml:注册LAUNCHER桌面图标入口
  4. 修改strings.xml:增加多语言投屏名称文本

变更文件列表:vendor/partner_gms/

复制代码
apps/SearchLauncher/AndroidManifest.xml
apps/SearchLauncher/quickstep/res/drawable/ic_cast.xml(新建)
apps/SearchLauncher/quickstep/res/drawable/ic_cast_connected.xml(新建)
apps/SearchLauncher/quickstep/src/com/android/searchlauncher/CastShortcutActivity.java(新建)
apps/SearchLauncher/res/values/strings.xml

三、分文件完整修改逻辑

3.1 res/values/strings.xml:新增图标显示文字

修改逻辑

单独定义投屏名称字符串资源,统一管理、支持多语言包翻译,不硬编码文字。

修改片段
复制代码
<!-- 原有内容省略 -->
    <!-- Cast shortcut icon label
         投屏快捷方式图标下方展示文字,Launcher读取label字段渲染 -->
    <string name="cast_app_name">Cast</string>

3.2 新增矢量图标 ic_cast.xml(默认未投屏状态)

修改逻辑

遵循Android 24dp标准系统图标规范,矢量图适配所有分辨率;黑色图标作为桌面默认展示图标,预留连接状态图标用于后续动态切换。

复制代码
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017 The Android Open Source Project
开源协议声明,AOSP所有资源必须携带版权头
Licensed under the Apache License, Version 2.0
-->
<!-- vector矢量图标根标签,适配dp缩放,无像素模糊 -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"        <!-- 图标标准宽24dp,系统快捷图标统一尺寸 -->
    android:height="24dp"       <!-- 图标标准高24dp -->
    android:viewportWidth="24.0"  <!-- 矢量画布逻辑宽度 -->
    android:viewportHeight="24.0"><!-- 矢量画布逻辑高度 -->

    <!-- 投屏图形路径,黑色填充,未连接投屏默认样式 -->
    <path
        android:fillColor="#FF000000"
        android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v3h2L3,5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM1,18v3h3c0,-1.66 -1.34,-3 -3,-3zM1,14v2c2.76,0 5,2.24 5,5h2c0,-3.87 -3.13,-7 -7,-7zM1,10v2c4.97,0 9,4.03 9,9h2c0,-6.08 -4.93,-11 -11,-11z" />
</vector>

3.3 新增矢量图标 ic_cast_connected.xml(投屏连接状态)

修改逻辑

图形轮廓和默认图标完全一致,仅修改填充色为白色;预留资源,后续可监听投屏连接状态动态替换图标,本次Patch暂未做状态切换逻辑。

复制代码
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017 The Android Open Source Project
Apache开源版权声明
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"        <!-- 图标尺寸和默认图标保持统一 -->
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">

    <!-- 投屏连接成功白色样式,填充色引用系统白色 -->
    <path
        android:fillColor="@android:color/white"
        android:pathData="M19,7H5v1.63c3.96,1.28 7.09,4.41 8.37,8.37H19V7zM1,14v2c2.76,0 5,2.24 5,5h2C8,17.13 4.87,14 1,14zM1,10v2c4.97,0 9,4.03 9,9h2C12,14.92 7.07,10 1,10zM21,3H3C1.9,3 1,3.9 1,5v3h2V5h18v14h-7v2h7c1.1,0 2,-0.9 2,-2V5C23,3.9 22.1,3 21,3" />
</vector>

3.4 核心中转页面 CastShortcutActivity.java(新增文件)

修改逻辑
  1. 无布局、无界面,仅作为中转跳板;
  2. 跳转逻辑对齐SystemUI下拉状态栏投屏Tile长按行为,统一产品交互;
  3. 增加异常捕获,兼容裁剪固件(无Cast设置页面),自动降级无线设置;
  4. 跳转后立即finish,不占用Activity返回栈,无残留页面。
CastShortcutActivity 完整源码
复制代码
/*
 * Copyright (C) 2024 The Android Open Source Project
 * AOSP标准开源版权头
 * Licensed under the Apache License, Version 2.0
 */
package com.android.searchlauncher;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;

/**
 * 投屏快捷方式中转Activity
 * 功能:桌面点击Cast图标后,跳转系统投屏设置
 * 对齐SystemUI QS面板投屏Tile长按交互逻辑
 * 无任何UI界面,透明中转,跳转后自动销毁自身
 */
public class CastShortcutActivity extends Activity {

    /**
     * Activity生命周期入口,所有跳转逻辑写在此处
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 1. 优先跳转系统原生投屏设置页面
        // Settings.ACTION_CAST_SETTINGS 系统标准投屏设置Action
        Intent castIntent = new Intent(Settings.ACTION_CAST_SETTINGS);
        // FLAG_ACTIVITY_NEW_TASK:新开任务栈,不依附当前桌面栈
        // FLAG_ACTIVITY_CLEAR_TOP:清空目标页面之上所有页面,简化返回栈
        castIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

        try {
            // 尝试启动投屏设置
            startActivity(castIntent);
        } catch (Exception e) {
            // 异常捕获场景:固件裁剪投屏模块、无投屏硬件、GMS缺失
            // 降级方案:跳转到无线设置(WiFi/蓝牙,间接满足投屏需求)
            Intent fallbackWifiIntent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
            fallbackWifiIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(fallbackWifiIntent);
        }

        // 跳转完成,立即销毁当前中转Activity
        // 用户返回时直接回到桌面,不会出现空白中转页面
        finish();
    }
}

3.5 AndroidManifest.xml 注册桌面快捷入口(关键修改)

修改逻辑

通过MAIN + LAUNCHER标准intent-filter,告知系统在应用列表生成独立图标; 配置透明无标题主题,隐藏空白中转页面; exported=true允许Launcher组件读取该图标信息。

修改片段
复制代码
        <!-- 原有Activity省略 -->

        <!-- Cast Shortcut Activity
             投屏快捷方式注册配置,桌面图标生成核心配置
         -->
        <activity
            <!-- 对应我们新建的中转Activity完整类名 -->
            android:name="com.android.searchlauncher.CastShortcutActivity"
            <!-- 图标下方展示文字,引用strings资源 -->
            android:label="@string/cast_app_name"
            <!-- 桌面展示图标,使用默认未连接投屏矢量图 -->
            android:icon="@drawable/ic_cast"
            <!-- 允许外部组件(Launcher)访问此页面,必须配置true -->
            android:exported="true"
            <!-- 透明无标题主题,中转页面不需要显示任何UI,避免黑屏弹窗 -->
            android:theme="@android:style/Theme.Translucent.NoTitleBar">
            <!-- LAUNCHER过滤器:系统识别此Activity为桌面可展示应用图标 -->
            <intent-filter>
                <!-- 应用启动标准Action -->
                <action android:name="android.intent.action.MAIN" />
                <!-- 标记需要在Launcher应用列表展示图标 -->
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

四、完整业务执行流程(时序拆解)

  1. 系统编译打包,解析SearchLauncher的AndroidManifest;
  2. 识别携带MAIN+LAUNCHER过滤器的CastShortcutActivity;
  3. Launcher桌面加载全部应用,列表自动渲染:图标ic_cast、文字Cast;
  4. 用户点击桌面Cast图标,系统启动透明中转Activity;
  5. Activity onCreate执行跳转逻辑:
    • 存在投屏模块:打开投屏设置页面;
    • 固件裁剪投屏:捕获异常,跳转无线设置;
  6. 中转页面执行finish()销毁;
  7. 用户返回按键直接回到桌面,无空白中转页残留。

将图标添加到桌面Hotseat-101中

五、方案优缺点分析

优势

  1. 轻量化低侵入:仅新增中转页面,不修改原有Launcher桌面、Quickstep逻辑,无回归风险;
  2. 交互统一:跳转逻辑复用系统原生Action,和下拉状态栏投屏按钮行为完全一致;
  3. 高兼容适配:异常降级逻辑兼容无GMS、无投屏硬件、精简车载固件;
  4. 资源解耦:图标、文字、跳转逻辑分层,后续修改仅改动对应文件;
  5. 无权限额外申请:跳转系统设置属于普通应用权限,不需要platform签名、priv-app特权。

待扩展优化点(可二次开发)

  1. 增加投屏状态监听(MediaRouter),动态切换ic_cast/ic_cast_connected图标;
  2. 增加权限预校验,无WiFi权限时弹出提示弹窗;
  3. 支持桌面长按快捷菜单;
  4. 补充多语言strings翻译包;
  5. 支持分屏、车载副屏适配。
相关推荐
米码收割机2 小时前
【项目】spring boot+vue3 宠物领养系统(源码+文档)【独一无二】
java·spring boot·宠物
刹那芳华19923 小时前
STMF+ESP-S+MQTT协议连接华为云端(附踩坑记录)
java·struts·华为
就改了8 小时前
Java8 日期处理(详细版)
java·python·算法
IT小盘10 小时前
12-Prompt不等于一句话-System-User-Context三层结构
java·windows·prompt
都叫我大帅哥11 小时前
Spring Data JPA 查询之道:方法命名与示例查询完全指南
java·后端·spring
momo12 小时前
Java+WebAI黑马知识点
java·spring boot·mybatis
重庆小透明13 小时前
带你从不同视角了解三大MQ
java·学习·spring·kafka·rabbitmq·rocketmq
冰心孤城13 小时前
C++ 与 C#混合编程 示例 (基于VS)
java·c++·c#
风中芦苇啊15 小时前
Java EasyExcel 导入通用工具类:自定义注解映射字段 + 反射机制
java·开发语言