Astra Launcher 给电视和带屏音箱做一个顺手的横屏桌面
现在不少电视和带屏设备的默认桌面越来越臃肿,广告、会员订阅和付费内容占据了显眼的位置,打开自己安装的应用反而要翻找一番。换成第三方桌面也未必能完全解决问题:一些方案闭源,想按自己的习惯定制并不容易;开源方案对遥控器方向键和触屏输入的支持又参差不齐,很难同时照顾好两种操作方式。
而在日常使用中,需要的也不只是一个应用启动器。传送和安装 APK、执行 Shell 命令、通过 Activity Launcher 一类工具打开应用内部入口,通常还得分别安装不同的 App。原本只是想把设备用得顺手一些,最后却要在一组工具之间来回切换。
笔者最初想给家里的小米电视和一台带屏天猫精灵做一个简单的桌面。电视上主要用遥控器,希望打开电视直播、Kodi 之类的应用时少翻几层菜单;音箱则是一块 1024×600 的横屏,运行 Android 8,主要靠触摸操作,而且没有常见的系统导航栏和返回键。
这两种设备看起来都是「横着放的一块 Android 屏幕」,实际用起来却很不一样。适合遥控器的菜单,放到触屏上可能能打开却不好退出;照着手机设计的界面,又未必适合坐在几米外用方向键操作。
Astra Launcher 就是从这些需求开始的:做一个面向 Android 8 及以上横屏设备的轻量桌面,同时兼顾触摸与遥控器,让常用应用、时间天气和几个系统入口都在容易找到的位置。局域网 APK 安装、Shell 和 Activity 浏览工具则收进设置页,需要时可以直接打开,不必再为每件小事单独找一个 App。

