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. Save and Open PDF on Android!
Forum Updated to NodeBB v4.3 + New Features

Save and Open PDF on Android!

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
16 Posts 3 Posters 1.5k 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.
  • R Offline
    R Offline
    RenanHm
    wrote on 31 Oct 2022, 17:13 last edited by
    #1

    Hello.. I am saving a PDF file on the Android device as follows:

    QString fileName = QFileDialog::getSaveFileName(this, tr("Exportar relatório..."), QString(), tr("PDF (*.pdf);;HTML (*.htm *.html);;Excel (*.csv);;Todos Arquivos (*)"));
        if(fileName.isEmpty())
            return;
    
    printer->setOutputFormat(QPrinter::PdfFormat);
    printer->setOutputFileName(fileName);
    TE_Rel->document()->print(printer);
    

    This way I use on Windows and now I'm using it on Android.
    Apparently the PDF is successfully saved in the APP folder. But I can't view the APP form PDF, which I believe is related to Android permissions.

    Given this, I'm trying to open the PDF right after saving. I use the following code to try to open it:

            QString filePath = fileName; //The file exists at that location, I used the same path to create the pdf
            QDesktopServices::openUrl(QUrl::fromLocalFile(filePath));
    

    However, the PDF is not opened through a standard PDF viewer that is installed on the device.

    Any other alternative to save and read PDF on Android?

    I use QT 5.14.2.
    Thanks.

    1 Reply Last reply
    0
    • J Offline
      J Offline
      JoeCFD
      wrote on 31 Oct 2022, 17:31 last edited by JoeCFD
      #2

      add read and write permissions in your AndroidManifess.xml? You can save your files in QStandardPaths::DocumentsLocation

      1 Reply Last reply
      0
      • R Offline
        R Offline
        RenanHm
        wrote on 31 Oct 2022, 17:52 last edited by
        #3

        I will add the following permissions:

            <uses-permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES"/>
            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
            <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
            <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
            <uses-permission android:name="android.permission.WRITE_PROFILE"/>
        

        But apparently it has no effect.

        Whenever I save the PDF, the QFileDialog opens, allowing saving only within the APP folder.

        Any idea?

        1 Reply Last reply
        0
        • J Offline
          J Offline
          JoeCFD
          wrote on 31 Oct 2022, 18:08 last edited by JoeCFD
          #4

          @JoeCFD said in Save and Open PDF on Android!:

          QStandardPaths::DocumentsLocation

          you assign this path QStandardPaths::DocumentsLocation to QFileDialog

          1 Reply Last reply
          0
          • R Offline
            R Offline
            RenanHm
            wrote on 31 Oct 2022, 18:36 last edited by
            #5

            Hello.. Okay. Change to:

                QString caminho = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
                QString fileName = QFileDialog::getSaveFileName(this, tr("Exportar relatório..."), caminho, tr("PDF (*.pdf);;HTML (*.htm *.html);;Excel (*.csv);;Todos Arquivos (*)"));
                if(fileName.isEmpty())
                    return;
            

            Now open the "Documents" folder. Saves correctly. But I can't open it with my APP through QDesktopServices

            1 Reply Last reply
            0
            • J Offline
              J Offline
              JoeCFD
              wrote on 31 Oct 2022, 18:46 last edited by JoeCFD
              #6

              not familiar with QDesktopServices. What is the error message?
              the following link is a bit old. But it may help a bit.
              https://stackoverflow.com/questions/18786919/qt-android-qdesktopservicesopenurl-qurlfromlocalfile-pdf-with
              https://bugreports.qt.io/browse/QTBUG-67877

              1 Reply Last reply
              0
              • R Offline
                R Offline
                RenanHm
                wrote on 31 Oct 2022, 20:02 last edited by
                #7

                W System.err: android.os.FileUriExposedException: file:///storage/emulated/0/Documents/Caduser.pdf exposed beyond app through Intent.getData()
                W System.err: at android.os.StrictMode.onFileUriExposed(StrictMode.java:2209)
                W System.err: at android.net.Uri.checkFileUriExposed(Uri.java:2402)
                W System.err: at android.content.Intent.prepareToLeaveProcess(Intent.java:12108)
                W System.err: at android.content.Intent.prepareToLeaveProcess(Intent.java:12057)
                W System.err: at android.app.Instrumentation.execStartActivity(Instrumentation.java:1742)
                W System.err: at android.app.Activity.startActivityForResult(Activity.java:5473)
                W System.err: at android.app.Activity.startActivityForResult(Activity.java:5431)
                W System.err: at android.app.Activity.startActivity(Activity.java:5817)
                W System.err: at android.app.Activity.startActivity(Activity.java:5770)
                W System.err: at org.qtproject.qt5.android.QtNative.openURL(QtNative.java:164)
                W System.err: at org.qtproject.qt5.android.QtNative.startQtApplication(Native Method)
                W System.err: at org.qtproject.qt5.android.QtNative$7.run(QtNative.java:390)
                W System.err: at org.qtproject.qt5.android.QtThread$1.run(QtThread.java:61)
                W System.err: at java.lang.Thread.run(Thread.java:1012)

                P 1 Reply Last reply 31 Oct 2022, 23:12
                0
                • R RenanHm
                  31 Oct 2022, 20:02

                  W System.err: android.os.FileUriExposedException: file:///storage/emulated/0/Documents/Caduser.pdf exposed beyond app through Intent.getData()
                  W System.err: at android.os.StrictMode.onFileUriExposed(StrictMode.java:2209)
                  W System.err: at android.net.Uri.checkFileUriExposed(Uri.java:2402)
                  W System.err: at android.content.Intent.prepareToLeaveProcess(Intent.java:12108)
                  W System.err: at android.content.Intent.prepareToLeaveProcess(Intent.java:12057)
                  W System.err: at android.app.Instrumentation.execStartActivity(Instrumentation.java:1742)
                  W System.err: at android.app.Activity.startActivityForResult(Activity.java:5473)
                  W System.err: at android.app.Activity.startActivityForResult(Activity.java:5431)
                  W System.err: at android.app.Activity.startActivity(Activity.java:5817)
                  W System.err: at android.app.Activity.startActivity(Activity.java:5770)
                  W System.err: at org.qtproject.qt5.android.QtNative.openURL(QtNative.java:164)
                  W System.err: at org.qtproject.qt5.android.QtNative.startQtApplication(Native Method)
                  W System.err: at org.qtproject.qt5.android.QtNative$7.run(QtNative.java:390)
                  W System.err: at org.qtproject.qt5.android.QtThread$1.run(QtThread.java:61)
                  W System.err: at java.lang.Thread.run(Thread.java:1012)

                  P Offline
                  P Offline
                  piervalli
                  wrote on 31 Oct 2022, 23:12 last edited by
                  #8

                  @RenanHm said in Save and Open PDF on Android!:

                  W System.err: at java.lang.Thread.run(Thread.java:1012)

                  Have you checked permission on startup?

                  #ifdef REQUEST_PERMISSIONS_ON_ANDROID
                  #include <QtAndroid>
                  
                  bool requestStoragePermission() {
                      using namespace QtAndroid;
                      SOPermission sop;
                      QStringList permissions = {"android.permission.ACCESS_FINE_LOCATION"};
                      const QHash<QString, PermissionResult> results = requestPermissionsSync(permissions);
                      auto ok = true;
                      auto i = 0;
                      while (ok && i< permissions.size()) {
                          if (!results.contains(permissions[i]) || results[permissions[i]] == PermissionResult::Denied) {
                              qCritical() << "Couldn't get permission: " << permissions[i];
                              ok = false;
                              --i;
                          }
                          ++i;
                      }
                      return ok;
                  }
                  #endif
                  
                  1 Reply Last reply
                  0
                  • R Offline
                    R Offline
                    RenanHm
                    wrote on 1 Nov 2022, 12:57 last edited by
                    #9

                    Hello.. I performed the test with the function mentioned. Change to permission:

                        QStringList permissions = {"android.permission.READ_EXTERNAL_STORAGE"};
                    

                    It is returned to me that it has permission. But without any practical effect.

                    Searching more.. I found that in the most recent versions of Android it is now necessary to use "Provider".

                    https://bugreports.qt.io/browse/QTBUG-67877
                    https://bugreports.qt.io/browse/QTBUG-85238

                    Following the guidelines for using the Provider, I add in the Manifest:

                    <provider
                                android:name="androidx.core.content.FileProvider"
                                android:authorities="com.example.myapp.fileprovider"
                                android:grantUriPermissions="true"
                                android:exported="false">
                                <meta-data
                                    android:name="android.support.FILE_PROVIDER_PATHS"
                                    android:resource="@xml/filepaths" />
                            </provider>
                    

                    I also include the "filepaths" file in the "xml" folder.
                    But the error always occurs when opening the APP:

                    E AndroidRuntime: FATAL EXCEPTION: main
                    E AndroidRuntime: Process: com.digitalsof.totallocapp, PID: 4718
                    E AndroidRuntime: java.lang.RuntimeException: Unable to get provider androidx.core.content.FileProvider: java.lang.ClassNotFoundException: Didn't find class "androidx.core.content.FileProvider" on path: DexPathList[[zip file "/data/app/~~qh7wYdLZU6AvVfgP104ckQ==/com.digitalsof.totallocapp-pzAvkKqAw1X05TWYviFvnA==/base.apk"],nativeLibraryDirectories=[/data/app/~~qh7wYdLZU6AvVfgP104ckQ==/com.digitalsof.totallocapp-pzAvkKqAw1X05TWYviFvnA==/lib/arm64, /data/app/~~qh7wYdLZU6AvVfgP104ckQ==/com.digitalsof.totallocapp-pzAvkKqAw1X05TWYviFvnA==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]]
                    E AndroidRuntime: 	at android.app.ActivityThread.installProvider(ActivityThread.java:8231)
                    E AndroidRuntime: 	at android.app.ActivityThread.installContentProviders(ActivityThread.java:7728)
                    E AndroidRuntime: 	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7482)
                    E AndroidRuntime: 	at android.app.ActivityThread.access$1600(ActivityThread.java:310)
                    E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2281)
                    E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
                    E AndroidRuntime: 	at android.os.Looper.loopOnce(Looper.java:226)
                    E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:313)
                    E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:8669)
                    E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
                    E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
                    E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
                    E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.core.content.FileProvider" on path: DexPathList[[zip file "/data/app/~~qh7wYdLZU6AvVfgP104ckQ==/com.digitalsof.totallocapp-pzAvkKqAw1X05TWYviFvnA==/base.apk"],nativeLibraryDirectories=[/data/app/~~qh7wYdLZU6AvVfgP104ckQ==/com.digitalsof.totallocapp-pzAvkKqAw1X05TWYviFvnA==/lib/arm64, /data/app/~~qh7wYdLZU6AvVfgP104ckQ==/com.digitalsof.totallocapp-pzAvkKqAw1X05TWYviFvnA==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]]
                    E AndroidRuntime: 	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
                    E AndroidRuntime: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
                    E AndroidRuntime: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
                    E AndroidRuntime: 	at android.app.AppComponentFactory.instantiateProvider(AppComponentFactory.java:147)
                    E AndroidRuntime: 	at android.app.ActivityThread.installProvider(ActivityThread.java:8215)
                    E AndroidRuntime: 	... 11 more
                    

                    Any idea?

                    P 1 Reply Last reply 1 Nov 2022, 17:21
                    0
                    • R RenanHm
                      1 Nov 2022, 12:57

                      Hello.. I performed the test with the function mentioned. Change to permission:

                          QStringList permissions = {"android.permission.READ_EXTERNAL_STORAGE"};
                      

                      It is returned to me that it has permission. But without any practical effect.

                      Searching more.. I found that in the most recent versions of Android it is now necessary to use "Provider".

                      https://bugreports.qt.io/browse/QTBUG-67877
                      https://bugreports.qt.io/browse/QTBUG-85238

                      Following the guidelines for using the Provider, I add in the Manifest:

                      <provider
                                  android:name="androidx.core.content.FileProvider"
                                  android:authorities="com.example.myapp.fileprovider"
                                  android:grantUriPermissions="true"
                                  android:exported="false">
                                  <meta-data
                                      android:name="android.support.FILE_PROVIDER_PATHS"
                                      android:resource="@xml/filepaths" />
                              </provider>
                      

                      I also include the "filepaths" file in the "xml" folder.
                      But the error always occurs when opening the APP:

                      E AndroidRuntime: FATAL EXCEPTION: main
                      E AndroidRuntime: Process: com.digitalsof.totallocapp, PID: 4718
                      E AndroidRuntime: java.lang.RuntimeException: Unable to get provider androidx.core.content.FileProvider: java.lang.ClassNotFoundException: Didn't find class "androidx.core.content.FileProvider" on path: DexPathList[[zip file "/data/app/~~qh7wYdLZU6AvVfgP104ckQ==/com.digitalsof.totallocapp-pzAvkKqAw1X05TWYviFvnA==/base.apk"],nativeLibraryDirectories=[/data/app/~~qh7wYdLZU6AvVfgP104ckQ==/com.digitalsof.totallocapp-pzAvkKqAw1X05TWYviFvnA==/lib/arm64, /data/app/~~qh7wYdLZU6AvVfgP104ckQ==/com.digitalsof.totallocapp-pzAvkKqAw1X05TWYviFvnA==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]]
                      E AndroidRuntime: 	at android.app.ActivityThread.installProvider(ActivityThread.java:8231)
                      E AndroidRuntime: 	at android.app.ActivityThread.installContentProviders(ActivityThread.java:7728)
                      E AndroidRuntime: 	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7482)
                      E AndroidRuntime: 	at android.app.ActivityThread.access$1600(ActivityThread.java:310)
                      E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2281)
                      E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
                      E AndroidRuntime: 	at android.os.Looper.loopOnce(Looper.java:226)
                      E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:313)
                      E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:8669)
                      E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
                      E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
                      E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
                      E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.core.content.FileProvider" on path: DexPathList[[zip file "/data/app/~~qh7wYdLZU6AvVfgP104ckQ==/com.digitalsof.totallocapp-pzAvkKqAw1X05TWYviFvnA==/base.apk"],nativeLibraryDirectories=[/data/app/~~qh7wYdLZU6AvVfgP104ckQ==/com.digitalsof.totallocapp-pzAvkKqAw1X05TWYviFvnA==/lib/arm64, /data/app/~~qh7wYdLZU6AvVfgP104ckQ==/com.digitalsof.totallocapp-pzAvkKqAw1X05TWYviFvnA==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]]
                      E AndroidRuntime: 	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
                      E AndroidRuntime: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
                      E AndroidRuntime: 	at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
                      E AndroidRuntime: 	at android.app.AppComponentFactory.instantiateProvider(AppComponentFactory.java:147)
                      E AndroidRuntime: 	at android.app.ActivityThread.installProvider(ActivityThread.java:8215)
                      E AndroidRuntime: 	... 11 more
                      

                      Any idea?

                      P Offline
                      P Offline
                      piervalli
                      wrote on 1 Nov 2022, 17:21 last edited by piervalli 11 Jan 2022, 17:23
                      #10

                      @RenanHm
                      In the my app I haved inserted in the all permission that we need .
                      const QStringList m_permissionsNameListAndroid = {"android.permission.ACCESS_FINE_LOCATION","android.permission.ACCESS_COARSE_LOCATION","android.permission.READ_EXTERNAL_STORAGE","android.permission.WRITE_EXTERNAL_STORAGE","android.permission.CHANGE_WIFI_STATE","android.permission.READ_PHONE_STATE","android.permission.ACCESS_WIFI_STATE","android.permission.BLUETOOTH","android.permission.BLUETOOTH_ADMIN","android.permission.VIBRATE","android.permission.RECEIVE_BOOT_COMPLETED"};

                      For Android > 10 I have ceate this function to create an file on directory. So You can test, if you can write on directory. I neved opened a url but I think the way is create a function java.

                      For example
                      //https://trendoceans.com/how-to-open-pdf-programmatically-using-intent-in-android/

                      For open the url
                      public static String directoryDownLoad() {
                      Context context = m_instance.getApplicationContext();
                      File path = android.os.Environment.getExternalStoragePublicDirectory(
                      android.os.Environment.DIRECTORY_DOWNLOADS);
                      Log.v(m_instance.TAG,"directoryDownLoad"+path.getAbsolutePath());
                      return path.getAbsolutePath();
                      }

                      Id

                      1 Reply Last reply
                      0
                      • R Offline
                        R Offline
                        RenanHm
                        wrote on 1 Nov 2022, 19:37 last edited by
                        #11

                        I'm managing to save the PDF, as I went above.
                        The problem is in opening the PDF.

                        From what I researched, the "Provider" should be created and call the native java class through "QAndroidJniObject".

                        But I can't move forward when I edit the Manifest file as above.

                        P 1 Reply Last reply 1 Nov 2022, 21:46
                        0
                        • R RenanHm
                          1 Nov 2022, 19:37

                          I'm managing to save the PDF, as I went above.
                          The problem is in opening the PDF.

                          From what I researched, the "Provider" should be created and call the native java class through "QAndroidJniObject".

                          But I can't move forward when I edit the Manifest file as above.

                          P Offline
                          P Offline
                          piervalli
                          wrote on 1 Nov 2022, 21:46 last edited by
                          #12

                          @RenanHm
                          In this case usually I create a basic project with Android Studio to open a pdf. Then you can push the function in activity that you have extended in Qt for Android

                          R 1 Reply Last reply 3 Nov 2022, 12:38
                          0
                          • P piervalli
                            1 Nov 2022, 21:46

                            @RenanHm
                            In this case usually I create a basic project with Android Studio to open a pdf. Then you can push the function in activity that you have extended in Qt for Android

                            R Offline
                            R Offline
                            RenanHm
                            wrote on 3 Nov 2022, 12:38 last edited by
                            #13

                            @piervalli said in Save and Open PDF on Android!:

                            In this case usually I create a basic project with Android Studio to open a pdf. Then you can push the function in activity that you have extended in Qt for Android

                            I understood. I am going to try..

                            1 Reply Last reply
                            0
                            • R Offline
                              R Offline
                              RenanHm
                              wrote on 3 Nov 2022, 12:40 last edited by
                              #14

                              I'm having the same problem with printing documents on Android... QT doesn't recognize the drivers installed... it just gives the option to save to PDF... Do you know anything about this?

                              P 1 Reply Last reply 3 Nov 2022, 13:25
                              0
                              • R RenanHm
                                3 Nov 2022, 12:40

                                I'm having the same problem with printing documents on Android... QT doesn't recognize the drivers installed... it just gives the option to save to PDF... Do you know anything about this?

                                P Offline
                                P Offline
                                piervalli
                                wrote on 3 Nov 2022, 13:25 last edited by
                                #15

                                @RenanHm
                                I am remember that the printer is not supported on Android, I think that you need same way.

                                R 1 Reply Last reply 3 Nov 2022, 13:34
                                0
                                • P piervalli
                                  3 Nov 2022, 13:25

                                  @RenanHm
                                  I am remember that the printer is not supported on Android, I think that you need same way.

                                  R Offline
                                  R Offline
                                  RenanHm
                                  wrote on 3 Nov 2022, 13:34 last edited by
                                  #16

                                  @piervalli Got it.. I'll research about it. Thanks.

                                  1 Reply Last reply
                                  0

                                  1/16

                                  31 Oct 2022, 17:13

                                  • Login

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