App通過瀏覽器下載更新的實現方法

轉自:https://blog.csdn.net/wolfking0608/article/details/79619472

特別注意:  兩個更新前後的apk,必須保證簽名和包名完全一致,纔可以覆蓋安裝,否則安裝會失敗!!!

工具類代碼如下:

1.下載更新APK的工具

[java] view plain copy
  1. public class InstallUtils {  
  2.   
  3.   
  4.     //任務定時器  
  5.     private Timer mTimer;  
  6.     //定時任務  
  7.     private TimerTask mTask;  
  8.     //文件總大小  
  9.     private int fileLength = 1;  
  10.     //下載的文件大小  
  11.     private int fileCurrentLength;  
  12.   
  13.     private Context context;  
  14.     private String httpUrl;  
  15.     private String savePath;  
  16.     private String saveName;  
  17.     private DownloadCallBack downloadCallBack;  
  18.     private static File saveFile;  
  19.   
  20.     private boolean isComplete = false;  
  21.   
  22.   
  23.     public interface DownloadCallBack {  
  24.         void onStart();  
  25.   
  26.         void onComplete(String path);  
  27.   
  28.         void onLoading(long total, long current);  
  29.   
  30.         void onFail(Exception e);  
  31.     }  
  32.   
  33.     public interface InstallCallBack {  
  34.   
  35.         void onSuccess();  
  36.   
  37.         void onFail(Exception e);  
  38.     }  
  39.   
  40.     public InstallUtils(Context context, String httpUrl, String saveName, DownloadCallBack downloadCallBack) {  
  41.         this.context = context;  
  42.         this.httpUrl = httpUrl;  
  43.         this.saveName = saveName;  
  44.         this.downloadCallBack = downloadCallBack;  
  45.         this.savePath = getCachePath(this.context);  
  46.     }  
  47.   
  48.   
  49.     public void downloadAPK() {  
  50.         if (TextUtils.isEmpty(httpUrl)) {  
  51.             return;  
  52.         }  
  53.         saveFile = new File(savePath);  
  54.         if (!saveFile.exists()) {  
  55.             boolean isMK = saveFile.mkdirs();  
  56.             if (!isMK) {  
  57.                 //創建失敗  
  58.                 return;  
  59.             }  
  60.         }  
  61.   
  62.         saveFile = new File(savePath + File.separator + saveName + ".apk");  
  63.   
  64.         if (downloadCallBack != null) {  
  65.             //下載開始  
  66.             downloadCallBack.onStart();  
  67.         }  
  68.   
  69.         new Thread(new Runnable() {  
  70.             @Override  
  71.             public void run() {  
  72.                 InputStream inputStream = null;  
  73.                 FileOutputStream outputStream = null;  
  74.                 HttpURLConnection connection = null;  
  75.                 try {  
  76.                     URL url = new URL(httpUrl);  
  77.                     connection = (HttpURLConnection) url.openConnection();  
  78.                     connection.setConnectTimeout(10 * 1000);  
  79.                     connection.setReadTimeout(10 * 1000);  
  80.                     connection.connect();  
  81.                     inputStream = connection.getInputStream();  
  82.                     outputStream = new FileOutputStream(saveFile);  
  83.                     fileLength = connection.getContentLength();  
  84.   
  85.                     //判斷fileLength大小  
  86.                     if (fileLength <= 0) {  
  87.                         //失敗的地址  
  88.                         ((Activity) context).runOnUiThread(new Runnable() {  
  89.                             @Override  
  90.                             public void run() {  
  91.                                 if (downloadCallBack != null) {  
  92.                                     downloadCallBack.onFail(new Exception("下載地址異常"));  
  93.                                     downloadCallBack = null;  
  94.                                 }  
  95.                             }  
  96.                         });  
  97.                         return;  
  98.                     }  
  99.   
  100.                     //計時器  
  101.                     initTimer();  
  102.   
  103.                     byte[] buffer = new byte[1024];  
  104.                     int current = 0;  
  105.                     int len;  
  106.                     while ((len = inputStream.read(buffer)) > 0) {  
  107.                         outputStream.write(buffer, 0, len);  
  108.                         current += len;  
  109.                         if (fileLength > 0) {  
  110.                             fileCurrentLength = current;  
  111.                         }  
  112.                     }  
  113.                     isComplete = true;  
  114.                     //下載完成  
  115.                     ((Activity) context).runOnUiThread(new Runnable() {  
  116.                         @Override  
  117.                         public void run() {  
  118.                             //解決某些低版本安裝失敗的問題  
  119.                             changeApkFileMode(saveFile);  
  120.   
  121.                             if (downloadCallBack != null) {  
  122.                                 downloadCallBack.onComplete(saveFile.getPath());  
  123.                                 downloadCallBack = null;  
  124.                             }  
  125.                         }  
  126.                     });  
  127.                 } catch (final Exception e) {  
  128.                     e.printStackTrace();  
  129.                     ((Activity) context).runOnUiThread(new Runnable() {  
  130.                         @Override  
  131.                         public void run() {  
  132.                             if (downloadCallBack != null) {  
  133.                                 downloadCallBack.onFail(e);  
  134.                                 downloadCallBack = null;  
  135.                             }  
  136.                         }  
  137.                     });  
  138.                 } finally {  
  139.                     try {  
  140.                         if (inputStream != null)  
  141.                             inputStream.close();  
  142.                         if (outputStream != null)  
  143.                             outputStream.close();  
  144.                         if (connection != null)  
  145.                             connection.disconnect();  
  146.                     } catch (IOException e) {  
  147.                     }  
  148.                     //銷燬Timer  
  149.                     destroyTimer();  
  150.                 }  
  151.             }  
  152.         }).start();  
  153.   
  154.     }  
  155.   
  156.     private void initTimer() {  
  157.         mTimer = new Timer();  
  158.         mTask = new TimerTask() {//在run方法中執行定時的任務  
  159.             @Override  
  160.             public void run() {  
  161.                 ((Activity) context).runOnUiThread(new Runnable() {  
  162.                     @Override  
  163.                     public void run() {  
  164.                         if (downloadCallBack != null) {  
  165.                             if (!isComplete) {  
  166.                                 downloadCallBack.onLoading(fileLength, fileCurrentLength);  
  167.                             }  
  168.                         }  
  169.                     }  
  170.                 });  
  171.             }  
  172.         };  
  173.         //任務定時器一定要啓動  
  174.         mTimer.schedule(mTask, 0200);  
  175.     }  
  176.   
  177.   
  178.     private void destroyTimer() {  
  179.         if (mTimer != null && mTask != null) {  
  180.             mTask.cancel();  
  181.             mTimer.cancel();  
  182.             mTask = null;  
  183.             mTimer = null;  
  184.         }  
  185.     }  
  186.   
  187.     /** 
  188.      * 安裝APK工具類 
  189.      * 
  190.      * @param context  上下文 
  191.      * @param filePath 文件路徑 
  192.      * @param callBack 安裝界面成功調起的回調 
  193.      */  
  194.     public static void installAPK(Context context, String filePath, InstallCallBack callBack) {  
  195.         try {  
  196.             Intent intent = new Intent();  
  197.             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  198.             intent.setAction(Intent.ACTION_VIEW);  
  199.             File apkFile = new File(filePath);  
  200.             Uri apkUri;  
  201.             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  
  202.                 String authority = context.getPackageName() + ".updateFileProvider";  
  203.                 apkUri = FileProvider.getUriForFile(context, authority, apkFile);  
  204.                 // 授予目錄臨時共享權限  
  205.                 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);  
  206.             } else {  
  207.                 apkUri = Uri.fromFile(apkFile);  
  208.             }  
  209.             intent.setDataAndType(apkUri, "application/vnd.android.package-archive");  
  210.             context.startActivity(intent);  
  211.             if (callBack != null) {  
  212.                 callBack.onSuccess();  
  213.             }  
  214.             //關閉當前  
  215.             android.os.Process.killProcess(android.os.Process.myPid());  
  216.         } catch (Exception e) {  
  217.             if (callBack != null) {  
  218.                 callBack.onFail(e);  
  219.             }  
  220.         }  
  221.     }  
  222.   
  223.     /** 
  224.      * 通過瀏覽器下載APK更新安裝 
  225.      * 
  226.      * @param context    上下文 
  227.      * @param httpUrlApk APK下載地址 
  228.      */  
  229.     public static void installAPKWithBrower(Context context, String httpUrlApk) {  
  230.         Uri uri = Uri.parse(httpUrlApk);  
  231.         Intent viewIntent = new Intent(Intent.ACTION_VIEW, uri);  
  232.         context.startActivity(viewIntent);  
  233.     }  
  234.   
  235.   
  236.     /** 
  237.      * 獲取app緩存路徑    SDCard/Android/data/你的應用的包名/cache 
  238.      * 
  239.      * @param context 
  240.      * @return 
  241.      */  
  242.     public String getCachePath(Context context) {  
  243.         String cachePath;  
  244.         if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())  
  245.                 || !Environment.isExternalStorageRemovable()) {  
  246.             //外部存儲可用  
  247.             cachePath = context.getExternalCacheDir().getPath();  
  248.         } else {  
  249.             //外部存儲不可用  
  250.             cachePath = context.getCacheDir().getPath();  
  251.         }  
  252.         return cachePath;  
  253.     }  
  254.   
  255.     //參照:APK放到data/data/下面提示解析失敗 (http://blog.csdn.net/lonely_fireworks/article/details/27693073)  
  256.     private void changeApkFileMode(File file) {  
  257.         try {  
  258.             //apk放在緩存目錄時,低版本安裝提示權限錯誤,需要對父級目錄和apk文件添加權限  
  259.             String cmd1 = "chmod 777 " + file.getParent();  
  260.             Runtime.getRuntime().exec(cmd1);  
  261.   
  262.             String cmd = "chmod 777 " + file.getAbsolutePath();  
  263.             Runtime.getRuntime().exec(cmd);  
  264.         } catch (IOException e) {  
  265.             e.printStackTrace();  
  266.         }  
  267.     }  
  268.   
  269.   
  270. }  
[java] view plain copy
  1.   

使用方式:

public static final String APK_URL = "http://static.portport.cn/tools/app/GangGang_release-1.0.apk";
[java] view plain copy
  1. public void download2(View view) {  
  2.        //通過瀏覽器去下載APK  
  3.        InstallUtils.installAPKWithBrower(this, APK_URL);  
  4.    }  
自個去試試吧!挺好用的!希望能幫到現在正在做app升級的你!!!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章