您的位置:首页 > 移动开发 > Android开发

Android 下载apk提示更新以及解决Android 6.0 Marshmallow提示更新报错问题

2016-11-08 18:37 507 查看
下载并安装apk的方法很多,但是谷歌还是建议我们采用DownloadManager。

下载更新的代码比较简单,分如下几块:

启动下载
public long startDownload(String uri, String title, String description) {
DownloadManager.Request req = new DownloadManager.Request(Uri.parse(uri));

req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
//req.setAllowedOverRoaming(false);

req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

//设置文件的保存的位置[三种方式]
//第一种
//file:///storage/emulated/0/Android/data/your-package/files/Download/update.apk
req.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, "update.apk");
//第二种
//file:///storage/emulated/0/Download/update.apk
//req.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "update.apk");
//第三种 自定义文件路径
//req.setDestinationUri()

// 设置一些基本显示信息
req.setTitle(title);
req.setDescription(description);
//req.setMimeType("application/vnd.android.package-archive");

return dm.enqueue(req);
}


然后是监听下载完成的Receive
public class ApkInstallReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
long downloadApkId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
long id = PrefUtils.getDownloadId();
if (downloadApkId == id) {
installApk(context, downloadApkId);
}
}
}

private  void installApk(Context context, long downloadApkId) {
Intent install = new Intent(Intent.ACTION_VIEW);
DownloadManager dManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadFileUri = dManager.getUriForDownloadedFile(downloadApkId);
if (downloadFileUri != null) {
Log.d("DownloadManager", downloadFileUri.toString());
install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive");
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(install);
} else {
Log.e("DownloadManager", "下载失败");
}

}


上面的做法在Android 6.0 Marshmallow 系统之前是没有问题的,但是在6.0之后,会报错,倒是应用直接挂掉;报错LOG如下:
Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=content: typ=application/vnd.android.package-archive flg=0x10000000 }


经过查看Uri的值,发现6.0与之前的不一样

6.0的downloadFileUri 值为: content://downloads/my_downloads/10 

6.0之前的downloadFileUri 值为:file:///storage/emulated/0/Android/data/com.chiclam.download/files/Download/update-2.apk

完整的解决写法:
private  void installApk(Context context, long downloadApkId) {

DownloadManager dManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadApkId);
Cursor c = dManager.query(query);
if(c != null) {
if (c.moveToFirst()) {
int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
String downloadFileUrl = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
startInstall(context, Uri.parse(downloadFileUrl));
}
}
c.close();
}
}

private boolean startInstall(Context context, Uri uri) {
if(!new File( uri.getPath()).exists()) {
System.out.println( " local file has been deleted! ");
return false;
}
Intent intent = new Intent();
intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction( Intent.ACTION_VIEW);
intent.setDataAndType( uri, "application/vnd.android.package-archive");
context.startActivity( intent);
return true;
}


这样便完美解决了6.0上自动启动更新界面BUG
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: