下载并安装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

经过在谷歌上搜索,终于有了解决办法。一下就是解决路径http://stackoverflow.com/questions/33315849/android-6-get-path-to-downloaded-file

完整的解决写法:

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;

更多相关文章

  1. Android文件解压工具类
  2. android apk dex odex jar 等文件的 反编译工具
  3. 【转】android编译系统的makefile文件Android.mk写法
  4. Android+JNI调用–文件操作
  5. Android错误处理——Android读取txt文件乱码解决方案
  6. Android 10 创建文件失败
  7. 关于android中的各种路径对应的方法
  8. Android_判断文件是否存在并创建代码
  9. Android 项目打包成apk文件

随机推荐

  1. 刷爆全网的动态条形图,原来5行Python代码
  2. 新一代Notebook神器出现,Jupyter危险了!
  3. 总结一些网站加密和混淆技术
  4. 爱了!安利一个相见恨晚的可视化学习网站
  5. 今天网站都变成灰色了,这其中是怎么实现的
  6. JavaScript 逆向爬取实战
  7. 用Echarts打造一个轮播图!
  8. 做动态图表,没有数据?用Python就能获取!
  9. 看完这篇文章,我彻底爱上了Python动态图表
  10. NBA投篮数据可视化,4行代码就能实现!