触摸和遥控器共用一套界面
开发过程中,一个很早就确定下来的原则,就是同时支持触摸和遥控器操作,而不要求用户在首次使用时选择模式。
Astra 直接根据实际输入处理交互:触摸时可以直接点击,按下方向键时进入焦点导航。界面根据可用空间调整网格,不根据品牌、型号或某个固定分辨率判断应该显示什么。
另一个重要细节是返回路径。应用列表、设置和工具页面都有明确的返回按钮,触屏设备不必借助遥控器才能离开;在主页上按返回键,也不会把桌面退出掉。
这里解决的是 Astra 自己的交互。打开另一个应用以后,那个应用是否适合触摸、有没有返回按钮,仍取决于它自己的设计。Astra 没有加入全局返回浮层,也不申请无障碍权限。
主页只放经常要用的东西
主页的内容比较简单:时钟、日期、地点与天气、常用应用,以及进入全部应用的按钮。没有推荐流,也不需要先经过内容频道才能找到已经安装的应用。
应用列表会同时查找普通 Android 应用和电视应用的启动入口。这样,设备上侧载的普通 APK 不会仅仅因为缺少电视专用入口就被排除在列表之外。常用应用可以加入收藏,其余应用留在抽屉中。
天气和背景图片都不阻塞主页显示。有缓存时先显示缓存,再在后台更新;网络暂时不可用,也不影响打开本地应用。
地点使用公网 IP 推测,不读取 GPS。因此它提供的是一个粗略城市位置:如果网络经过代理或 VPN,显示的可能是出口所在城市。天气优先使用 Open-Meteo,失败时尝试 wttr.in;地点查询也有备用来源。
背景图片按 Bing、Wikimedia Commons 每日图片、NASA APOD 的顺序尝试更新。新图片下载并校验成功后才替换旧图,所有来源都失败时继续使用最近缓存。没有缓存时显示渐变背景,不附带一套内置壁纸。数据和图片的来源、作者及许可说明集中放在设置页,主页不再堆这些文字。
右上角保留了几个纯图标入口:Wi-Fi、蓝牙、信号源、文件和 Astra 设置。它们主要负责把用户送到系统已经提供的功能,而不是重新实现一套网络设置或文件管理器。
例如,「文件」优先打开系统文件管理应用;没有合适入口时,再使用系统文档选择器。U 盘是否出现在其中,取决于系统是否向应用开放了相应存储位置。
信号源也遵循同样的思路:通过 Android TV Input Framework 获取系统报告的 HDMI、AV 等输入,再交给系统处理。它没有内置一张按小米型号匹配私有页面的表,因此也不能保证每台电视都能列出、切换所有信号源。
用浏览器把 APK 送到电视
这次新增的功能里,笔者最想介绍的是局域网安装 APK。
在电脑或手机上下载一个安装包很简单,麻烦的是把它送到电视。找 U 盘、复制文件、插到电视上,再找到文件管理器;或者打开电脑,连接 ADB 后执行安装。偶尔做一次没有问题,反复更新几个应用就有些繁琐。
Astra 的做法是在需要时临时开启一个接收页面。发送端不必再安装传输工具,只需要浏览器:
- 在电视上的 Astra 设置中进入「局域网安装 APK」,点击「开启接收」。
- 页面会显示局域网 HTTP 地址和六位配对码。
- 用同一局域网的手机或电脑打开这个地址,输入配对码,选择一个 APK 上传。
- 电视收到文件后会显示应用名称、包名、版本和大小,用户再点击安装。
- 首次使用时,按系统提示允许 Astra 安装未知应用,随后在系统安装界面确认。
这里有一个刻意保留的步骤:上传成功之后,安装仍需要在设备端确认。 Astra 只负责接收文件并交给系统安装器,不提供静默安装。
接收网页的资源内置在 App 中,安装包直接进入设备上的私有缓存,不需要通过云端中转。离开接收页或开启满 15 分钟后,接收服务会停止;已经完成的上传可以保留,方便从授权页面回来继续安装,也可以手动清除。
当前支持单个 APK,大小上限为 256 MiB,不解析 APKS、XAPK 等打包格式。手机和电视还必须能够在局域网内互相访问;如果连接的是开启设备隔离的访客 Wi-Fi,即使看起来接入了同一台路由器,也可能传不过去。
配对码用于限制上传,但并非传输加密。接收页面使用 HTTP,适合在可信的家庭局域网内临时开启,不应把端口映射到公网。
当然,这解决的是 Astra 已经装好之后 如何给设备继续安装应用。第一次安装 Astra 本身,仍然需要使用设备允许的侧载方式,例如 U 盘或 ADB。
把调试工具放进设置里
新版还加入了 Activity 浏览和 Shell 命令工具,不过它们都收在设置页,不占用日常主页。
Activity 可以粗略理解为 Android 应用中的一个界面入口。有些系统组件没有普通桌面图标,但内部可能提供可启动的设置页面。Activity 工具可以按应用浏览、搜索这些入口,查看组件名称、导出状态和权限要求,并把常用入口收藏到工具自己的列表中。
能列出来,并不意味着一定能打开。Astra 仍是普通应用,只能尝试启动已启用、允许外部访问且权限满足的 Activity;有些页面还需要额外参数,不能仅凭一个组件名就正常工作。
Shell 工具则适合执行少量非交互命令,查看输出、退出码和最近的命令记录。它运行在 Astra 自己的应用 UID 下,不是 ADB shell,更不是 root 终端。
这些功能让排查设备时少切换几个工具,但不改变 Astra 的权限身份。当前应用声明了网络访问、完整应用列表查询和请求安装 APK 的权限,没有申请定位、悬浮窗或无障碍权限。
更换接管系统桌面
对定制 Android 设备来说,桌面画得出来,和它能否稳定成为系统 HOME,是两件不同的事。
Astra 声明了标准的 HOME 入口,也提供普通应用和电视应用入口,可以先像普通 App 一样打开体验。但某些厂商固件有自己的首页选择、开机或待机恢复逻辑,安装第三方桌面可能也无法覆盖默认桌面首页。
因此,Astra Launcher 不负责禁用原厂桌面,不修改厂商服务,也不承诺安装后就接管开机和遥控器 Home 键。语音、闹钟、待机等系统功能仍由原系统负责,其兼容性需要按设备验证。
如何体验
项目使用 Kotlin 和传统 Android View/XML,最低支持 Android 8.0,也就是 API 26。界面固定横屏,普通手机模拟器也可以用来预览布局、触摸和方向键操作;电视信号源等能力则要看真机系统是否提供。
代码已放在 GitHub 仓库。可以用 Android Studio 打开项目,配置 Android SDK,并使用其自带的 JDK 21 构建:1
2
3git clone https://github.com/astra-sec/astra-launcher.git
cd astra-launcher
./gradlew testDebugUnitTest assembleDebug
生成的调试 APK 位于:1
app/build/outputs/apk/debug/app-debug.apk
安装前先确认设备允许侧载,并保留原厂桌面。天气、每日图片和安装界面的可用性会受到网络、固件及系统组件影响。
目前 Astra Launcher 仍是一个持续完善中的轻量桌面。对笔者来说,它最有用的地方,是把几个原本分散的日常动作放到了一起:看一眼时间和天气,打开常用应用,需要装新应用时,再从手机浏览器把 APK 传过去。电视和带屏音箱不一定需要更复杂的首页,但这些经常发生的小操作,值得做得顺手一些。