[Interest] Android-6 File Opening Permissions

Robert Iakobashvili coroberti at gmail.com
Thu Mar 23 18:23:57 CET 2017


Hello,

Qt-5.7, Nexus-7, Android-6, API 25 or 22.

1. Running Intent from Qt widget app to ask for a new file rather in a
standard way works properly:

QAndroidJniObject intent("android/content/Intent");
QAndroidJniObject ACTION_CREATE_DOCUMENT =
QAndroidJniObject::fromString("android.intent.action.CREATE_DOCUMENT");

        if (ACTION_CREATE_DOCUMENT.isValid() && intent.isValid())
        {
            intent.callObjectMethod("setAction",

"(Ljava/lang/String;)Landroid/content/Intent;",
                                    ACTION_CREATE_DOCUMENT.object<jstring>());
            intent.callObjectMethod("setType",

"(Ljava/lang/String;)Landroid/content/Intent;",

QAndroidJniObject::fromString("text/html").object<jstring>());
            intent.callObjectMethod("putExtra",

"(Ljava/lang/String;Z)Landroid/content/Intent;",

QAndroidJniObject::fromString("android.intent.extra.LOCAL_ONLY").object<jstring>(),
                                    jboolean(true));
            QtAndroid::startActivity(intent.object<jobject>(),

AndroidOpenFileReceiver::NEW_FILE_NAME_REQUEST,
                                     this->android_receiver_);
        }

2. File could be selected and seen as immediately created in a
derivative of a QAndroidActivityResultReceiver

handleActivityResult

const QString fileURI =
data.callObjectMethod("getData","()Landroid/net/Uri;").toString();

and that could be translated by calling Java to the absolute file path
for the file selected, i.e. first.htm:

/storage/emulated/0/Download/first.htm

3. The file content could be written or read in Java using Java I/O Streams.
Further the stream and file are closed in Java.

4. Unfortunately, returning to C++ the file is found existing, but open fails.
That happens in all cases consistently: whenever dealing with it in
Java before or not.

if (!QFile::exists(filename)) - it exists
        return false;

QFile file(filename);
if (!file.open(QFile::ReadWrite)) - fails
{
     if (!file.open(QFile::ReadOnly)) - fails.
            return false;
}

5. The C++ code above works fine if the location of the files is in
/data/data/<app-path>
    or any writable standard path returned by Qt.

6. My conclusion is that on Nexus-7 the Intent returned path in
/storage/emulated/0/Download/
    is considered to be an External Storage.

    But the manifest has appropriate Write and Read permissions for
External Storage.

The question is what I am missing like
permission for that specific thread or running something on the GUI
thread, or etc.

Thanks in advance for any help or ideas.

Kind regards,
Robert



More information about the Interest mailing list