使用适用于 Android 13 的 Cordova 12 在 AndroidManifest 中复制 WRITE_EXTERNAL_STORAGE 权限

问题描述 投票:0回答:1

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

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

两个插件都会在 AndroidManifest.xml 中插入权限。升级到 Cordova 12 并将 targetSdk 设置为 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

以下是 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>

以下是 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" />

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

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" />

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

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

手动删除捕获插件条目确实可以让构建成功完成。但是,我不确定结果在功能上是否正确。

问题:这是清单合并代码中的错误,还是有解决方法来避免冲突并保持功能相同?

cordova android-manifest android-permissions cordova-plugin-camera
1个回答
0
投票

问题:这是清单合并代码中的错误,还是有解决方法来避免冲突并保持功能相同?

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

什么是 bug,事实上 Cordova 的 <edit-config>

/
<config-file>
 指令会导致最终结果中的冲突和/或重复指令,这已经是一个 bug 好几年了。

但是可以使用钩子来纠正项目

after_prepare


使用脚本在

stripExtraWriteExternalStoragePerm.js

 目录中添加 
hooks/
 文件:

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);
在您的

config.xml

中添加:

<widget ...> ... <platform name="android"> ... <hook type="after_prepare" src="hooks/stripExtraWritePerm.js" /> </platform> </widget>
如果您已经有一个适用于 Android 的 

<platform>

 块,那么您应该将其添加到现有的 
<platform>
 块中。

正如 JS 注释所述,任何插件组合都可能会发生冲突,具体取决于它们如何声明

WRITE_EXTERNAL_STORAGE

(例如,有或没有 
maxSDKVersion
 属性,或者指定了不同的 
maxSDKVersion
 属性)。如果是这种情况,您可能需要为您的项目添加额外的 
manifest = manifest.replace(...)
 行。

我最初为工作编写了钩子脚本,因此该代码是在 Apache 许可证下获得 Total Pave Inc. 的版权发布的:

https://gist.github.com/breautek/bd157b8598f9a816f2ec0d45e3d932c8

© www.soinside.com 2019 - 2024. All rights reserved.