Google Play上架小结
前言
最近我负责的APP终于上架Google成功了,终于有时间来做一次完整的上架小结了!有些内容是之前写的,现在聚合一下,希望对读者有帮助!
注册Google开发者账号
Google账号我是QQ邮箱注册的,现在不知道行不行了,Google开发者账号是还要花25美金的,需要准备一张visa的卡,我用的之前公司的商务卡,弄成功了。进入下面页面,按着要求填就行,没有必要造假,后面还要身份证信息,感觉有点坑,还是弄了。
这些网上也很多教程,我就不多写了。
打包AAB包
打包可以用Android Studio内部生成bundle来生成AAB包,也可以使用命令,在根目录执行命令:
./gradlew bundle
# AAB位置:
# platforms/android/app/build/outputs/bundle/release
AAB包自测
这里要下个解包工具,地址如下:
使用方法:
生成json文件:java -jar bundletool-all-1.8.0.jar get-device-spec --output=./device-spec.json
生成apks文件:java -jar bundletool-all-1.13.1.jar build-apks --bundle=./android.aab --output=./android.apks --overwrite --ks=xxx --ks-pass=pass:xxx --ks-key-alias=xxx --key-pass=pass:xxx --device-spec=./device-spec.json
安装apks文件:java -jar bundletool-all-1.13.1.jar install-apks --apks=./android.apks
ps. 这里要先连上手机,生成的json文件是连上的这个手机的一些信息,然后根据手机信息生成的apks,最后安装到手机上。
密钥的配置自己改一下,注意下jar包的版本号,apks里面实际就是有好多个apk。
Google上架
有了开发者账号,创建一个应用,点进去管理,在信息中心里面第二步会让设置应用,按那个列表设置就行了。有问题随便搜下也能解决。
上传AAB包
在发布测试版本里面可以提交AAB包,这里卡了我挺久,大致就是下面几个问题。
AAB包过大
这里Google要求AAB包大小是150M,但是并不是AAB包的大小,看了下网上说的应该是把包解压出来里面base文件的大小,这个不超过150就行了(我这里就是包比150大,里面没超过150,通过了)。要是包大了,处理下,很奇怪的是我配置的gradle分包,对于AAB不生效,打包APK的时候倒是可以。
ps. 后面发现好像是分发出去的包不能大于150M,也就是根据特定手机型号生成的安装包。具体可以看Google的文档(需要魔法):
android {
splits {
abi {
enable true
reset()
include 'armeabi-v7a', 'arm64-v8a' //select ABIs to build APKs for
universalApk false //generate an additional APK that contains all the ABIs
}
}
}
密钥强度太低
大小限制没问题,我这上传发现提示了下面问题:
您的 android app bundle 所使用的上传证书的密钥强度太低。
直接网上搜解决办法,有的说密钥位数太低的,有的说没签名的,最后我发现我的问题就是密钥强度太低,重新生成一个密钥,密码加上字母、数字、符号、大小写,再上传就可以了。
这里还有人推荐了一个签名的工具,我也附带提一下,可能有的人是这里的问题:
# 下载fair-guard工具:https://www.fair-guard.com/help/list-228.html
# 修改config.ini配置,配置好密钥,上面工具里有文档
java -jar FairGuard3.6.3.jar -optype_sign_jar -inputfile ./android.aab
ps. 说到密钥这里提一下,参加了那什么计划,向Google上传的aab用自己的密钥,然后Google分发出去的apks会用另一个密钥。
上传密钥不要丢了,下次上传会校验是否还是那个上传密钥。
targetSdkVersion太低
改好了再上传,提示targetSdkVersion太低了,发现是Cordova在config.xml里面写了targetSdkVersion,虽然在gradle里面我已经改了,Cordova写到了manifest里面,还是被检查出来了,改了config.xml再打包就行了。现在Google要求至少31,有点高了,估计还得适配下。
没有“android:exported”属性设置
果然设置targetSdkVersion为31后,出了适配问题:
# 您上传的 APK 或 Android App Bundle 内含活动、活动别名、服务或广播接收器,这些项目有 intent 过滤器,但没有“android:exported”属性设置。
# 此文件无法在 Android 12 或更高版本上安装。详情请参阅:developer.android.com/about/versions/12/behavior-changes-12#exported
这个说起来好解决,但是也有几点要注意:
-
首先对manifest里带intent-filter的组件增加exported属性,各个module都要检查一遍。也可以直接分析aab包的manifest查看缺失的,通过Android Studio的工具Build -> analyze apk,看看aab里面的manifest,哪个缺了再回到源码里面改,这样不容易漏。
-
还有个问题就是第三方SDK的manifest,aab里面的manifest缺失了exported属性,我们外面改不到SDK manifest,这里可以在主工程的manifest复写一份,覆盖了就行,最后manifest会合成一份(replace属性也可以用起来)。
REQUEST_INSTALL_PACKAGES
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
Google play禁止了使用REQUEST_INSTALL_PACKAGES这个权限,如果真需要使用的话要自己额外提供资料进行说明。也就是说,应用内自己下载APK进行安装更新是实现不了了,只能乖乖去Google Play更新。处理这个问题的时候记得在manifest删除该权限,并关闭相关安装功能。
AAB加固
这个个人的话好像还挺麻烦,我找了几个看了下价格,直接劝退,好在公司有和做加密的公司合作,支持AAB加固,也就弄了下,但是不加固也不是不行,当然有安全考虑还是加固下最好。
应用审核
打包上传什么的都是简单的。。。审核后会出很多问题,然后就得去适配,下面列举下我碰到的退回邮件:
- TBS SDK(X5内核),下载可执行代码。
- AliPay、极光推送,不符合显着披露准则传输已安装应用程序信息的集合
- SSL Error处理不当
- 微博、QQ分享SDK问题
总而言之,就是国内的好多第三方SDK都不能在Google使用,包括但不限于: TBS、bugly、微信支付&分享(Android版在一起)、QQ分享、微博分享、AliPay、友盟、极光(有专门的海外版)等。
所以要不就看看这些SDK有没有海外版,要不就能删了找替代方案了。
功能适配
上面提到了targetSdkVersion要提高到31,这就有很多问题了,下面说说我遇到的一些问题。
储存适配
targetSdkVersion提高了,影响最大的就是储存适配了,还好我这不是很多。办法就是尽量使用私有目录,重要的东西放到内部私有目录,缓存、文件较大的放到外部私有目录,可以通过FileProvider向外提供Uri(拍照、裁切之类)。
对于要使用公有目录的地方,尽量使用SAF框架和Media通过Uri去访问,注意Android 9.0及以下要申请权限,9.0以上权限都不用申请,尽量避免使用File直接访问。其实Uri也不是特别难用吧,访问文件就像操作数据库一样。我也写了一点文章,但是感觉不怎么样,就不放出来了。
分享功能
因为微信、QQ、微博的分享SDK都用不了,所以只能用系统自带的分享去实现类似的功能,下面我也总结了一篇文章,可以参考下:
使用系统自带分享,分享到微信、朋友圈、微博、QQ,适配Android12
H5适配
我这上架的是要给混合开发的应用,好老了,用的还是Cordova。因为X5内核不能用了,所以我们这边就只能用系统自带的webveiw了,真就头大了,各种不兼容问题,好在问题不是我解决,提一下。
SSL Error
这个问题主要是WebViewClient里面的onReceivedSslError方法写得不当:
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// handler.cancel();
handler.proceed();
}
根据被拒邮件提示,大概意思是遇到SSL错误的时候需要提示用户,所以处理方式如下:
AlertDialog.Builder(context).apply {
val errorMsg = when (error?.primaryError) {
SslError.SSL_UNTRUSTED -> "The certificate authority is not trusted."
SslError.SSL_EXPIRED -> "The certificate has expired."
SslError.SSL_IDMISMATCH -> "The certificate Hostname mismatch."
SslError.SSL_NOTYETVALID -> "The certificate is not yet valid."
SslError.SSL_DATE_INVALID -> "The date of the certificate is invalid"
else -> "SSL Certificate error."
}
setMessage("$errorMsg Do you want to continue anyway?")
setPositiveButton("continue") { _, _ ->
handler?.proceed()
}
setNegativeButton("cancel") { _, _ ->
handler?.cancel()
}
}.create().show()
也是网上找的,能用就行。
小结
首先恭喜下自己,这个应用算是蒙混过关了(吐槽下Google的审核也是水),担心了很久因为隐私协议问题过不了。其次,其实我这app涉及的东西不多,像是推送、支付、统计什么的都没有,有的话就麻烦多了哦!最后,希望有需要的朋友,自己的应用也能顺利上架Google!