在android 7.0之前版本更新其實相當簡單,隻需要使用系統下載下傳器就能夠完成下載下傳之後安裝,但是在7.0之後android更新安全機制,下載下傳安裝受到一些限制。這裡我分裝成了幾個工具友善開發者使用:
添權重限
<uses-permissionandroid:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
接下來是最重要的工具類:
public class CXVersionCheckUtils {
private static File saveFile;
private Activity activity;
private static long downloadId = ;
public CXVersionCheckUtils(Activity activity) {
this.activity = activity;
initFile();
}
private void initFile() {
if (saveFile==null)
saveFile=new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "filiday.apk");
}
public void start(String url,String t, String d){
if (downloadId!=) {
clearCurrentTask(downloadId);
}
downloadId=download(url,t,d);
}
public long download(String url, String title, String desc) {
Uri uri = Uri.parse(url);
DownloadManager.Request req = new DownloadManager.Request(uri);
//設定WIFI下進行更新
req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
//下載下傳中和下載下傳完後都顯示通知欄
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
//使用系統預設的下載下傳路徑 此處為應用内 /android/data/packages ,是以相容7.0
// req.setDestinationInExternalFilesDir(activity, Environment.DIRECTORY_DOWNLOADS, title);
if (saveFile.exists()) {
saveFile.delete();
}
req.setDestinationUri(Uri.fromFile(saveFile));
//通知欄标題
req.setTitle(title);
//通知欄描述資訊
req.setDescription(desc);
//設定類型為.apk
req.setMimeType("application/vnd.android.package-archive");
//擷取下載下傳任務ID
DownloadManager dm = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE);
return dm.enqueue(req);
}
public void clearCurrentTask(long downloadId) {
DownloadManager dm = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE);
try {
dm.remove(downloadId);
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
}
}
public static void installApk(Context context) {
downloadId=;
Intent intent = new Intent(Intent.ACTION_VIEW);
try {
String[] command = {"chmod", "777", saveFile.getAbsolutePath()};
ProcessBuilder builder = new ProcessBuilder(command);
builder.start();
} catch (Exception ignored) {
ignored.printStackTrace();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(context, "com.chengxing.comchenxingnetapp.fileprovider", saveFile);
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(saveFile), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
}
}
建立廣播接受者:CXDownloadReceiver
public class CXDownloadReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -);
CXVersionCheckUtils.installApk(context);//開始安裝
} else if (intent.getAction().equals(DownloadManager.ACTION_NOTIFICATION_CLICKED)) {
// DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
//擷取所有下載下傳任務Ids組
//long[] ids = intent.getLongArrayExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS);
點選通知欄取消所有下載下傳
//manager.remove(ids);
//Toast.makeText(context, "下載下傳任務已取消", Toast.LENGTH_SHORT).show();
//處理 如果還未完成下載下傳,使用者點選Notification ,跳轉到下載下傳中心
Intent viewDownloadIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
viewDownloadIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(viewDownloadIntent);
}
}
}
配置廣播:
<!--下載下傳安裝接收器-->
<receiver android:name=".CXDownloadReceiver">
<intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
<action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED" />
</intent-filter>
</receiver>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.chengxing.comchenxingnetapp.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
@xml/file_paths是允許安裝apk的目錄:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>
這裡使用允許sd卡根目錄的apk 允許安裝。android.support.v4.content.FileProvider 是android7.0 需要配置一個提供者。
使用方法:
versionCheckUtils.start(updateBean.updateUrl,"filiday.apk", "filiday new version");
第一個參數是下載下傳位址, 第二個參數是下載下傳通知标題,第三個通知是通知描述。