Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Cant get the correct filepath from FileDialog in Android
Forum Updated to NodeBB v4.3 + New Features

Cant get the correct filepath from FileDialog in Android

Scheduled Pinned Locked Moved Solved QML and Qt Quick
7 Posts 5 Posters 3.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Amanda1102
    wrote on last edited by Amanda1102
    #1

    I am using FileDialog with qt 5.13.1 to save a file in my application directory. The problem is that the path of the file does not contains the correct name of the file and I need it.

    Here is my qml code

    import QtQuick 2.12
    import QtQuick.Controls 2.12
    import QtQuick.Dialogs 1.2
    
    ApplicationWindow {
        id: mRoot
        visible: true
        width: 400
        height: 300
    
        Button{
            id: mButtonSaveFiles
    
            anchors.centerIn: parent
    
            height: 50
            width: 100
    
            text: "Save File"
    
            onClicked: mFileDialog.open()
        }
    
        FileDialog{
            id: mFileDialog
    
            nameFilters: ["Compressed files(*bz2)"]
    
            onAccepted: mFileManager.saveFile(mFileDialog.fileUrl)
        }
    }
    

    Here is my c++ function:

    
    bool FileManager::saveFile(QString fileUrl) {
      qDebug() << "File url:" << fileUrl;
    
      int start = fileUrl.indexOf(QDir::separator()) + 1;
      int length = fileUrl.length() - start;
      QString filename = fileUrl.mid(start, length);
    
      QFile file(fileUrl);
      if (!file.copy(m_dir.path() + QDir::separator() + filename))
        return false;
    
      return true;
    }
    

    It works just fine in desktop, but in android I am getting this fileUrl:
    "content://com.android.providers.downloads.documents/document/152"

    So my file is being saved as 152, but I need it to be saved with the original name.

    Does anyone know how I can get the correct name?

    1 Reply Last reply
    0
    • Quang PhuQ Offline
      Quang PhuQ Offline
      Quang Phu
      wrote on last edited by Quang Phu
      #2

      @Amanda1102 ,
      I use this config for 3 platforms:

      #ifdef ANDROID_PLATFORM
          m_currentDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
          qDebug() << "Android writable location ... " + QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
      #elif IOS_PLATFORM
          m_currentDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
      #else
          m_currentDir = QDir::currentPath();
      #endif
      

      It's worked well for both C++ and QML. You can try it!
      QFile file(m_currentDir + QDir::separator() + filename);

      1 Reply Last reply
      0
      • A Offline
        A Offline
        Amanda1102
        wrote on last edited by
        #3

        Thank you for your help @Quang-Phu, but that isn't my problem. The problem is that I have a file inside a android directory and I wanna save it inside my app directory, but I am not getting the correct name. For example, my filename is android-file, but I am getting 151 as the name. The thing is that it is using a uri link and I need to get the name of the file based on the uri.

        jsulmJ 1 Reply Last reply
        0
        • A Amanda1102

          Thank you for your help @Quang-Phu, but that isn't my problem. The problem is that I have a file inside a android directory and I wanna save it inside my app directory, but I am not getting the correct name. For example, my filename is android-file, but I am getting 151 as the name. The thing is that it is using a uri link and I need to get the name of the file based on the uri.

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Amanda1102 said in FileDialog in Android:

          and I wanna save it inside my app directory

          I don't think your app has write access in the directory where it is installed. Why do you want to write there?

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • A Offline
            A Offline
            Amanda1102
            wrote on last edited by
            #5

            I did solve the problem partially by creating a java class and calling it from c++. Unfortunally this doesn't work with OneDrive.

            Here is the java code I found in the internet:

            package br.com.myjavapackage;
            
            import android.content.Context;
            import android.database.Cursor;
            import android.net.Uri;
            import android.webkit.MimeTypeMap;
            import android.provider.OpenableColumns;
            
            public class PathUtil {
            
                public static String getFileName(Uri uri, Context context) {
                    String fileName = getFileNameFromCursor(uri, context);
            
                    if (fileName == null) {
                        String fileExtension = getFileExtension(uri, context);
                        fileName = "temp_file" + (fileExtension != null ? "." + 
                                                                    fileExtension : "");
                    } else if (!fileName.contains(".")) {
                        String fileExtension = getFileExtension(uri, context);
                        fileName = fileName + "." + fileExtension;
                    }
            
                    return fileName;
                }
            
                public static String getFileExtension(Uri uri, Context context) {
                    String fileType = context.getContentResolver().getType(uri);
                    return MimeTypeMap.getSingleton().getExtensionFromMimeType(fileType);
                }
            
                public static String getFileNameFromCursor(Uri uri, Context context) {
                    Cursor fileCursor = context.getContentResolver().query(uri, new String[] 
                                           {OpenableColumns.DISPLAY_NAME}, null, null, null);
                    String fileName = null;
                    if (fileCursor != null && fileCursor.moveToFirst()) {
                        int cIndex = fileCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                        if (cIndex != -1) {
                            fileName = fileCursor.getString(cIndex);
                        }
                    }
                    return fileName;
                }
            }
            

            Here is the way I call it on my c++ function:

              QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod(
                  "android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;",
                  QAndroidJniObject::fromString(fileUrl).object<jstring>());
            
              QString filename =
                  QAndroidJniObject::callStaticObjectMethod(
                      "br/com/myjavapackage/PathUtil", "getFileName",
                      "(Landroid/net/Uri;Landroid/content/Context;)Ljava/lang/String;",
                      uri.object(), QtAndroid::androidContext().object())
                      .toString();
            

            I am marking this problem as solved, but if anyone find a better solution please share it!

            ekkescornerE 1 Reply Last reply
            1
            • A Amanda1102

              I did solve the problem partially by creating a java class and calling it from c++. Unfortunally this doesn't work with OneDrive.

              Here is the java code I found in the internet:

              package br.com.myjavapackage;
              
              import android.content.Context;
              import android.database.Cursor;
              import android.net.Uri;
              import android.webkit.MimeTypeMap;
              import android.provider.OpenableColumns;
              
              public class PathUtil {
              
                  public static String getFileName(Uri uri, Context context) {
                      String fileName = getFileNameFromCursor(uri, context);
              
                      if (fileName == null) {
                          String fileExtension = getFileExtension(uri, context);
                          fileName = "temp_file" + (fileExtension != null ? "." + 
                                                                      fileExtension : "");
                      } else if (!fileName.contains(".")) {
                          String fileExtension = getFileExtension(uri, context);
                          fileName = fileName + "." + fileExtension;
                      }
              
                      return fileName;
                  }
              
                  public static String getFileExtension(Uri uri, Context context) {
                      String fileType = context.getContentResolver().getType(uri);
                      return MimeTypeMap.getSingleton().getExtensionFromMimeType(fileType);
                  }
              
                  public static String getFileNameFromCursor(Uri uri, Context context) {
                      Cursor fileCursor = context.getContentResolver().query(uri, new String[] 
                                             {OpenableColumns.DISPLAY_NAME}, null, null, null);
                      String fileName = null;
                      if (fileCursor != null && fileCursor.moveToFirst()) {
                          int cIndex = fileCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                          if (cIndex != -1) {
                              fileName = fileCursor.getString(cIndex);
                          }
                      }
                      return fileName;
                  }
              }
              

              Here is the way I call it on my c++ function:

                QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod(
                    "android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;",
                    QAndroidJniObject::fromString(fileUrl).object<jstring>());
              
                QString filename =
                    QAndroidJniObject::callStaticObjectMethod(
                        "br/com/myjavapackage/PathUtil", "getFileName",
                        "(Landroid/net/Uri;Landroid/content/Context;)Ljava/lang/String;",
                        uri.object(), QtAndroid::androidContext().object())
                        .toString();
              

              I am marking this problem as solved, but if anyone find a better solution please share it!

              ekkescornerE Offline
              ekkescornerE Offline
              ekkescorner
              Qt Champions 2016
              wrote on last edited by
              #6

              @Amanda1102 perhaps you can get some ideas from my share example, where I try to get the file uri from a content uri
              https://github.com/ekke/ekkesSHAREexample/blob/master/android/src/org/ekkescorner/examples/sharex/QShareActivity.java
              https://github.com/ekke/ekkesSHAREexample/blob/master/android/src/org/ekkescorner/utils/QSharePathResolver.java
              don't know if it helps or if it works with OneDrive

              ekke ... Qt Champion 2016 | 2024 ... mobile business apps
              5.15 --> 6.9 https://t1p.de/ekkeChecklist
              QMake --> CMake https://t1p.de/ekkeCMakeMobileApps

              1 Reply Last reply
              1
              • W Offline
                W Offline
                wimalopaan
                wrote on last edited by
                #7

                Using java to solve this problem is very weird.

                Isn't there a true Qt/QML solution?

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved