android 7.0 download and install apk遇到的问题
2017-01-17 17:08
288 查看
android 7.0 download and install apk遇到的问题
背景:还有十天过年,哈哈,今年的成就就是四川移动项目了。不过,最近android7.0出来以后,同事反馈,他的华为mate9,在下载完更新包以后,无法进入到安装流程,这这这。。。这是什么情况,于是进入到了一天的埋头挖土环节。下面就将这天的经历记录下来,供解决问题的思路和参考。问题1:先说说下载过程,下载完成后,曾经出现过安装包解析错误的问题。
分析:安装包解析错误,一般原因有:
1,、intent配置有误(可以对照google官方intent参数配置,下面的例子也会给出);
2、下载的安装包缺失或者不完整(可以通过adb shell命令查看安装包是否正常);
3、下载到了错误的路径(安装包如果储存在internal中,会遇到安装包解析错误)。
解决方案:我这里出现安装包解析错误的原因是下载到了internal中(也就是context.getFilesDir()),解决方案就是将下载路径切换到external存储中。这里的external存储可以通过Context.getExternalxxx()和Enviroment.getExternalxxx()两种方式配置,区别在于:Context.getExternalxxx()是context当前app的外部存储,6.0以后不需要授予外部存储权限也能进行读写操作;而Enviroment.getExternalxxx()是整个操作系统环境的外部存储,6.0以后,进行读写操作需要授予外部存储权限。以下是异步下载任务的安装包文件创建过程代码片段:
public DownloadTask() { File tempPath = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "apk");//外部存储路径 if (!tempPath.exists()) {//创建目录 try { tempPath.mkdir(); } catch (Exception e) { e.printStackTrace(); } } File apkFile = new File(tempPath, "apk.apk");//外部存储路径下的apk文件 if (apkFile.exists()) {//防止文件过多 try { apkFile.delete(); } catch (Exception e) { e.printStackTrace(); } } }
问题2:上面的文件创建好以后,就是进入到下载过程,下载过程就是根据网络url将apk写入上述文件中,这里就不说明了,不清楚可以google。下面就来说说apk文件下载完毕后的安装,在安装的时候啊,7.0不能启动apk的安装页面。
分析:不行了,不行了,怎么就不行了呢,后来通过google和查询官方文档,找到原因。启动安装页面的思路通常是往intent里面传递action个、flags、uri等参数,然后通过startActivity(Intent)的方式。7.0以前和7.0以后这些参数的配置就不太一样了。
7.0以前,配置action:Intent.setAction(Intent.ACTION_VIEW);配置flags:Intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);配置uri:Intent.setDataAndType(Uri.fromFile(问题1中的apkFile),"application/vnd.android.package-archive")。
7.0以后,配置action:Intent.setAction(Intent.ACTION_INSTALL_PACKAGE);配置flags:Intent.setFlags(Intent.FLAG_GRANT_URI_PERMISSION);配置uri:Intent.setDataAndType(FileProvider.getUriForFile(context, "manifest中的provider,下面的例子会讲到",
问题1中的apkFile),"application/vnd.android.package-archive")。
解决方案:android7.0以前,下面的例子涉及较少,不过完全够用,这里重点讲android7.0以后,正确启动apk安装页面的3个姿势,姿势不对,可能无法安装可能抛出如FileUriExposedException的异常(所有的姿势,都是依据google android7.0新玩儿法api:7.0Changes 和 FileProvider)。
1、在工程的res目录下,创建xml目录,并在xml目录中,创建file_paths.xml文件:作用是存放uri需要提供的文件信息。
<?xml version="1.0" encoding="utf-8"?> <paths> <external-files-path //对应的是Context.getExternalCacheDir() name="apk" //名字,传递给uri的,可以随意 path="Download/apk/" //文件路径,填写上面问题1中的tempPath路径 /> </paths>
2、在manifest的application中,创建android.support.v4.content.FileProvider:作用是以provider的形式,提供uri所需的apk文件信息。
<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.xxx.xxx.fileprovider"<!--com.xxx.xxx为项目包名--> android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>3、启动apk安装页面。
Intent intent = new Intent(); Uri uri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//7.0启动姿势
//com.xxx.xxx.fileprovider为上述manifest中provider所配置相同;apkFile为问题1中的外部存储apk文件uri = FileProvider.getUriForFile(context, "com.xxx.xxx.fileprovider", apkFile);
intent.setAction(Intent.ACTION_INSTALL_PACKAGE); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//7.0以后,系统要求授予临时uri读取权限,安装完毕以后,系统会自动收回权限,次过程没有用户交互} else {//7.0以下启动姿势 uri = Uri.fromFile(apkFile); intent.setAction(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);}intent.setDataAndType(uri,
"application/vnd.android.package-archive");context.startActivity(intent);
当然,详细的姿势,可以参考google官网。
相关文章推荐
- android 7.0 download and install apk遇到的问题
- android apk包在android 2.3以下系统上安装时遇到的INSTALL_FAILED_DEXOPT和LinearAlloc exceeded capacity问题解决方法
- 开发中碰到的问题:Android 7.0 更新APK在安装时的报错 android.os.FileUriExposedException: file:///storage/emulated/0/And
- android 开发遇到的问题 :Installation error: INSTALL_FAILED_INSUFFICIENT_STORAGE
- Download and Install AndroidSDK in Ubuntu 12.04 (Precise Pangolin)
- 异常处理系列:Android开发问题:Failed to install Hello.apk on device 'emulator-5554!
- [Android]使用 Eclipse 给 APK 签名时遇到的两个问题及解决办法
- android安装apk的时候遇到INSTALL_PARSE_FAILED_MANIFEST_MALFORMED
- 尝试使用Androidfby反编译APK生成文件时遇到的问题
- android集成apk到系统中常遇到的一些问题
- Android工程导入外部jar包时遇到的问题自动生成APK文件
- eclair的源码下编译的apk装到其他的版本的系统上遇到INSTALL_FAILED_OLDER_SDK的问题
- HOWTO install and setup Android NDK for Linux(Android NDK安装遇到的问题和解决方法)
- android打包apk时混淆遇到的问题
- Android apk上各大分发市场遇到的一谢问题
- 解决下载Android源码时遇到的问题 DownloadError: android.googlesource.com:
- 对Android中的apk文件进行数字签名及版本更新时遇到apk签名问题
- Android系统移植与调试之------->安装apk时出现错误Failure [INSTALL_FAILED_DEXOPT]问题解决的方法
- 【Android】使用 Eclipse 给 APK 签名时遇到的两个问题及解决办法
- mac 下装cocoapods时遇到的问题:please install libyaml and reinstall your ruby