工具-下载并安装Apk

下载并安装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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
* 1.从服务器下载apk
*
* @param path
* @param pd
*/
public static File getFileFromServer(String path, @NonNull ProgressDialog pd) throws Exception{
// 如果相等的话表示当前的sdcard挂载在手机上并且是可用的
HttpURLConnection conn;

if(path.indexOf("https") != -1){//独立打包的地址为https,因此需要用Https方式下载
int lastIndex = path.lastIndexOf("/");
if(lastIndex == -1){
File file = new File(pd.getContext().getExternalCacheDir(), "updata.apk");
return file;
}

String preScheme = path.substring(0, lastIndex);
String name = path.substring(lastIndex, path.length());
URL url = new URL(preScheme + URLEncoder.encode(name,"UTF-8"));//独立打包的包名时utf-8的

TrustHttpsHostHelper.trustAllHosts();
conn = (HttpsURLConnection)url.openConnection();
TrustHttpsHostHelper.setHostVerifier((HttpsURLConnection) conn);
conn.connect();
}else{
URL url = new URL(path);
conn = (HttpURLConnection) url.openConnection();
}

conn.setConnectTimeout(5000);

// 获取到文件的大小
int fileSize = conn.getContentLength();
int newFileSize = FormetFileSize(fileSize);
pd.setMax(newFileSize);

InputStream is = conn.getInputStream();

File file = new File(pd.getContext().getExternalCacheDir(), "updata.apk");

FileOutputStream fos = new FileOutputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int len;
int total = 0;
while ((len = bis.read(buffer)) != -1){
fos.write(buffer, 0, len);
total += len;
// 获取当前已下载量
int newTotal = FormetFileSize(total);
pd.setProgress(newTotal);
pd.setProgressNumberFormat(newTotal + " kb/" + newFileSize + " kb");
}
fos.close();
bis.close();
is.close();
return file;
}

注意:这一段中URL url = new URL(preScheme + URLEncoder.encode(name,"UTF-8"));//独立打包的包名时utf-8的(其中 name 是带一个斜杆的,比如”/byldy_1.1.2.apk”)会把最后一个”/“转成”%2F”,而这会有个问题:七牛的链接比如https://qiniudownload.byjxj.com%2Fbyldy_1.1.2.apk放到浏览器上也无法下载;而https://qiniudownload.byjxj.com/20191219%2Fbyldy_1.1.3.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
//下载并安装
public void downLoadApk(final UpdataInfoModel info) {
if (info == null) {
return;
}

final ProgressDialog pd; // 进度条对话框
pd = new ProgressDialog(activity);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("正在下载更新");
pd.setCanceledOnTouchOutside(false);// 设置点击屏幕Dialog不消失
pd.show();
new Thread() {
@Override
public void run() {
try {
File file = DownLoadManager.getFileFromServer(info.getUpdateUrl(), pd);
sleep(3000);
installApk(file);
pd.dismiss(); // 结束掉进度条对话框
} catch (Exception e) {
e.printStackTrace();

// 下载apk失败
ToastUtil.showToastLong(activity.getApplicationContext(), "下载新版本失败");
if (!info.isForceUpdate() && versionUpdateListener != null) {
//后台设置非强制升级,又更新失败,那么直接进入下一步
versionUpdateListener.onNormal(false);
}
}
}
}.start();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 安装apk
private void installApk(File file) {
Intent intent = new Intent(Intent.ACTION_VIEW);
//判断是否是AndroidN以及更高的版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".updateProvider", file);
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
//这个要加 return,否则可能会出现安装完毕点返回又到安装页面的问题
return;
} else {
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}

activity.startActivityForResult(intent, 999, false);
}