升级Ionic7/Angular16/Capacitor5后相机无法打开报错求助
问题描述
我开发了一款基于Ionic、Angular和Capacitor的应用,近期升级至Ionic 7、Angular 16和Capacitor 5版本,针对API 33构建安装包。升级后打开相机时无法启动,抛出如下异常:
Unable to create photo on disk java.lang.IllegalArgumentException: Couldn't find meta-data for provider with authority AppID.fileprovider at androidx.core.content.FileProvider.getFileProviderPathsMetaData(FileProvider.java:664) at androidx.core.content.FileProvider.parsePathStrategy(FileProvider.java:695) at androidx.core.content.FileProvider.getPathStrategy(FileProvider.java:645) at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:449) at com.capacitorjs.plugins.camera.CameraPlugin.openCamera(CameraPlugin.java:304) at com.capacitorjs.plugins.camera.CameraPlugin.showCamera(CameraPlugin.java:175) at com.capacitorjs.plugins.camera.CameraPlugin.doShow(CameraPlugin.java:135) at com.capacitorjs.plugins.camera.CameraPlugin.getPhoto(CameraPlugin.java:113) at java.lang.reflect.Method.invoke(Native Method) at com.getcapacitor.PluginHandle.invoke(PluginHandle.java:138) at com.getcapacitor.Bridge.lambda$callPluginMethod$0(Bridge.java:774) at com.getcapacitor.Bridge.$r8$lambda$ehFTi5f4HhVNFKTbCKAYDkpQYRA(Unknown Source:0) at com.getcapacitor.Bridge$$ExternalSyntheticLambda3.run(Unknown Source:8) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:236) at android.os.HandlerThread.run(HandlerThread.java:67)
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" > <uses-sdk tools:overrideLibrary="com.google.zxing.client.android" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove"/> <uses-feature android:name="android.hardware.bluetooth" android:required="true" /> <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" /> <uses-feature android:name="android.hardware.camera" android:required="false" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" > <activity android:name="AppID.MainActivity" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:exported="true" android:label="@string/title_activity_main" android:launchMode="singleTask" android:theme="@style/AppTheme.NoActionBarLaunch"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.file-provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application>
项目信息
Ionic CLI : 7.1.1 Ionic Framework : @ionic/angular 7.0.14 @angular-devkit/build-angular : 16.1.0 @angular-devkit/schematics : 16.1.0 @angular/cli : 16.1.0 @ionic/angular-toolkit : 9.0.0 Capacitor: Capacitor CLI : 5.1.0 @capacitor/android : 5.1.0 @capacitor/core : 5.1.0 @capacitor/ios : 5.1.0 NodeJS : v18.10.0 npm : 8.19.2 Android Studio Flamingo | 2022.2.1 Patch 2 Java 17 Gradle 8.0.0
问题原因分析
异常核心提示是找不到AppID.fileprovider这个权限对应的FileProvider元数据,而你的AndroidManifest.xml中配置的FileProvider权限是${applicationId}.file-provider(带连字符),两者格式不匹配。Capacitor 5的Camera插件默认使用的权限格式为${applicationId}.fileprovider(无连字符),导致插件无法匹配到正确的FileProvider配置。
解决方案
方案一:修改AndroidManifest中的权限格式
将provider标签的android:authorities值改为无连字符的格式,和插件默认期望一致:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
方案二:在Capacitor配置中指定自定义权限
如果不想修改AndroidManifest.xml,可以在capacitor.config.ts中配置Camera插件使用你当前的权限:
import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { appId: '你的AppID', appName: '你的AppName', webDir: 'www', bundledWebRuntime: false, plugins: { Camera: { fileProviderAuthority: '${applicationId}.file-provider' } } }; export default config;
额外检查项
确保android/app/src/main/res/xml/file_paths.xml文件存在,若不存在则创建,内容参考如下:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="my_images" path="Pictures" /> <external-files-path name="my_files" path="Files" /> </paths>
最后执行构建命令
修改完成后,清理缓存并重新同步构建:
cd android ./gradlew clean cd .. ionic cap sync android ionic cap build android
内容的提问来源于stack exchange,提问作者Jitendera Kumar
相关产品推荐
相关产品推荐

