AndroidStudio:apk exposed beyond app through Intent.getData()

it2022-05-05  115

今天做app版本升级,发现下载好了之后无法自动安装,检查发现,APP已经下载到了本地,就是最后安装的时候捕捉到了异常,根据异常(apk exposed beyond app through Intent.getData())提示,发现是AndroidStudio7.0之后官方对这权限做了调整:官方解答:出于用户隐私安全考虑,谷歌——(对于面向 Android 7.0 的应用,Android 框架执行的 StrictMode API 政策禁止在您的应用外部公开 file://URI。传递软件包网域外的 file://URI 可能给接收器留下无法访问的路径。因此,尝试传递 file://URI会触发 FileUriExposedException。分享私有文件内容的推荐方法是使用 FileProvider。);根据网络上一众大佬的指导,我很快将需要添加的代码添加上了,以下是需要添加的代码:

(1)添加在Manifest中(你知道我为什么将Manifest斜体加下划线吗?)

<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" /> </provider> android:authorities="你的包名.provider" android:resource="@xml/provider_paths" (provider_paths新建的一个xml资源文件)

其他的不用修改!

(2) 在新建的资源文件中添加如下代码:

<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path path="Android/data/com.example.administrator.devicemanagerapp/" name="files_root" /> <external-path path="." name="external_storage_root" /> </paths>

这里选择external-path 是因为这个路径要和java代码中保持一致

(3)

以前的代码:以前的代码乱了。。。。就不在这放了

新代码:

File apkfile = new File(mSavePath, "DM.apk"); Intent intent = new Intent(Intent.ACTION_VIEW); if (!apkfile.exists()) { return; } //判断是否是AndroidN以及更高的版本 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { String ss = "com.example.administrator.devicemanagerapp" + ".fileprovider"; Uri contentUri = FileProvider.getUriForFile(context.getApplicationContext(), ss, apkfile); intent.setAction(Intent.ACTION_VIEW); intent.setDataAndType(contentUri, "application/vnd.android.package-archive"); } catch (Exception e) { e.printStackTrace(); } } else { intent.setDataAndType(Uri.fromFile(apkfile), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } try { context.startActivity(intent); } catch (Exception e) { e.printStackTrace(); }

一切都配置好了

然而···始终在报一个错:java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference——看了无数篇博客,最终原因定位在了:

要和这里

保持一致!!!我试了很多方法让他俩保持一致,他俩就是保持一致的啊。。。。但是问题yi然存在,接着在网上找,看到有个哥们评论,说provider要放在Application中,那我就试试吧 放到了Application中结果还是不行  报错:

Error:Execution failed for task ':app:processDebugManifest'. > Manifest merger failed with multiple errors, see logs

找到原因可能是申请权限的时候有重复的。。我就把权限一项一项 对比,果然有两个重复项(为毛以前没事。。。),然后不报那个错,但是在更新App版本的时候又报另外一个错:

Error:Execution failed for task ':app:processDebugManifest'. > Manifest merger failed : Attribute provider# android.support.v4.content.FileProvider@authorities value=(com.example.administrator.devicemanagerapp.provider) from AndroidManifest.xml:378:13-86 is also present at [com.jph.takephoto:takephoto_library:4.0.2] AndroidManifest.xml:19:13-64 value=(com.example.administrator.devicemanagerapp.fileprovider).     Suggestion: add 'tools:replace="android:authorities"' to <provider> element at AndroidManifest.xml:376:9-384:20 to override.

这两行··· 原来是App的Manifest和一个插件的Manifest中的上面说的authorities重复

无奈再修改自己的authority,最后可以运行了,

事后想到,其实后面的问题挺流畅的。就是前面,看了那么多篇博客,没有一篇讲Provider要放在Application中的。没有怪别人的意思。这里也是记录一下,给其他像我这样的小白一个帮助。


最新回复(0)