非常讨厌国内手机音乐播放器各种流氓行为,我只要听本地音乐,每次打开时要先强迫你看一屏广告,本地音乐入口还隐藏得特别深,一不小心就点到直播、联网音乐等界面去了,非常让人反感。想找个简单的本地音乐播放器,发现非常困难,要么功能欠缺,要么带广告。这东西Android本来就自带的,可是国内各组装厂却都替换成了自己的,还要强制联网。某Q音乐本地版加载个歌曲列表竟然一卡一卡的,完全不像大厂出品。
找来找去,最后用上了开源的Shuttle,使用起来感觉还不错,但唯有两点让我很不爽:
部分中文歌曲名显示乱码
没有自动去除重复的歌曲,即使用上收费的Shuttle2也没解决这个问题
既然是开源的,索性自己动手解决。
由于本地没有纯安卓的开发环境,又不想为了搞这个破东西装一大堆软件(因为特别抵触Gradle这破东西,感觉Maven秒它N条街),于是GitHub Action就派上用场了。GitHub Action可以将项目编译,并自动生成可执行文件。
GitHub Action的价值:给没有安装编译环境的开发者来说真的是极大的便利,开发者可以把源码丢上GitHub,然后Action让它自动在后台编译,并自动部署。所谓的CI/CD原来跟这差不多。
如果项目主界面没有显示Action,需要注意以下几点:
项目需要公开
需要设置为默认项目(可能在yml里设置指定版本也行,没亲测)
在项目根目录.github/workflows/xx.yml,yml文件必须规范,并且指定了触发条件,xx可随意

name: Android CI
on: [push,pull_request]
jobs:
build:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- name: set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
distribution: 'temurin'
cache: gradle
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build
- name: Prepare App
run: |
mkdir -p ${{ github.workspace }}/apk/
for file in `find ~ -name "*.apk" -print`; do
mv "$file" ${{ github.workspace }}/apk/
done
- name: Upload App To Artifact
uses: actions/upload-artifact@v3
with:
name: com.abc.test.apk
path: ${{ github.workspace }}/apk/*GitHub启用后,首先让它编译一下fork过来的源码,发现各种报错。报错不可怕,毕竟5年前的代码,有些插件可能都没提供了。但是,一连串的环境问题,折腾得让人怀疑人生。
经过各种折腾,先后解决了:
Gradle版本问题
签名问题
SDK版本问题
Google的Firebase问题(其中Firebase又有新旧版本的区别)
好不容易把各种依赖和版本都对应上了,Action build成功,狂喜。
既然用上了GitHub Action,自然也不用本地装开发工具了,GitHub连VSCode都提供给你了,平时简单改改代码,用github.dev问题不大。但是,这次翻车了:
代码编辑器智能提示非常弱智,即使打错字也不会报错,即使用上了GitHub CodeSpace也一样
没有智能提示,加上对Kotlin又不熟悉,完全是盲人摸象的方式,效率非常低
没有调试功能,改完代码每次提交后Action编译还要5到8分钟,然后到手机上测试,输出日志到log.txt做分析,非常痛苦。。。
经历一次又一次的失败后,终于把这个开源的播放器改成自己想要的了,虽然不完美,但是也基本满足自己使用。
解决中文乱码问题:其实就是用displayName替换原来的name
去重功能:Kotlin里大量用到了JavaRX,其中有个DistinctBy(xx)可以按需过滤重复的歌曲
去除付费限制:Shuttle1.0源码中竟然还有付费的版本,我直接去掉了(一直以为作者2.0版本才要付费)
public static boolean isUpgraded(ShuttleApplication application, SettingsManager settingsManager) {
if(1==1)
return true;
// no updgrade at all!!
if (application.getIsUpgraded()) {
return true;
}
if (settingsManager.getIsLegacyUpgraded()) {
return true;
}
try {
return application.getPackageName().equals(Config.PACKAGE_NAME_PRO);
} catch (Exception ignored) {
}
//If something goes wrong, assume the user has the pro version
return true;
}