看我如何解决“包解析错误”问题

您所在的位置:网站首页 安卓apk解析软件包时出现问题 看我如何解决“包解析错误”问题

看我如何解决“包解析错误”问题

2023-09-09 01:06| 来源: 网络整理| 查看: 265

项目中遇到了安装APP时,出现“包解析错误”错误,日志中也没有明显的fatal信息,应该是系统报错信息。

Android开发吗,抓日志是必备的技能,没有错误日志,那就抓了全量的logcat日志,开始疯狂的看日志,发现一个错误。

Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{ca55219 13782:com.android.packageinstaller/u0a32} (pid=13782, uid=10032) that is not exported from UID 10076

哈哈哈,有错误日志,就可以搜了,解决问题近在眼前。日志上面显示没有权限,然后我检查了下代码,网上说,除了要加Intent.FLAG_GRANT_READ_URI_PERMISSION 还要加上Intent.FLAG_GRANT_WRITE_URI_PERMISSION,其实仔细想想,我这只是简单的安装个App,没有写数据啊,为了怕前人留的坑,还是加了这个权限,运行程序,果然是没有用,还是需要继续。

我在想是不是FileProvider的权限问题,检测下FileProvider是否给与权限了,配置如下

从配置文件看,该给的权限都给了,是不是filepaths指的路径问题,于是检测了下filepaths配置文件,

简单的说下这个配置文件,每个字段代表的意义。

path:需要临时授权访问的路径(.代表所有路径) name:就是你给这个访问路径起个名字

那么标签external-path是什么意思呢? 代表外部存储,具体的如下:

//代表设备的根目录new File("/"); //context.getFilesDir() //context.getCacheDir() //Environment.getExternalStorageDirectory() //context.getExternalFilesDirs() //getExternalCacheDirs()

既然了解了,我指定的也是没有毛病啊,但是还是不行,我重新看了下报错信息,发现报错信息中有

that is not exported

是不是在provider中exported的参数设置问题,感觉找到了希望,我急忙去改这个参数,运行程序,噢噢,直接崩溃了。这是什么鬼。看下日志:

java.lang.SecurityException: Provider must not be exported

大概的意思就是不能设置为exported为true,看来问题还是没有找到。

我重新梳理下,安装APP的适配问题,fileprovider适配其实分三个阶段,

分6.0之前,7.0和7.0之后,也就说在7.0之前根本不需要使用FileProvider, 在6.0之前直接使用

Intent intent = new Intent(Intent.ACTION_VIEW); Uri.fromFile(new File(installPath) intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent);

就可以了,但是到了7.0,Google改变了策略,就需要使用FileProvider,

Intent intent = new Intent(); Uri uri = null; uri = FileProvider.getUriForFile(context, context.getPackageName()+".fileprovider", new File(filesPath)); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Intent.ACTION_VIEW);

authorities:app的包名.fileProvider

grantUriPermissions:必须是true,表示授予 URI 临时访问权限

exported:必须是false 否则会报上面的错误

resource:中的@xml/file_paths是我们接下来要添加的文件,具体怎么写,可以参考上面的写法

在8.0及8.0以上的Google又做了改变,我靠。安装APP时,还需要将APP拷贝到context.getFilesDir()这个目录下,但是仍然需要fileprovider,代码如下:

Intent intent = new Intent(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addCategory("android.intent.category.DEFAULT"); Uri contentUri = FileProvider.getUriForFile(context, "com.iflytek.appstroe2.fileprovider", new File(dstPath)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(contentUri, context.getContentResolver().getType(contentUri)); List resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo : resInfoList) { context.grantUriPermission(resolveInfo.activityInfo.packageName, contentUri,Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); } context.startActivity(intent);

到此算是梳理清楚了,但是我问题还是没有解决。我看了下我的系统版本,发现尼玛是Android8.0的,但是我一直在搞Android7.0的,我按照Android 8.0的方法试了下,发现可以了。

总结: 从解决这个的问题过程可以看出,即使一个小问题,在毫无方案的情况下,还是需要回归到问题的本质,这样才能才能有针对性的给出方案。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3