Browse Source

feat 自动更新适配

lihao1 3 years ago
parent
commit
28b5781a2f

+ 1 - 1
demo/src/main/java/com/sybotan/android/demo/activities/PocActivity.kt

@@ -272,7 +272,7 @@ class PocActivity : BaseActivity(), DIAware {
         dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)
         dialog.setCancelable(false)
         dialog.show()
-        Thread(DownLoadApk(dialog, url, this@PocActivity, build)).start()
+        Thread(DownLoadApk(dialog, url!!, this@PocActivity, build!!)).start()
     }
 
     @RequiresApi(Build.VERSION_CODES.R)

+ 97 - 178
demo/src/main/java/com/sybotan/android/demo/tools/DownLoadApk.kt

@@ -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"
     }
-}
+}