@ionic-native/zip无法在API 31上运行,打开失败:EACCES(权限被拒绝)

vi4fp9gy  于 2023-02-01  发布在  Ionic
关注(0)|答案(1)|浏览(187)

我正在处理一个遗留的ionic-cordova项目,在API级别31(最近升级)上运行我的android应用程序。

<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'检查了我的"读取外部存储“和”写入外部存储“权限,并获得了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)

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

m2xkgtsf

m2xkgtsf1#

最后,我想出了一个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>

在窗口小部件标签处添加xmlns:android="http://schemas.android.com/apk/res/android"是很重要的。
然后,为了请求'管理_外部_存储'权限,我修改了Android studion上的插件的.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的较新scoped stotage限制,“MANAGE_EXTERNAL_STORAGE”权限可能会使您很难在Play Store上发布应用程序,还有其他更复杂的策略来访问外部存储,不会导致这种麻烦。

相关问题