avatar

Unity 调用安卓原生更新APK

引言

产品上线后免不了要迭代更新,尤其是大版本更新的时候,必须让玩家重新安装。常用方法是使用打包时的版本号结合后端配置进行控制,根据自己定义的规则,当判断需要重新安装更新时,提示玩家进行更新。我们一开始在iPhone上的处理是跳转到AppStore,Android上的处理是跳转到我们的官网,提示玩家进行下载。后来有很多安卓用户反馈不清楚如何下载、经常更新失败。

解决方案

在游戏内根据安装包的版本号和渠道号,直接下载对应的apk,下载完成后调用安卓原生进行安装。

具体实现

1.Unity中使用WWW下载安卓apk,并保存到沙盒路径,调用安卓原生方法安装。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
private IEnumerator downloadApk(string apkURL) {

string apkPath = Application.persistentDataPath + "temp.apk";

if (File.Exists(apkPath)) {
File.Delete(apkPath);
}

if (string.IsNullOrEmpty(apkURL)) {
Debug.LogError("下载地址为空");
yield break;
}

WWW www = new WWW(apkURL);

//更新下载进度
while (!www.isDone) {
float progress =www.progress;
if (progress>0) {
progress = (((int)(www.progress * 100)) % 100);
}
if (progress >= 99) {
progress = 100;
}
Debug.Log("下载中{0}%,请耐心等待...", progress);
yield return 1;
}

if (string.IsNullOrEmpty(www.error)) {
Debug.Log("下载完成,开始安装");
var bytes = www.bytes;
File.WriteAllBytes(apkPath, bytes);
//调用接口进行安装
if (File.Exists(apkPath)) {
PlatformFace.Instance.InstallApk(apkPath);
}
} else {
//下载有错
Debug.LogWarning("下载未完成");
}

}

2.修改安卓工程
添加权限,在AndroidMainfest.xml文件的manifest标签中添加

1
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

配置FileProvider,适配安卓7.0以上
在AndroidMainfest.xml文件的application标签中添加

1
2
3
4
5
6
7
8
9
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>

在res/xml文件目录下新建file_paths.xml文件,添加

1
2
3
4
5
6
7
<resources>
<paths>
<external-path
name="files"
path="" />
</paths>
</resources>

在build.gradle中添加android-support-v4.jar依赖

1
2
3
dependencies {
implementation files("libs/android-support-v4.jar")
}

在MainActivity下添加代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//安装apk
public void InstallApk(String apkPath) {
File file = new File(apkPath);
Intent intent = new Intent(Intent.ACTION_VIEW);
if(Build.VERSION.SDK_INT>=24) { //Android 7.0及以上
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// 参数2 清单文件中provider节点里面的authorities ; 参数3 共享的文件,即apk包的file类
Uri apkUri = FileProvider.getUriForFile(getApplicationContext(), BuildConfig.APPLICATION_ID+".fileprovider", file);//记住修改包名
//对目标应用临时授权该Uri所代表的文件
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
}else{
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
this.startActivity(intent);
}

备注

文章内容参考了CSDN-幻世界。不用于商业用途,如有侵权请联系,我将尽快删除。
需要注意的是打包时的Bundle Version Code和Target API Level,如果低于设备上已安装的apk,将不能覆盖安装,需要先拆卸才可以安装。

文章作者: tiger
文章链接: https://chenghu.online/posts/144fe5a4/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 tiger
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论