非常讨厌国内手机音乐播放器各种流氓行为,我只要听本地音乐,每次打开时要先强迫你看一屏广告,本地音乐入口还隐藏得特别深,一不小心就点到直播、联网音乐等界面去了,非常让人反感。想找个简单的本地音乐播放器,发现非常困难,要么功能欠缺,要么带广告。这东西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; }