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. File copy fails on Android
Forum Updated to NodeBB v4.3 + New Features

File copy fails on Android

Scheduled Pinned Locked Moved Solved Mobile and Embedded
9 Posts 6 Posters 1.5k Views 2 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.
  • SeDiS Offline
    SeDiS Offline
    SeDi
    wrote on last edited by SeDi
    #1

    Hi, I am copying a file to the download folder:

    Q_INVOKABLE bool exportNutritionLogFile() {
            QString downloadFolder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
            qDebug()<<"downloadFolder is: "<<downloadFolder;
            QString timeStamp = QDateTime::currentDateTime().toString("_yyyy-MM-dd_HH-mm-ss");
            QString targetFilenameAndPath = downloadFolder+"/nutritionLogExport"+timeStamp+".json";
            qDebug() << "targetFilenameAndPath: "<<targetFilenameAndPath;
            QFile logFile(QStringLiteral("logged_nutrition.json"));
            if (!logFile.exists()) return false;
    
            QFile testFile(targetFilenameAndPath);
            if (testFile.exists()) {
                testFile.remove();
            }
            auto success = logFile.copy(targetFilenameAndPath);
            qDebug()<<"success: "<<success;
            return success;
        }
    

    That works on my phone (Nokia8). But on my tablet (Galaxy Tab S4) I recieve:

    D libPunktlandung_armeabi-v7a.so: downloadFolder is:  "/storage/emulated/0/Download"
    D libPunktlandung_armeabi-v7a.so: targetFilenameAndPath:  "/storage/emulated/0/Download/nutritionLogExport_2021-08-14_12-59-51.json"
    D libPunktlandung_armeabi-v7a.so: success:  false
    

    I have the WRITE_EXTERNAL_STORAGE permisison and the folder / the path does exist.
    What could possibly be the problem here? Why does it work on one device and doesn't on a different one?

    J.HilkJ 1 Reply Last reply
    1
    • KH-219DesignK Offline
      KH-219DesignK Offline
      KH-219Design
      wrote on last edited by
      #2

      I might come across as extremely cynical...

      but after years of cross-platform development (on desktop and mobile), I have essentially "given up" on certain why questions, such as:

      • Why does it work on one device and doesn't on a different one?

      Instead, I have just come to EXPECT that these conundrums will reoccur at every possible opportunity...

      Here is a sample of how I proactively attempt to "code around" such pain points:

          QString OurLocalLogPathWithSeparatorAlreadyAppended()
          {
              // In order of preference. We expect the first to always succeed.
              const std::vector<QStandardPaths::StandardLocation> possibleLocations{ {
                  QStandardPaths::DataLocation,
                  QStandardPaths::ConfigLocation,
                  QStandardPaths::GenericDataLocation,
                  QStandardPaths::DownloadLocation, // truly a last resort.
              } };
      
              QString chosenLocation;
              for( const auto possibility : possibleLocations )
              {
                  const QString location = QStandardPaths::writableLocation( possibility );
                  // mkpath was necessary on my Android phone when app was first installed!
                  const bool madePath = QDir().mkpath( location );
                  if( location.length() > 3 && madePath )
                  {
                      chosenLocation = location;
                      break;
                  }
              }
      
              qDebug() << chosenLocation;
      
              if( !chosenLocation.isEmpty() )
              {
                  chosenLocation += "/";
              }
              return chosenLocation;
          }
      

      In other words, plan to have 2 or 3 "backup locations" where you can read/write your files, in case your first location is off-limits for any reason.

      www.219design.com
      Software | Electrical | Mechanical | Product Design

      1 Reply Last reply
      2
      • SeDiS SeDi

        Hi, I am copying a file to the download folder:

        Q_INVOKABLE bool exportNutritionLogFile() {
                QString downloadFolder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
                qDebug()<<"downloadFolder is: "<<downloadFolder;
                QString timeStamp = QDateTime::currentDateTime().toString("_yyyy-MM-dd_HH-mm-ss");
                QString targetFilenameAndPath = downloadFolder+"/nutritionLogExport"+timeStamp+".json";
                qDebug() << "targetFilenameAndPath: "<<targetFilenameAndPath;
                QFile logFile(QStringLiteral("logged_nutrition.json"));
                if (!logFile.exists()) return false;
        
                QFile testFile(targetFilenameAndPath);
                if (testFile.exists()) {
                    testFile.remove();
                }
                auto success = logFile.copy(targetFilenameAndPath);
                qDebug()<<"success: "<<success;
                return success;
            }
        

        That works on my phone (Nokia8). But on my tablet (Galaxy Tab S4) I recieve:

        D libPunktlandung_armeabi-v7a.so: downloadFolder is:  "/storage/emulated/0/Download"
        D libPunktlandung_armeabi-v7a.so: targetFilenameAndPath:  "/storage/emulated/0/Download/nutritionLogExport_2021-08-14_12-59-51.json"
        D libPunktlandung_armeabi-v7a.so: success:  false
        

        I have the WRITE_EXTERNAL_STORAGE permisison and the folder / the path does exist.
        What could possibly be the problem here? Why does it work on one device and doesn't on a different one?

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

        @SeDi said in File copy fails on Android:

        I have the WRITE_EXTERNAL_STORAGE permisison and the folder / the path does exist.

        You may have that in your manifest file, but after a certain Android version it became a requirement to check&request them at run time, just before the copy operation.

        Also I may be the case, that the default location, that your logged_nutrition.json is unavailable because its inside the AppSandbox.
        I would recommend to store it with QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) That should work, from my experience.


        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.

        SeDiS 1 Reply Last reply
        3
        • J.HilkJ J.Hilk

          @SeDi said in File copy fails on Android:

          I have the WRITE_EXTERNAL_STORAGE permisison and the folder / the path does exist.

          You may have that in your manifest file, but after a certain Android version it became a requirement to check&request them at run time, just before the copy operation.

          Also I may be the case, that the default location, that your logged_nutrition.json is unavailable because its inside the AppSandbox.
          I would recommend to store it with QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) That should work, from my experience.

          SeDiS Offline
          SeDiS Offline
          SeDi
          wrote on last edited by
          #4

          @J-Hilk said in File copy fails on Android:

          That should work

          It's been some time since I've opened this thread. But the solution, for posterity, is a bit disappointing (from me lazy programmer's point of view) as well as very positive in regards to data security:

          It's just not possible to just write into a shared space on Android any more (if you want to address a current API in order to be able to push your app to the PlayStore, that is).

          Instead we have to write the file locally and then share it with a share intent.
          ekkesSHAREexample was a huge help, but I had to nudge it into using the (newer) androidx system.

          ekkescornerE 1 Reply Last reply
          4
          • KH-219DesignK Offline
            KH-219DesignK Offline
            KH-219Design
            wrote on last edited by
            #5

            @SeDi thanks for returning here to share the outcome. This is good info that will surely help others (and likely me the next time I'm working on Android!).

            www.219design.com
            Software | Electrical | Mechanical | Product Design

            1 Reply Last reply
            1
            • G Offline
              G Offline
              generalelectric
              Banned
              wrote on last edited by
              #6
              This post is deleted!
              1 Reply Last reply
              0
              • SeDiS SeDi

                @J-Hilk said in File copy fails on Android:

                That should work

                It's been some time since I've opened this thread. But the solution, for posterity, is a bit disappointing (from me lazy programmer's point of view) as well as very positive in regards to data security:

                It's just not possible to just write into a shared space on Android any more (if you want to address a current API in order to be able to push your app to the PlayStore, that is).

                Instead we have to write the file locally and then share it with a share intent.
                ekkesSHAREexample was a huge help, but I had to nudge it into using the (newer) androidx system.

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

                @SeDi said in File copy fails on Android:

                ekkesSHAREexample was a huge help, but I had to nudge it into using the (newer) androidx system.

                would be great if you publish your code or if you tell me about your changes in Issues of my example. thx

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

                SeDiS 1 Reply Last reply
                2
                • ekkescornerE ekkescorner

                  @SeDi said in File copy fails on Android:

                  ekkesSHAREexample was a huge help, but I had to nudge it into using the (newer) androidx system.

                  would be great if you publish your code or if you tell me about your changes in Issues of my example. thx

                  SeDiS Offline
                  SeDiS Offline
                  SeDi
                  wrote on last edited by
                  #8

                  @ekkescorner Sorry for not noticing this for more than half a year. And sorry again: I have been wrong with saying that I had to nudge your example. I have just checked. What I had to nudge was in my build.gradle:

                  dependencies {
                      implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
                      compile 'androidx.appcompat:appcompat:1.1.0'     // <-- THIS
                      def billing_version = "4.0.0"
                      implementation "com.android.billingclient:billing:$billing_version"
                  }
                  

                  and my gradle.properties:

                  android.useAndroidX=true
                  
                  ekkescornerE 1 Reply Last reply
                  0
                  • SeDiS SeDi

                    @ekkescorner Sorry for not noticing this for more than half a year. And sorry again: I have been wrong with saying that I had to nudge your example. I have just checked. What I had to nudge was in my build.gradle:

                    dependencies {
                        implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
                        compile 'androidx.appcompat:appcompat:1.1.0'     // <-- THIS
                        def billing_version = "4.0.0"
                        implementation "com.android.billingclient:billing:$billing_version"
                    }
                    

                    and my gradle.properties:

                    android.useAndroidX=true
                    
                    ekkescornerE Offline
                    ekkescornerE Offline
                    ekkescorner
                    Qt Champions 2016
                    wrote on last edited by
                    #9

                    @SeDi thx. Will take a look at it soon - have to update / rewrite all my examples for Qt6 next months

                    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
                    0

                    • Login

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