Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. QStandardPaths & Android
Forum Updated to NodeBB v4.3 + New Features

QStandardPaths & Android

Scheduled Pinned Locked Moved Solved Mobile and Embedded
7 Posts 3 Posters 4.0k 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.
  • J.HilkJ Online
    J.HilkJ Online
    J.Hilk
    Moderators
    wrote on last edited by
    #1

    Hell everyone,

    I have some trouble with crossplatform file management.

    In my app, I create a temporary pdf and I want to attach it to the native E-Mail programm.

    I'm using this code for the file location:

    QString filePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + name + "."+ extension;
    

    It works fine in Ios, but in Android this results in /data/user/0/myApp/cache/name.pdf, and I'm unable to attach the file to the E-Mail programm.
    If I use a fixed hardcoded path, lets say /sdcard/Download/name.pdf the file is attached properly.

    My guess is, that QStandardPaths::writableLocation(QStandardPaths::TempLocation) is not a readable location for external programms, under Android?

    Is there a StandardPath that would allow this ?


    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


    Q: What's that?
    A: It's blue light.
    Q: What does it do?
    A: It turns blue.

    1 Reply Last reply
    0
    • J.HilkJ Online
      J.HilkJ Online
      J.Hilk
      Moderators
      wrote on last edited by
      #7

      So I ended up with the following solution, because @VRonin link/example is really extensive and, so do I feel at least, overkill.

      void EmailPopup::showEmailPopup(QString receiver, QString extension)
      {
      #if defined(Q_OS_IOS)
          QString filePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + extension + "."+ extension;
          _impl->showEmail(receiver.toLatin1().data(), filePath.toLatin1().data());
      #elif defined(Q_OS_ANDROID)
          QtAndroid::requestPermissions(QStringList("android.permission.WRITE_EXTERNAL_STORAGE"), [this, receiver, extension](QtAndroid::PermissionResultMap resultHash){
              if(resultHash["android.permission.WRITE_EXTERNAL_STORAGE"] == QtAndroid::PermissionResult::Granted){
                  QString filePath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/" + extension + "."+ extension;
      
                  QAndroidJniObject javaFilenameStr = QAndroidJniObject::fromString(filePath);
                  QAndroidJniObject javaSendToStr = QAndroidJniObject::fromString(receiver);
      
                  QAndroidJniObject::callStaticMethod<void>("app/email/Mailer","sendMail","(Ljava/lang/String;Ljava/lang/String;)V", javaFilenameStr.object<jstring>(), javaSendToStr.object<jstring>());
              }else{
                  emit errorMessage(tr("Sending E-Mails with attachment requires permission to write"));
             }
          });
      
      
      #else
          Q_UNUSED(receiver)
          Q_UNUSED(extension)
      #endif
      }
      

      I decided to use QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) when on Android, thats a path, that allows all apps to access, but requires extra permission.

      If the user does not grand the permission he/she can not send the pdf file. But it's checked and requested each time he/she tries to send one. In case once mind changes.

      Works fine.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      1
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by
        #2

        This is actually explained in a blog post by @ekkescorner : http://blog.qt.io/blog/2017/12/01/sharing-files-android-ios-qt-app/

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        J.HilkJ 1 Reply Last reply
        3
        • VRoninV VRonin

          This is actually explained in a blog post by @ekkescorner : http://blog.qt.io/blog/2017/12/01/sharing-files-android-ios-qt-app/

          J.HilkJ Online
          J.HilkJ Online
          J.Hilk
          Moderators
          wrote on last edited by
          #3

          @VRonin thanks, I was not aware of that. Its a rather lengthly post, but I'll read through it.

          In the end, I could potentially simply create a folder at /sdcard/MyCompany/MyApp and call it a day. But that doesn't seem very future proof and it would at the very least require external read and write permission.

          And I'm hesitant to go that route.


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          jsulmJ 1 Reply Last reply
          0
          • J.HilkJ J.Hilk

            @VRonin thanks, I was not aware of that. Its a rather lengthly post, but I'll read through it.

            In the end, I could potentially simply create a folder at /sdcard/MyCompany/MyApp and call it a day. But that doesn't seem very future proof and it would at the very least require external read and write permission.

            And I'm hesitant to go that route.

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

            @J.Hilk Not all smartphones have a SDCard.

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

            J.HilkJ 1 Reply Last reply
            0
            • jsulmJ jsulm

              @J.Hilk Not all smartphones have a SDCard.

              J.HilkJ Online
              J.HilkJ Online
              J.Hilk
              Moderators
              wrote on last edited by
              #5

              @jsulm sofar all Android devices refer to the internal solid state memory as "sdcard", confused the hell out of me before too. => /sdcard/ has existed an all the devices I had since 2012


              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


              Q: What's that?
              A: It's blue light.
              Q: What does it do?
              A: It turns blue.

              jsulmJ 1 Reply Last reply
              0
              • J.HilkJ J.Hilk

                @jsulm sofar all Android devices refer to the internal solid state memory as "sdcard", confused the hell out of me before too. => /sdcard/ has existed an all the devices I had since 2012

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

                @J.Hilk OK, good to know

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

                1 Reply Last reply
                0
                • J.HilkJ Online
                  J.HilkJ Online
                  J.Hilk
                  Moderators
                  wrote on last edited by
                  #7

                  So I ended up with the following solution, because @VRonin link/example is really extensive and, so do I feel at least, overkill.

                  void EmailPopup::showEmailPopup(QString receiver, QString extension)
                  {
                  #if defined(Q_OS_IOS)
                      QString filePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + extension + "."+ extension;
                      _impl->showEmail(receiver.toLatin1().data(), filePath.toLatin1().data());
                  #elif defined(Q_OS_ANDROID)
                      QtAndroid::requestPermissions(QStringList("android.permission.WRITE_EXTERNAL_STORAGE"), [this, receiver, extension](QtAndroid::PermissionResultMap resultHash){
                          if(resultHash["android.permission.WRITE_EXTERNAL_STORAGE"] == QtAndroid::PermissionResult::Granted){
                              QString filePath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/" + extension + "."+ extension;
                  
                              QAndroidJniObject javaFilenameStr = QAndroidJniObject::fromString(filePath);
                              QAndroidJniObject javaSendToStr = QAndroidJniObject::fromString(receiver);
                  
                              QAndroidJniObject::callStaticMethod<void>("app/email/Mailer","sendMail","(Ljava/lang/String;Ljava/lang/String;)V", javaFilenameStr.object<jstring>(), javaSendToStr.object<jstring>());
                          }else{
                              emit errorMessage(tr("Sending E-Mails with attachment requires permission to write"));
                         }
                      });
                  
                  
                  #else
                      Q_UNUSED(receiver)
                      Q_UNUSED(extension)
                  #endif
                  }
                  

                  I decided to use QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) when on Android, thats a path, that allows all apps to access, but requires extra permission.

                  If the user does not grand the permission he/she can not send the pdf file. But it's checked and requested each time he/she tries to send one. In case once mind changes.

                  Works fine.


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  1 Reply Last reply
                  1

                  • Login

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