Android NDK Fopen返回错误2“没有此类文件或目录”在文件上我知道退出

发布于 2025-01-26 14:56:11 字数 1918 浏览 2 评论 0原文

我的应用程序正在访问音频文件,我正在双簧管对它们进行一些处理。因此,我有JNI工作,文件位于我的文档树中。所有零件都在那里,通常我将文件加载到字节数组中,并将其传递到JNI上进行处理。

现在,我想直接在本机代码中打开一个文件。

从本质上讲,在Java侧,我正在用onActivityResult进行以下操作,该由action_open_document intent触发。

AudioUri = data.getData();
String filepath = AudioUri.getPath();

因此,filepath正在JNI方法中作为JString传递。在C ++方面,我正在执行以下

    JNIEXPORT void JNICALL
Java_com_myco_fileload_MainActivity_setFilepathNative(JNIEnv *env, jobject thiz,
                                                         jstring filepath) {

    std::string file_path = ConvertJString( env, filepath );

    __android_log_print(ANDROID_LOG_INFO, TAG,  "%s", file_path.c_str());

    FILE* file = fopen(file_path.c_str(),"rb");
    if(file){
        __android_log_print(ANDROID_LOG_INFO, TAG,  "%s", "it's a file");
    } else {
        __android_log_print(ANDROID_LOG_INFO, TAG,  "%s", "it's null");
        __android_log_print(ANDROID_LOG_INFO, TAG,  "%d", errno);
        __android_log_print(ANDROID_LOG_INFO, TAG,  "%s", strerror(errno));
    }
}

fopen()始终导致错误代码2-'no这样的文件或目录'

filepath is /document/document/document/主题:Documents/MyFolder/MyFile.wav

这是什么问题?那是错误的道路吗?权限错误?有什么想法吗?

编辑#1 我发现,如果将filepath更改为/storage/emulation/0/documents/myfolder/myfile.wav error conformcode 13会更改,则拒绝了权限。

所以我的问题是现在w我得到正确的文件路径吗?

为什么我会拒绝阅读与Java一起阅读的本机的文件的许可?

顺便说一句,我的清单包含用户权限

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

编辑#2 事实证明这是文件权限问题。我必须将权限设置为action_manage_all_files_access_permission,这对我的用例很好,但似乎有点过大。

因此,我现在的问题是 - 如何将本机代码提供给我应用程序的Java侧的权限?

My app is accessing audio files and I'm doing some processing on them in OBOE. So I have JNI working, the files are located in my documents tree. All the parts are there and normally I'm loading the file into a byte array and passing it over the JNI for processing.

Now, I want to open a file directly in the Native code.

Essentially, on the Java side, I'm doing the following in an onActivityResult which is triggered by an ACTION_OPEN_DOCUMENT intent.

AudioUri = data.getData();
String filepath = AudioUri.getPath();

So filepath is being passed as a jstring in the JNI method. On the C++ side I'm doing the following

    JNIEXPORT void JNICALL
Java_com_myco_fileload_MainActivity_setFilepathNative(JNIEnv *env, jobject thiz,
                                                         jstring filepath) {

    std::string file_path = ConvertJString( env, filepath );

    __android_log_print(ANDROID_LOG_INFO, TAG,  "%s", file_path.c_str());

    FILE* file = fopen(file_path.c_str(),"rb");
    if(file){
        __android_log_print(ANDROID_LOG_INFO, TAG,  "%s", "it's a file");
    } else {
        __android_log_print(ANDROID_LOG_INFO, TAG,  "%s", "it's null");
        __android_log_print(ANDROID_LOG_INFO, TAG,  "%d", errno);
        __android_log_print(ANDROID_LOG_INFO, TAG,  "%s", strerror(errno));
    }
}

fopen() always results in null with errorcode 2 - 'No such file or directory'

filepath is /document/primary:Documents/myFolder/myfile.wav

So what is the issue? Is that the path is wrong? A permission error? Any thoughts?

edit #1
I found that if I change the filepath to /storage/emulated/0/Documents/myFolder/myfile.wav the error changes to errorcode 13, Permission Denied.

So my question is now w do I get the correct file path?

And why would I get permission denied on reading a file with Native that I can read with Java?

btw, my manifest contained the user permissions

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

edit #2 It turns out this was a file permissions issue. I had to set permission to ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION, which is fine for my use case, but seems a bit excessive.

So, my question is now - how can I give the native code the permissions that are available to the java-side of my app?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮萍、无处依 2025-02-02 14:56:11

好吧,action_open_document返回content://getPath()它仅对相应的内容提供商有效(其“权限” )。因此,您只能通过内容解析器接口访问它。

我假设您是通过 ContentResolver#OpenFiledScriptor 以及在Java中进行操作。您应该做的是从parcelfiledScriptor获得文件描述符( parcelfiledScriptor#getfd() )并将其传递给NDK,您可以像其他任何文件描述符一样在其中操作。但是,您应该照顾文件描述符的寿命。

Well, ACTION_OPEN_DOCUMENT returns a content:// and the getPath() on it is only valid for the respective content provider (its "authority"). So you can only access it through the content resolver interface.

I'd assume you're opening a file descriptor through ContentResolver#openFileDescriptor and the operating on it in Java. What you should do is get the file descriptor from the ParcelFileDescriptor (ParcelFileDescriptor#getFd()) and pass it on to NDK where you can operate on it like any other file descriptor. Just an FYI you should take care of the life time of the file descriptor however.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文