最近用到了软件更新,感觉自己写更新比较麻烦,我这个人比较懒,能不自己写的绝对不自己写,必须自己写的,再找找看看能不能不写,想了一下还是使用系统自带的DownloadManager好了,但这个坑还是挺多的,还要搞兼容,现在来总结一下。
需要声明的权限,7.x之后的动态获取权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
一开始呢你的写一个类:
DownloadInfo(不是必须得叫这个名字,随便取),
接下来就开始撸,我注释写的比较清楚的,方便以后好看,好理解,之前大部分我都不写注释,写之前,只有我和电脑知道是干啥的,过段时间之后就只有电脑知道是干啥的了,问题是,电脑还不和我分享,这个就很气人,没办法。
public static void DownloadAPK(Context context,String url,String title,String detail){
//创建request对象
DownloadManager.Request request=new DownloadManager.Request(Uri.parse(url));
//设置什么网络情况下可以下载
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE);
//设置通知栏的标题
request.setTitle(title);
//设置通知栏的message
request.setDescription(detail);
//设置漫游状态下是否可以下载
request.setAllowedOverRoaming(false);
request.setVisibleInDownloadsUi(true);
//设置文件存放目录
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
request.setDestinationInExternalPublicDir(Environment.getExternalStorageDirectory().getAbsolutePath() , "dlysc.apk");
//获取系统服务
if (downloadManager==null) {
downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
}
//进行下载
DownLoadID = downloadManager.enqueue(request);
}
这部分是设置下载和启动下载的,其实这样就已经可以下载了,只是为了体验好一点呢,我们还得写一个监听,不对,人家给我们提供了方法的,
DownLoadCompleteReceiver
当然,给我们提供的不是这个类,这个只是我们的普通类,也是自己瞎起的名字,关键是继承:BroadcastReceiver这个类,这个类是一个抽象类,我们需要实现他的**onReceive()**方法:
@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);
Log.e("DownloadManager","下载完成啦!!!");
installApk(context,id);
} else if (intent.getAction().equals(DownloadManager.ACTION_NOTIFICATION_CLICKED)) {
//处理 如果还未完成下载,点击通知 ,跳转到下载中心
Intent viewDownloadIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
viewDownloadIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(viewDownloadIntent);
}
然后这样就可以实现监听了,下载完成后就可以提示了。
这个类写好了之后,别忘了去清单文件中(AndroidManifest.xml)的application中注册一下
:
<!--注册下载广播-->
<receiver android:name="net.archeryc.Powercloudmall.util.download.DownLoadCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
<action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED"/>
</intent-filter>
</receiver>
如果是文件,那么到这里就结束了,如果是APK的下载,那就还得安装:
private static void installApk(Context context, long downloadApkId) {
DownloadManager dManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
Intent install = new Intent(Intent.ACTION_VIEW);
Uri downloadFileUri = dManager.getUriForDownloadedFile(downloadApkId);
if (downloadFileUri != null) {
Log.e("DownloadManager", downloadFileUri.toString());
install.setDataAndType(downloadFileUri, "application/vnd.android.package-archive");
if ((Build.VERSION.SDK_INT >= 24)){
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
}
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (install.resolveActivity(context.getPackageManager()) != null) {
context.startActivity(install);
} else {
Log.e("DownloadManager","自动安装失败,请手动安装");
Toast.makeText(context, "下载完成,请点击下拉列表的通知手动安装", Toast.LENGTH_SHORT).show();
}
} else {
Log.e("DownloadManager", "download error");
}
}
到这就结束了,总结一下我遇到的坑:
1、文件可以下载,但是通知栏没反应,改写的都写了,结果还是没有,这就让我吐血了。
2、获取安装路径失败,我用的是:
c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));获取安装路径的,结果说已经淘汰了。
3、下载完成后,无法跳转到安装界面。
接下来解释一下我怎么解决的:
1、这个是因为自己没细心,代码写少了,忘了去清单文件中注册了。
2、我仔细想了想,我可以自定义路径的,就是说,我自己已经知道下载到那个文件夹了,就不用后去路径了,后去路径时还要兼容7.0前后版本,太难了,不过还好,系统给了我们一个方法,
DownloadManager dManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
Intent install = new Intent(Intent.ACTION_VIEW);
Uri downloadFileUri = dManager.getUriForDownloadedFile(downloadApkId);
这样,我们就可以轻松的获取到uri.
3、这个是没有添加权限,安装未知应用,以及允许该APP安装应用,上面写的有,我就不重复了。
奉上我的代码:
DownloadInfo
DownLoadCompleteReceiver