@ionic-native/zip不能在API 31上工作,打开失败:EACCES(拒绝权限) &g



我正在做一个遗留的ionic-cordova项目,在API级别31上运行我的android应用程序(最近升级)。我有android:requestLegacyExternalStorage="true"和权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

在我的AndroidManifest.xml文件。还检查了我的权限与'cordova-plugin-android-permissions'和'cordova-diagnostic-plugin'为'READ_EXTERNAL_STORAGE' &'WRITE_EXTERNAL_STORAGE'权限得到granted: true

但我仍然不能使用'cordova-plugin-zip',由于EACCES (Permission denied)

这是我在Android Studio上得到的错误:

2023-01-11 13:06:36.328 14977-22760/es.my-app.my-app E/Zip: An error occurred while unzipping.
java.io.FileNotFoundException: /storage/emulated/0/Download/some-file.KMZ: open failed: EACCES (Permission denied)
at libcore.io.IoBridge.open(IoBridge.java:492)
at java.io.FileInputStream.<init>(FileInputStream.java:160)
at java.io.FileInputStream.<init>(FileInputStream.java:115)
at org.apache.cordova.CordovaResourceApi.openForRead(CordovaResourceApi.java:250)
at org.apache.cordova.CordovaResourceApi.openForRead(CordovaResourceApi.java:233)
at org.apache.cordova.Zip.unzipSync(Zip.java:84)
at org.apache.cordova.Zip.access$000(Zip.java:23)
at org.apache.cordova.Zip$1.run(Zip.java:39)

预览更新,Zip.unzip方法从'@ionic-native/zip'过去可以很好地解压缩我的。kmz文件,但现在它抛出一个错误:-1由于权限拒绝,而试图从外部存储读取。

最后,我想出了一个OK的解决方案,从API 31开始,完全访问外部存储有一个特定的权限:'MANAGE_EXTERNAL_STORAGE',为了注册我的应用程序获得该权限,首先我必须将其添加到'config.xml'文件中,如下所述:

<widget xmlns:android="http://schemas.android.com/apk/res/android">
<platform name="android">
...
<config-file parent="/manifest" target="AndroidManifest.xml">
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
</config-file>
...
</platform>
</widget>

在widget标签处添加xmlns:android="http://schemas.android.com/apk/res/android"是很重要的。

然后请求'MANAGE_EXTERNAL_STORAGE'权限,我修改了android studio上插件的.java文件,如下所示:

...
public class FileChooser extends CordovaPlugin {
@Override
public boolean execute(String action, JSONArray inputs, CallbackContext callbackContext) throws JSONException {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R && !android.os.Environment.isExternalStorageManager()) {
try {
Intent intent = new Intent();
intent.setAction(android.provider.Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
Uri uri = Uri.fromParts("package", cordova.getContext().getPackageName(), null);
intent.setData(uri);
cordova.getActivity().startActivity(intent);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(android.provider.Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
cordova.getActivity().startActivity(intent);
}
}
.... plugin code ...
}
}

execute函数是插件执行的起点,在那里,我添加了在执行其余插件进程之前请求权限的代码…

注意:android的'MANAGE_EXTERNAL_STORAGE'权限可能会使你的应用程序很难在play store上发布,有其他更复杂的策略来访问外部存储,这不会造成麻烦。

相关内容

最新更新