|
@@ -1,205 +1,124 @@
|
|
|
-package com.sybotan.android.demo.tools;
|
|
|
+package com.sybotan.android.demo.tools
|
|
|
+
|
|
|
+import android.app.ProgressDialog
|
|
|
+import android.content.Context
|
|
|
+import android.content.Intent
|
|
|
+import android.net.Uri
|
|
|
+import android.os.Build
|
|
|
+import android.os.Environment
|
|
|
+import android.os.Handler
|
|
|
+import android.os.Message
|
|
|
+import androidx.core.content.FileProvider
|
|
|
+import java.io.*
|
|
|
+import java.lang.Exception
|
|
|
+import java.net.HttpURLConnection
|
|
|
+import java.net.URL
|
|
|
+import java.nio.ByteBuffer
|
|
|
+import java.nio.charset.Charset
|
|
|
+
|
|
|
+class DownLoadApk(private val dialog: ProgressDialog, var url: String, var context: Context, build: String) : Runnable {
|
|
|
+ var `is`: InputStream? = null
|
|
|
+ var fos: FileOutputStream? = null
|
|
|
+ var build: String
|
|
|
|
|
|
-import android.app.ProgressDialog;
|
|
|
-import android.content.ContentResolver;
|
|
|
-import android.content.Context;
|
|
|
-import android.content.Intent;
|
|
|
-import android.net.Uri;
|
|
|
-import android.os.Build;
|
|
|
-import android.os.Environment;
|
|
|
-import android.os.Handler;
|
|
|
-import android.os.Message;
|
|
|
-import android.os.ParcelFileDescriptor;
|
|
|
-
|
|
|
-import androidx.core.content.FileProvider;
|
|
|
-
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileOutputStream;
|
|
|
-import java.io.InputStream;
|
|
|
-import java.net.HttpURLConnection;
|
|
|
-import java.net.URL;
|
|
|
-
|
|
|
-public class DownLoadApk implements Runnable {
|
|
|
- private ProgressDialog dialog;
|
|
|
- InputStream is;
|
|
|
- FileOutputStream fos;
|
|
|
- String url;
|
|
|
- String build;
|
|
|
- Context context;
|
|
|
// 判断是否停止
|
|
|
- private boolean mIsCancel = false;
|
|
|
- // 进度
|
|
|
- private int mProgress;
|
|
|
- // 文件保存路径
|
|
|
- private String mSavePath;
|
|
|
-
|
|
|
- public DownLoadApk(ProgressDialog dialog, String url, Context context, String build) {
|
|
|
- this.dialog = dialog;
|
|
|
- this.url = url;
|
|
|
- this.context = context;
|
|
|
- this.build = build;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void run() {
|
|
|
-// OkHttpClient client = new OkHttpClient();
|
|
|
-// LogUtils.e("url=====" + url);
|
|
|
-// Request request = new Request.Builder().get().url(url).build();
|
|
|
-// try {
|
|
|
-// Response response = client.newCall(request).execute();
|
|
|
-// if (response.isSuccessful()) {
|
|
|
-// //获取内容总长度
|
|
|
-// long contentLength = response.body().contentLength();
|
|
|
-// //设置最大值
|
|
|
-// LogUtils.e("url=====" + contentLength);
|
|
|
-// dialog.setMax((int) contentLength);
|
|
|
-// //保存到sd卡
|
|
|
-// File apkFile = new File(Environment.getExternalStorageDirectory() +"mnt/sdcard", "meos.apk");
|
|
|
-// fos = new FileOutputStream(apkFile);
|
|
|
-// //获得输入流
|
|
|
-// is = response.body().byteStream();
|
|
|
-// //定义缓冲区大小
|
|
|
-// byte[] bys = new byte[1024];
|
|
|
-// int progress = 0;
|
|
|
-// int len = -1;
|
|
|
-// while ((len = is.read(bys)) != -1) {
|
|
|
-// try {
|
|
|
-// Thread.sleep(1);
|
|
|
-// fos.write(bys, 0, len);
|
|
|
-// fos.flush();
|
|
|
-// progress += len;
|
|
|
-// //设置进度
|
|
|
-// dialog.setProgress(progress);
|
|
|
-// LogUtils.e("url=====" + progress);
|
|
|
-// } catch (InterruptedException e) {
|
|
|
-// LogUtils.e("url=====" + "InterruptedException");
|
|
|
-// }
|
|
|
-// }
|
|
|
-// //下载完成,提示用户安装
|
|
|
-// installApk(apkFile);
|
|
|
-// }
|
|
|
-// } catch (IOException e) {
|
|
|
-//
|
|
|
-// } finally {
|
|
|
-// //关闭io流
|
|
|
-// if (is != null) {
|
|
|
-// try {
|
|
|
-// is.close();
|
|
|
-// } catch (IOException e) {
|
|
|
-// e.printStackTrace();
|
|
|
-// }
|
|
|
-// is = null;
|
|
|
-// }
|
|
|
-// if (fos != null) {
|
|
|
-// try {
|
|
|
-// fos.close();
|
|
|
-// } catch (IOException e) {
|
|
|
-// e.printStackTrace();
|
|
|
-// }
|
|
|
-// fos = null;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// dialog.dismiss();
|
|
|
+ private val mIsCancel = false
|
|
|
|
|
|
+ // 进度
|
|
|
+ private var mProgress = 0
|
|
|
|
|
|
+ // 文件保存路径
|
|
|
+ private val mSavePath: String? = null
|
|
|
+ override fun run() {
|
|
|
try {
|
|
|
- if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
|
|
- String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/";
|
|
|
-// 文件保存路径
|
|
|
- mSavePath = sdPath + "meos";
|
|
|
-
|
|
|
- File dir = new File(mSavePath);
|
|
|
- if (!dir.exists()) {
|
|
|
- dir.mkdir();
|
|
|
+ if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
|
|
|
+ val dir = context.getExternalFilesDir("meos")
|
|
|
+ if (!dir!!.exists()) {
|
|
|
+ dir.mkdir()
|
|
|
}
|
|
|
// 下载文件
|
|
|
- HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
|
|
- conn.connect();
|
|
|
- InputStream is = conn.getInputStream();
|
|
|
- int length = conn.getContentLength();
|
|
|
-
|
|
|
- File apkFile = new File(mSavePath, build);
|
|
|
-
|
|
|
- File apkFiles = new File(mSavePath);
|
|
|
- if (!apkFiles.exists()) {
|
|
|
- apkFiles.mkdirs();
|
|
|
- }
|
|
|
- FileOutputStream fos = new FileOutputStream(apkFile);
|
|
|
-
|
|
|
- int count = 0;
|
|
|
- byte[] buffer = new byte[1024];
|
|
|
- while (!mIsCancel) {
|
|
|
- int numread = is.read(buffer);
|
|
|
- count += numread;
|
|
|
- // 计算进度条的当前位置
|
|
|
- mProgress = (int) (((float) count / length) * 100);
|
|
|
- // 更新进度条
|
|
|
- mUpdateProgressHandler.sendEmptyMessage(1);
|
|
|
-
|
|
|
- // 下载完成
|
|
|
- if (numread < 0) {
|
|
|
- mUpdateProgressHandler.sendEmptyMessage(2);
|
|
|
- break;
|
|
|
+ val conn = URL(url).openConnection() as HttpURLConnection
|
|
|
+ conn.connect()
|
|
|
+ val `is` = conn.inputStream
|
|
|
+ val length = conn.contentLength
|
|
|
+ val outputStream = FileOutputStream("$dir/$build")
|
|
|
+ val byteArray = ByteArray(1024)
|
|
|
+ var count: Int
|
|
|
+ var progress = 0f
|
|
|
+ do {
|
|
|
+ count = `is`.read(byteArray)
|
|
|
+ if (count != -1) {
|
|
|
+ outputStream.write(byteArray, 0, count)
|
|
|
+ progress += count
|
|
|
+ mProgress = ((progress / length) * 100f).toInt()
|
|
|
+ mUpdateProgressHandler.sendEmptyMessage(1)
|
|
|
+ } else {
|
|
|
+ `is`.close()
|
|
|
+ outputStream.close()
|
|
|
+ break
|
|
|
}
|
|
|
- fos.write(buffer, 0, numread);
|
|
|
- }
|
|
|
- fos.close();
|
|
|
- is.close();
|
|
|
+ } while (true)
|
|
|
+ mUpdateProgressHandler.sendEmptyMessage(2)
|
|
|
+ `is`.close()
|
|
|
+ outputStream.close()
|
|
|
+
|
|
|
}
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
+ } catch (e: Exception) {
|
|
|
+ e.printStackTrace()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 接收消息
|
|
|
*/
|
|
|
- private Handler mUpdateProgressHandler = new Handler() {
|
|
|
- @Override
|
|
|
- public void handleMessage(Message msg) {
|
|
|
- switch (msg.what) {
|
|
|
- case 1:
|
|
|
- // 设置进度条
|
|
|
- dialog.setProgress(mProgress);
|
|
|
- break;
|
|
|
- case 2:
|
|
|
+ private val mUpdateProgressHandler: Handler = object : Handler() {
|
|
|
+ override fun handleMessage(msg: Message) {
|
|
|
+ when (msg.what) {
|
|
|
+ 1 -> // 设置进度条
|
|
|
+ dialog.progress = mProgress
|
|
|
+ 2 -> {
|
|
|
// 隐藏当前下载对话框
|
|
|
- dialog.dismiss();
|
|
|
+ dialog.dismiss()
|
|
|
// 安装 APK 文件
|
|
|
- installAPK();
|
|
|
+ installAPK()
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- ;
|
|
|
- };
|
|
|
-
|
|
|
- protected void installAPK() {
|
|
|
- File apkFile = new File(mSavePath, build);
|
|
|
+ protected fun installAPK() {
|
|
|
+ val dir = context.getExternalFilesDir("meos")
|
|
|
+ // File apkFile = new File(mSavePath, build);
|
|
|
+ val apkFile = File(dir, build)
|
|
|
if (!apkFile.exists()) {
|
|
|
- return;
|
|
|
+ return
|
|
|
}
|
|
|
-// Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
|
-//// 安装完成后,启动app(源码中少了这句话)
|
|
|
-// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
-// Uri uri = Uri.parse("file://" + apkFile.toString());
|
|
|
-// intent.setDataAndType(uri, "application/vnd.android.package-archive");
|
|
|
-// intent.setAction("android.intent.action.VIEW");
|
|
|
-// intent.addCategory("android.intent.category.DEFAULT");
|
|
|
-// context.startActivity(intent);
|
|
|
-
|
|
|
-
|
|
|
- Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
|
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
+ val intent = Intent(Intent.ACTION_VIEW)
|
|
|
+ intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
|
//区别于 FLAG_GRANT_READ_URI_PERMISSION 跟 FLAG_GRANT_WRITE_URI_PERMISSION, URI权限会持久存在即使重启,直到明确的用 revokeUriPermission(Uri, int) 撤销。 这个flag只提供可能持久授权。但是接收的应用必须调用ContentResolver的takePersistableUriPermission(Uri, int)方法实现
|
|
|
- Uri apkUri = FileProvider.getUriForFile(context, "com.sybotan.android.demo.fileProvider", apkFile); //与manifest中定义的provider中的authorities="com.xxxx.fileprovider"保持一致
|
|
|
- intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
|
|
|
+ val apkUri = FileProvider.getUriForFile(context, "com.sybotan.android.demo.fileProvider", apkFile) //与manifest中定义的provider中的authorities="com.xxxx.fileprovider"保持一致
|
|
|
+ intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
|
|
|
} else {
|
|
|
- intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
|
|
|
+ intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive")
|
|
|
}
|
|
|
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
|
|
|
- intent.addCategory("android.intent.category.DEFAULT");
|
|
|
- intent.setAction("android.intent.action.VIEW");
|
|
|
- context.startActivity(intent);
|
|
|
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
|
|
|
+ intent.addCategory("android.intent.category.DEFAULT")
|
|
|
+ intent.action = "android.intent.action.VIEW"
|
|
|
+ context.startActivity(intent)
|
|
|
+ }
|
|
|
+
|
|
|
+ companion object {
|
|
|
+ fun getChars(bytes: ByteArray): CharArray {
|
|
|
+ val cs = Charset.forName("UTF-8")
|
|
|
+ val bb = ByteBuffer.allocate(bytes.size)
|
|
|
+ bb.put(bytes).flip()
|
|
|
+ val cb = cs.decode(bb)
|
|
|
+ return cb.array()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ init {
|
|
|
+ this.build = "$build.apk"
|
|
|
}
|
|
|
-}
|
|
|
+}
|