最近在項(xiàng)目中做了App 根據(jù)后臺(tái)返回的版本值嚎莉,提示更新下載安裝新的版本;做之前看了幾篇文章惠遏,實(shí)現(xiàn)起來不是特難蓬坡,主要是使用了自帶的一個(gè)類 DownloadManager下載,通過廣播進(jìn)行安裝;
一片迅、獲取當(dāng)前的版本號
/**
* 獲取版本號
*/
public static int getAppVersionCode(Context context) {
int versioncode = -1;
try {
// ---get the package info---
PackageManager pm = context.getPackageManager();
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
versioncode = pi.versionCode;
} catch (Exception e) {
Log.e("VersionInfo", "Exception", e);
}
return versioncode;
}
二残邀、請求后臺(tái),獲取新的版本號柑蛇,進(jìn)行對比提示更新(新的版本號本地模擬的)
/**
* 檢測版本更新
*
* @param context
* @param isForceCheck 是否強(qiáng)制檢測更新
* true強(qiáng)制 - 無論什么網(wǎng)絡(luò)環(huán)境都會(huì)提示更新
* false非強(qiáng)制 - WiFi情況下才提示更新
* newVersionCode- 后臺(tái)請求的版本號
* updataInfo- 更新的內(nèi)容
*/
public static void checkUpdate(final Context context, final boolean isForceCheck,int newVersionCode,String updataInfo) {
if (!NetUtils.isConnected(context)) {
// 無網(wǎng)絡(luò)時(shí)
if (isForceCheck) {
// 手動(dòng)強(qiáng)制檢測更新時(shí)芥挣,提示文字
Toasts.show(context, "請檢查網(wǎng)絡(luò)連接");
} else {
// 非強(qiáng)制不做操作
}
return;
}
// 開始檢測更新
if(newVersionCode>Tools.getAppVersionCode(context)){
showUpdateConfirmDialog(context,updataInfo);
}
}
/**
* 顯示更新對話框,包含版本相關(guān)信息
*/
private static void showUpdateConfirmDialog(final Context context, final String updateInfo) {
new AlertDialog.Builder(context)
.setTitle("發(fā)現(xiàn)新版本")
.setMessage(updateInfo)
.setPositiveButton("立即更新", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (NetUtils.isWifi(context)) {
downLoadApp(context);
} else {
DialogUtils.showCommonDialog(context, "您當(dāng)前使用的移動(dòng)網(wǎng)絡(luò),是否繼續(xù)更新耻台。", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
downLoadApp(context);
}
}).show();
}
}
})
.setNegativeButton("以后再說", null)
.show();
}
/**
* 下載文件
* @param context
*/
public static void downLoadApp(Context context){
//downurl:下載app的后臺(tái)地址
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downurl));
// 下載時(shí)的網(wǎng)絡(luò)狀態(tài)空免,默認(rèn)是wifi和移動(dòng)網(wǎng)絡(luò)都可以下載,如果選擇一個(gè)盆耽,只能在選中的狀態(tài)下進(jìn)行下載
//request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
request.setTitle("app更新");
request.setDescription("app正在下載");
request.setAllowedOverRoaming(false);
//設(shè)置文件存放目錄
//判斷文件是否存在蹋砚,保證其唯一性
File file = context.getExternalFilesDir("Download/ccyj");
if(file.exists()){
file.delete();
}
request.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, "downapp");
DownloadManager downManager = (DownloadManager)context.getApplicationContext().getSystemService(Context.DOWNLOAD_SERVICE);
long id = downManager.enqueue(request);
// 存儲(chǔ)下載Key
SharedPreferences sharedPreferences = context.getSharedPreferences("downloadapp", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putLong("downloadid",id);
editor.commit();
}
判斷手機(jī)是否是wifi連接
/**
* 判斷是否是wifi連接
*/
public static boolean isWifi(Context context) {
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (null == cm) {
return false;
}
NetworkInfo info = cm.getActiveNetworkInfo();
if (null != info) {
if (info.getType() == ConnectivityManager.TYPE_WIFI) {
return true;
}
}
return false;
}
三扼菠、注冊廣播接收器, 接收消息ACTION_DOWNLOAD_COMPLETE
, 下載完成會(huì)發(fā)送廣播. 獲取下載文件的Uri, 進(jìn)行匹配, 發(fā)送安裝消息, 自動(dòng)安裝.
/**
* 初始化app更新廣播
*/
private void initUpdata() {
IntentFilter filter = new IntentFilter();
filter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
filter.addAction(DownloadManager.ACTION_NOTIFICATION_CLICKED);
filter.addCategory("android.intent.category.DEFAULT");
receiver = new DownLoadCompleteReceiver();
registerReceiver(receiver, filter);
}
/**
* Created by zzj on 2016/11/22.
*/
public class DownLoadCompleteReceiver 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, -1);
installApk(context, id);
} else if (intent.getAction().equals(DownloadManager.ACTION_NOTIFICATION_CLICKED)) {
}
}
/**
* 下載完后安裝apk
*
* @param
*/
// 安裝Apk
private void installApk(Context context, long downloadApkId) {
SharedPreferences sharedPreferences = context.getSharedPreferences("downloadapp", Activity.MODE_PRIVATE);
long id = sharedPreferences.getLong("downloadid", 0);
// 獲取存儲(chǔ)ID
if (downloadApkId == id) {
DownloadManager dManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadFileUri = dManager.getUriForDownloadedFile(downloadApkId);
if (downloadFileUri != null) {
Intent install = new Intent(Intent.ACTION_VIEW);
File apkFile = context.getExternalFilesDir("Download/downapp");
//對Android 版本判斷
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// context.getPackageName() + ".fileprovider" 是配置中的authorities
Uri contentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", apkFile);
install.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
install.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
}
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(install);
} else {
Toasts.show(context,"下載失敗");
}
}
}
}
四:7.0以上的共享文件權(quán)限配置
1. 在manifest文件中添加 <application/>中
<provider
android:authorities="${applicationId}.fileprovider"
android:name="android.support.v4.content.FileProvider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths"/>
</provider>
注意:
authorities:app的包名.fileProvider
grantUriPermissions:必須是true,表示授予 URI 臨時(shí)訪問權(quán)限
exported:必須是false
resource:中的@xml/file_paths是我們接下來要添加的文件
2.在res目錄下新建一個(gè)xml文件夾都弹,并且新建一個(gè)file_paths的xml文件
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path path="Android/data/app的包名/" name="files_root" />
<external-path path="." name="external_storage_root" />
</paths>
path:需要臨時(shí)授權(quán)訪問的路徑(.代表所有路徑)
name:就是你給這個(gè)訪問路徑起個(gè)名字