Android apk升級 相容6.0 7.0 低版本 華為手機
阿新 • • 發佈:2019-01-24
上篇部落格寫了用DownloadManager,進行下載,結果發現有些手機並不能相容,查詢原因是DownloadManager.Request 的setDestinationInExternalPublicDir()函式問題,這直接根源掛鉤,Request 有個預設路徑,導致android 7.0的不相容,具體原因不說,你們也應該知道了(API 禁止向您的應用外公開 file://URI,若要在應用間共享檔案,您應傳送一項 content://URI,並授予 URI 臨時訪問許可權。進行此授權的最簡單方式是使用 FileProvider類。 如需有關許可權和共享檔案的更多資訊。)那,您說該怎麼玩呢?那我們就用原始的HttpURLConnection 下載唄,你想呀,無非就是下載一個檔案而已。
多的不說直接上程式碼,下面是個工具類直接用就可以:
public class UpdataAPP { public Context context; private ProgressDialog pBar; private DownloadApkAsyncTask mAsyncTask = null; private int apkSzie; public UpdataAPP(Context context) { this.context = context; } /** * 版本更新----起 */ // 更新版本要用到的一些資訊 public void updateAPP(String url) { mAsyncTask = new DownloadApkAsyncTask(); mAsyncTask.execute(url); pBar=new ProgressDialog(context); pBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pBar.setTitle("正在下載"); pBar.setMessage("請稍候..."); pBar.setCanceledOnTouchOutside(false); pBar.setProgress(0); pBar.show(); } class DownloadApkAsyncTask extends AsyncTask<String, Integer, Integer> { private static final int DOWNLOAD_OK = 0x00; private static final int DOWNLOAD_ERROR = 0x01; private File apkFile = null; private File updateDir = null; public DownloadApkAsyncTask() { super(); } @Override protected Integer doInBackground(String... params) { try { URL url = new URL(params[0]); HttpURLConnection connection = (HttpURLConnection) url .openConnection(); connection.setConnectTimeout(15000); InputStream in = connection.getInputStream(); int curSize = 0; int progress = 0; int totalSize = connection.getContentLength(); apkSzie=totalSize; pBar.setMax(totalSize); // 設定進度條的總長度 if (android.os.Environment.MEDIA_MOUNTED .equals(android.os.Environment .getExternalStorageState())) { updateDir = new File(Environment .getExternalStorageDirectory().getPath() + "/townnet/apk/"); } else { updateDir = new File("/data/data/" + context.getPackageName() + "/apk/"); } if (!updateDir.exists()) { updateDir.mkdirs(); } apkFile = new File(updateDir.getPath(), "townnet.apk"); if (apkFile.exists()) { apkFile.delete(); } // 修改資料夾及安裝包的許可權,供第三方應用訪問 try { Runtime.getRuntime().exec( "chmod 705 " + updateDir.getPath()); Runtime.getRuntime().exec("chmod 604 " + apkFile.getPath()); } catch (Exception e) { e.printStackTrace(); } int temp; byte[] bytes = new byte[1024]; FileOutputStream out = new FileOutputStream(apkFile); while ((temp = in.read(bytes)) != -1) { out.write(bytes, 0, temp); curSize += temp; progress = curSize * 100 / totalSize; publishProgress(curSize); } in.close(); out.close(); } catch (Exception e) { e.printStackTrace(); return DOWNLOAD_ERROR; } return DOWNLOAD_OK; } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected void onPostExecute(Integer result) { super.onPostExecute(result); if (result == DOWNLOAD_OK) { Intent intent = new Intent(Intent.ACTION_VIEW); Uri photoURI = FileProvider.getUriForFile(context, context.getPackageName() + ".provider", new File(apkFile.getPath()) ); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (Build.VERSION.SDK_INT >= 24) { intent.setDataAndType(photoURI, "application/vnd.android.package-archive"); } else { intent.setDataAndType(Uri.parse("file://" + apkFile.getPath()), "application/vnd.android.package-archive"); } context.startActivity(intent); } } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); pBar.setProgress(values[0]); // 這裡就是關鍵的實時更新進度了! if (pBar.getProgress()==apkSzie){ pBar.cancel(); } } @Override protected void onCancelled() { super.onCancelled(); if (pBar!=null){ pBar.cancel(); } } }
}
那你說怎麼用呢?很簡單呀。
//開始下載
new UpdataAPP(mContext).updateAPP(apkDownLoadUrl);
下面是:AndroidManifest.xml的FileProvider:
<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" /> </provider>
xml下的filepaths: