gpt4 book ai didi

Duplicate WRITE_EXTERNAL_STORAGE permissions in AndroidManifest using Cordova 12 for Android 13(使用Cordova 12 for Android 13在androidManifest中复制WRITE_EXTERNAL_STORAGE权限)

转载 作者:bug小助手 更新时间:2023-10-26 21:10:18 49 4
gpt4 key购买 nike



Introducing app using Cordova 12 which requires target SDK Android 13 / API 33. My app depends on the following plugins (among many others)...

介绍使用Cordova 12的应用程序,这需要目标SDK Android 13/API 33。我的应用程序依赖于以下插件(以及其他许多插件)…


cordova-plugin-camera
cordova-plugin-media-capture

Both plugins insert permissions in AndroidManifest.xml. After upgrading to Cordova 12 and setting targetSdk to 33, the build fails trying to merge permissions...

这两个插件都在androidManifest.xml中插入权限。在升级到Cordova 12并将Target Sdk设置为33之后,内部版本尝试合并权限失败...


> Task :app:processReleaseMainManifest FAILED
/Users/jmelvin/dev/sizzlescene/repos/mobile/platforms/android/app/src/main/AndroidManifest.xml:47:5-108 Error:
Element uses-permission#android.permission.WRITE_EXTERNAL_STORAGE at AndroidManifest.xml:47:5-108 duplicated with element declared at AndroidManifest.xml:26:5-81

Here are the properties inserted by the cordova-plugin-camera plugin...

以下是由Cordova-plugin-Camera插件插入的属性...


11a12,14
> <provider android:authorities="${applicationId}.cordova.plugin.camera.provider" android:exported="false" android:grantUriPermissions="true" android:name="org.apache.cordova.camera.FileProvider">
> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/camera_provider_paths" />
> </provider>
22a26,41
> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
> <queries>
> <intent>
> <action android:name="android.media.action.IMAGE_CAPTURE" />
> </intent>
> <intent>
> <action android:name="android.intent.action.GET_CONTENT" />
> </intent>
> <intent>
> <action android:name="android.intent.action.PICK" />
> </intent>
> <intent>
> <action android:name="com.android.camera.action.CROP" />
> <data android:mimeType="image/*" android:scheme="content" />
> </intent>
> </queries>

Here are the properties added by cordova-plugin-media-capture plugin...

以下是Cordova-plugin-media-Capture插件添加的属性...


22a23,28
> <uses-permission android:name="android.permission.RECORD_AUDIO" />
> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
> <uses-permission android:maxSdkVersion="32" android:name="android.permission.READ_EXTERNAL_STORAGE" />
> <uses-permission android:maxSdkVersion="32" android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

And lastly, when both plugins are included in the build...

最后,当两个插件都包含在构建中时…


11a12,14
> <provider android:authorities="${applicationId}.cordova.plugin.camera.provider" android:exported="false" android:grantUriPermissions="true" android:name="org.apache.cordova.camera.FileProvider">
> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/camera_provider_paths" />
> </provider>
22a26,47
> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
> <queries>
> <intent>
> <action android:name="android.media.action.IMAGE_CAPTURE" />
> </intent>
> <intent>
> <action android:name="android.intent.action.GET_CONTENT" />
> </intent>
> <intent>
> <action android:name="android.intent.action.PICK" />
> </intent>
> <intent>
> <action android:name="com.android.camera.action.CROP" />
> <data android:mimeType="image/*" android:scheme="content" />
> </intent>
> </queries>
> <uses-permission android:name="android.permission.RECORD_AUDIO" />
> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
> <uses-permission android:maxSdkVersion="32" android:name="android.permission.READ_EXTERNAL_STORAGE" />
> <uses-permission android:maxSdkVersion="32" android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

The permission request for WRITE_EXTERNAL_STORAGE are not exactly the same. The media-capture comes with an SDK qualifier...

WRITE_EXTERNAL_STORAGE的权限请求不完全相同。媒体截图附带SDK限定符...


camera:  android:name="android.permission.WRITE_EXTERNAL_STORAGE"
capture: android:maxSdkVersion="32" android:name="android.permission.WRITE_EXTERNAL_STORAGE"

Manually removing the capture plugin entry does allow the build to complete successfully. However, I'm not sure the result is functionally correct.

手动删除捕获插件条目确实允许构建成功完成。然而,我不确定结果在功能上是正确的。


Question: is this a bug in the manifest merge code or are there workarounds to circumvent the collision and remain functionally the same?

问:这是清单合并代码中的错误,还是有解决方法可以绕过冲突并保持功能不变?


更多回答

Additional info... The cordova-plugin-media-capture plugin released a new version 5 some three weeks ago to add the minSdkVersion. See cordova.apache.org/news/2023/08/18/…

更多信息... cordova-plugin-media-capture插件在大约三周前发布了一个新的版本5,添加了minSdkVersion。见cordova.apache.org/news/2023/08/18/.

优秀答案推荐


Question: is this a bug in the manifest merge code or are there workarounds to circumvent the collision and remain functionally the same?



It's not a bug, normally when authoring native projects, if two libraries attempt to declare the same permission with different configurations, it will result similar error.

这不是一个错误,通常在编写本机项目时,如果两个库试图用不同的配置声明相同的权限,则会导致类似的错误。


What is a bug is the fact Cordova's <edit-config>/<config-file> directives will result in conflicts and/or duplicate directives in the end-result, which has been a bug for several years.

这是一个错误,Cordova的 / 指令将在最终结果中导致冲突和/或重复的指令,这是一个多年来一直存在的错误。


A hook however can be used to correct the project after_prepare

但是,可以在_Prepare之后使用挂钩来更正项目


Add stripExtraWriteExternalStoragePerm.js file in your hooks/ directory with the script:

使用以下脚本在您的hooks/目录中添加stripExtraWriteExternalStoragePerm.js文件:


const FS = require('fs');
const Path = require('path');

let path = Path.resolve('platforms/android/app/src/main/AndroidManifest.xml');

let manifest = FS.readFileSync(path, {
encoding: 'utf-8'
});

// Strips ALL occurrences of <uses-permission android:name="androoid.permission.WRITE_EXTERNAL_STORAGE" />
// If you have several conflicts (of different maxSDKVersion, or in different formats) then the regex
// may need to be adjusted, or repeated for each format.
manifest = manifest.replace(/^(\s)+<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" \/>$/gm, '');

FS.writeFileSync(path, manifest);

In your config.xml add:

在您的config.xml中添加:


<widget ...>
...
<platform name="android">
...
<hook type="after_prepare" src="hooks/stripExtraWriteExternalStoragePerm.js" />
</platform>
</widget>

If you already have a <platform> block for android, then you should add it to your existing <platform> block.

如果您已经有一个用于Android的 块,那么您应该将其添加到现有的 块中。


As the JS comment states, the conflict may occur with any combination of plugins, depending on how they declare WRITE_EXTERNAL_STORAGE (e.g. with or without the maxSDKVersion attribute, or with a different maxSDKVersion attribute specified). If that's the case, you may need to add additional manifest = manifest.replace(...) lines for your project.

正如JS注释所指出的,任何插件组合都可能发生冲突,这取决于它们如何声明WRITE_EXTERNAL_DATA(例如,使用或不使用maxSDKVersion属性,或者指定不同的maxSDKVersion属性)。如果是这种情况,您可能需要添加额外的manifest = manifest.replace(.)线为您的项目。


I originally wrote the hook script for work and so the code is released with the copyright of Total Pave Inc. licensed under the Apache License: https://gist.github.com/breautek/bd157b8598f9a816f2ec0d45e3d932c8

我最初为工作编写了钩子脚本,因此代码是在Total Pave Inc.的版权下发布的,许可使用的是Apache许可证:https://gist.github.com/breautek/bd157b8598f9a816f2ec0d45e3d932c8


更多回答

thanks for the great solution. I had implemented the post-prepare solution using sed script, but your approach is preferred and may apply to other workarounds we've implemented in the past.

谢谢你的绝妙解决方案。我已经使用sed脚本实现了准备后解决方案,但您的方法是首选的,并且可能适用于我们过去实现的其他解决方法。

49 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com