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. How to share a PDF file using intents?
QtWS25 Last Chance

How to share a PDF file using intents?

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
15 Posts 4 Posters 22.1k Views
  • 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.
  • X xtingray
    28 Nov 2017, 14:51

    @ekkescorner Thank you, I will be waiting for your post! :)

    E Offline
    E Offline
    ekkescorner
    Qt Champions 2016
    wrote on 29 Nov 2017, 15:06 last edited by
    #5

    @xtingray I know you're waiting ;-)
    so here's the repo of the example app:
    https://github.com/ekke/ekkesSHAREexample

    PLEASE NO QUESTIONS BEFORE MY BLOG IS PUBLISHED

    I'm working on documentation and blog article to explain the workflows. stay tuned

    Overview

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

    X 1 Reply Last reply 29 Nov 2017, 22:47
    3
    • E ekkescorner
      29 Nov 2017, 15:06

      @xtingray I know you're waiting ;-)
      so here's the repo of the example app:
      https://github.com/ekke/ekkesSHAREexample

      PLEASE NO QUESTIONS BEFORE MY BLOG IS PUBLISHED

      I'm working on documentation and blog article to explain the workflows. stay tuned

      Overview

      X Offline
      X Offline
      xtingray
      wrote on 29 Nov 2017, 22:47 last edited by
      #6

      @ekkescorner It works! It works like a charm! I owe you a beer! :D
      Thank you :)


      Qt Developer

      E 1 Reply Last reply 29 Nov 2017, 22:49
      1
      • X xtingray
        29 Nov 2017, 22:47

        @ekkescorner It works! It works like a charm! I owe you a beer! :D
        Thank you :)

        E Offline
        E Offline
        ekkescorner
        Qt Champions 2016
        wrote on 29 Nov 2017, 22:49 last edited by
        #7

        @xtingray great to hear. that it works and the beer :)
        ...working on my blog...

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

        1 Reply Last reply
        0
        • E Offline
          E Offline
          ekkescorner
          Qt Champions 2016
          wrote on 1 Dec 2017, 13:17 last edited by
          #8

          and here's the Blog: http://blog.qt.io/blog/2017/12/01/sharing-files-android-ios-qt-app/
          thx to all helping me with this

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

          1 Reply Last reply
          1
          • S Offline
            S Offline
            sierdzio
            Moderators
            wrote on 2 Dec 2017, 07:48 last edited by
            #9

            Great stuff, thank you Ekke!

            (Z(:^

            1 Reply Last reply
            0
            • X Offline
              X Offline
              xtingray
              wrote on 4 Dec 2017, 04:09 last edited by xtingray 12 Apr 2017, 04:29
              #10

              Hi Ekke,
              Using your implementation I am having an issue with an specific version of Android (7.0), running from a tablet Samsung Galaxy Tab A sm-P580.

              It seems that this path is not available or accessible from my Qt app:

              QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).value(0);
              

              As this is the path where I do the copy of the asset to share, I can't accomplish the action. Any suggestion?

              PS: Quoting from -> https://developer.android.com/training/secure-file-sharing/index.html
              "In all cases, the only secure way to offer a file from your app to another app is to send the receiving app the file's content URI and grant temporary access permissions to that URI. Content URIs with temporary URI access permissions are secure because they apply only to the app that receives the URI, and they expire automatically. The Android FileProvider component provides the method getUriForFile() for generating a file's content URI. "


              Qt Developer

              E 1 Reply Last reply 4 Dec 2017, 05:27
              0
              • X xtingray
                4 Dec 2017, 04:09

                Hi Ekke,
                Using your implementation I am having an issue with an specific version of Android (7.0), running from a tablet Samsung Galaxy Tab A sm-P580.

                It seems that this path is not available or accessible from my Qt app:

                QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).value(0);
                

                As this is the path where I do the copy of the asset to share, I can't accomplish the action. Any suggestion?

                PS: Quoting from -> https://developer.android.com/training/secure-file-sharing/index.html
                "In all cases, the only secure way to offer a file from your app to another app is to send the receiving app the file's content URI and grant temporary access permissions to that URI. Content URIs with temporary URI access permissions are secure because they apply only to the app that receives the URI, and they expire automatically. The Android FileProvider component provides the method getUriForFile() for generating a file's content URI. "

                E Offline
                E Offline
                ekkescorner
                Qt Champions 2016
                wrote on 4 Dec 2017, 05:27 last edited by ekkescorner 12 Apr 2017, 05:29
                #11

                @xtingray have you set the permissions of the app ?
                also please note (see readme) that current implementation is for Target SDK 23.
                Google has changed the way Intents deal with URI startinmg with SDK 24, where you'll need a Content URI and a FileProvider.

                I started my app with the 'old' way and wanted to get this work before implementing the FileProvider.
                Will do this next 2-3 weeks.

                BTW: my current implementation runs well on Android 7 and Android 8 devices using Target SDK 23

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

                X 1 Reply Last reply 4 Dec 2017, 12:27
                3
                • E ekkescorner
                  4 Dec 2017, 05:27

                  @xtingray have you set the permissions of the app ?
                  also please note (see readme) that current implementation is for Target SDK 23.
                  Google has changed the way Intents deal with URI startinmg with SDK 24, where you'll need a Content URI and a FileProvider.

                  I started my app with the 'old' way and wanted to get this work before implementing the FileProvider.
                  Will do this next 2-3 weeks.

                  BTW: my current implementation runs well on Android 7 and Android 8 devices using Target SDK 23

                  X Offline
                  X Offline
                  xtingray
                  wrote on 4 Dec 2017, 12:27 last edited by xtingray 12 Apr 2017, 12:27
                  #12

                  @ekkescorner Damn it Ekker! You saved my life twice in less than a week. Thank you again.

                  PS: Please, don't forget to leave a note in this thread when you update your blog post ;)


                  Qt Developer

                  1 Reply Last reply
                  0
                  • X Offline
                    X Offline
                    xtingray
                    wrote on 6 Dec 2017, 13:11 last edited by xtingray 12 Jun 2017, 13:28
                    #13

                    Yesterday I started my own expedition to implement the share file feature from Android 7.0 Nougat., following the documentation from:
                    https://developer.android.com/training/secure-file-sharing/index.html

                    Here is a little report about my advance:

                    1. The first challenge I had to face was to include the Java library required to call the FileProvider class from my intent implementation. I was using Qt Creator 5.8 and I couldn't fix it from there, so I updated to 5.9 and then it was really easy. All I had to do was to edit the file: android/build.gradle
                      And to add the next line within the dependencies section:
                        compile 'com.android.support:support-v4:25.0.0'
                    
                    1. I had to edit the Android config file android/AndroidManifest.xml to add the Provider section inside the <application> tag:
                             <provider
                                android:name="android.support.v4.content.FileProvider"
                                android:authorities="com.company.myapp.fileprovider"
                                android:grantUriPermissions="true"
                                android:exported="false">
                                <meta-data
                                    android:name="android.support.FILE_PROVIDER_PATHS"
                                    android:resource="@xml/filepaths" />
                            </provider>
                    
                    1. I had to add an xml file to define a valid folder to locate all the files I want to share. Tip: If your files are not placed in that path, you will get an exception from Android 7. The xml must be created in the path android/res/xml/filepaths.xml and it must contain these lines:
                    <paths>
                        <files-path path="my_inner_dir/" name="mydir" />
                    </paths>
                    

                    Note: This directory (my_inner_dir) will be located at the "files" folder from your Android app installation path, so don't forget to create it in some point.
                    4. Inside my Intents section of the Java code, I added this new piece of code:

                    import android.support.v4.content.FileProvider;
                    ...
                        public static void shareFile(String path) {
                            String TAG = "Debug";
                    
                            if (QtNative.activity() == null)
                                return;
                    
                            File file = new File(path);
                            if (file.exists()) {
                                Uri fileUri;
                                try {
                                    fileUri = FileProvider.getUriForFile(QtNative.activity(),
                                                  "com.company.myapp.fileprovider", file);
                                    Log.i("Uri: ", fileUri.toString());
                                } catch (IllegalArgumentException e) {
                                    Log.e(TAG, "The selected file can't be shared: " + path);
                                    return;
                                }
                    
                                Intent myIntent = new Intent();
                                myIntent.setAction(Intent.ACTION_SEND);
                                myIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                                myIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                                myIntent.setDataAndType(fileUri, QtNative.activity().getContentResolver().getType(fileUri));
                    
                                if (myIntent.resolveActivity(QtNative.activity().getPackageManager()) != null)
                                    QtNative.activity().startActivity(myIntent);
                                else
                                    Log.i(TAG, "Fatal Error: Intent not resolved!");
                            } else {
                                Log.i(TAG, "Fatal Error: File doesn't exist -> " + path);
                            }
                        }
                    
                    

                    Now, here is the far I could go: The compilation is clean and I can try to share files from my app.
                    What is my new issue: when I get the list of apps to share and I pick any of them, they allow me to choose the contact I want to send the file, but when I select it, nothing happens. The only app that is actually sharing the file with absolutely no issues is Google Hangout.

                    So, the million dollar question is: What I am missing?

                    PS: From the console, I can see this lines when I try to share something from WhatsApp, Telegram or any other app (except GH):

                    I/Uri:    ( 2869): content://com.company.myapp..fileprovider/mydir/test.png
                    I/ActivityManager(  945): START u0 {act=android.intent.action.SEND dat=content://com.company.myapp.fileprovider/mydir/test.png typ=image/png flg=0x3 cmp=android/com.android.internal.app.ResolverActivity} from pid 2869
                    V/HardwareRenderer( 2869): Gl20Renderer.startTrimMemory: not force render mem full trim.
                    W/dalvikvm( 2645): VFY: unable to resolve virtual method 12869: Landroid/widget/ImageView;.setImageIcon (Landroid/graphics/drawable/Icon;)V
                    

                    Qt Developer

                    E 2 Replies Last reply 6 Dec 2017, 13:22
                    0
                    • X xtingray
                      6 Dec 2017, 13:11

                      Yesterday I started my own expedition to implement the share file feature from Android 7.0 Nougat., following the documentation from:
                      https://developer.android.com/training/secure-file-sharing/index.html

                      Here is a little report about my advance:

                      1. The first challenge I had to face was to include the Java library required to call the FileProvider class from my intent implementation. I was using Qt Creator 5.8 and I couldn't fix it from there, so I updated to 5.9 and then it was really easy. All I had to do was to edit the file: android/build.gradle
                        And to add the next line within the dependencies section:
                          compile 'com.android.support:support-v4:25.0.0'
                      
                      1. I had to edit the Android config file android/AndroidManifest.xml to add the Provider section inside the <application> tag:
                               <provider
                                  android:name="android.support.v4.content.FileProvider"
                                  android:authorities="com.company.myapp.fileprovider"
                                  android:grantUriPermissions="true"
                                  android:exported="false">
                                  <meta-data
                                      android:name="android.support.FILE_PROVIDER_PATHS"
                                      android:resource="@xml/filepaths" />
                              </provider>
                      
                      1. I had to add an xml file to define a valid folder to locate all the files I want to share. Tip: If your files are not placed in that path, you will get an exception from Android 7. The xml must be created in the path android/res/xml/filepaths.xml and it must contain these lines:
                      <paths>
                          <files-path path="my_inner_dir/" name="mydir" />
                      </paths>
                      

                      Note: This directory (my_inner_dir) will be located at the "files" folder from your Android app installation path, so don't forget to create it in some point.
                      4. Inside my Intents section of the Java code, I added this new piece of code:

                      import android.support.v4.content.FileProvider;
                      ...
                          public static void shareFile(String path) {
                              String TAG = "Debug";
                      
                              if (QtNative.activity() == null)
                                  return;
                      
                              File file = new File(path);
                              if (file.exists()) {
                                  Uri fileUri;
                                  try {
                                      fileUri = FileProvider.getUriForFile(QtNative.activity(),
                                                    "com.company.myapp.fileprovider", file);
                                      Log.i("Uri: ", fileUri.toString());
                                  } catch (IllegalArgumentException e) {
                                      Log.e(TAG, "The selected file can't be shared: " + path);
                                      return;
                                  }
                      
                                  Intent myIntent = new Intent();
                                  myIntent.setAction(Intent.ACTION_SEND);
                                  myIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                                  myIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                                  myIntent.setDataAndType(fileUri, QtNative.activity().getContentResolver().getType(fileUri));
                      
                                  if (myIntent.resolveActivity(QtNative.activity().getPackageManager()) != null)
                                      QtNative.activity().startActivity(myIntent);
                                  else
                                      Log.i(TAG, "Fatal Error: Intent not resolved!");
                              } else {
                                  Log.i(TAG, "Fatal Error: File doesn't exist -> " + path);
                              }
                          }
                      
                      

                      Now, here is the far I could go: The compilation is clean and I can try to share files from my app.
                      What is my new issue: when I get the list of apps to share and I pick any of them, they allow me to choose the contact I want to send the file, but when I select it, nothing happens. The only app that is actually sharing the file with absolutely no issues is Google Hangout.

                      So, the million dollar question is: What I am missing?

                      PS: From the console, I can see this lines when I try to share something from WhatsApp, Telegram or any other app (except GH):

                      I/Uri:    ( 2869): content://com.company.myapp..fileprovider/mydir/test.png
                      I/ActivityManager(  945): START u0 {act=android.intent.action.SEND dat=content://com.company.myapp.fileprovider/mydir/test.png typ=image/png flg=0x3 cmp=android/com.android.internal.app.ResolverActivity} from pid 2869
                      V/HardwareRenderer( 2869): Gl20Renderer.startTrimMemory: not force render mem full trim.
                      W/dalvikvm( 2645): VFY: unable to resolve virtual method 12869: Landroid/widget/ImageView;.setImageIcon (Landroid/graphics/drawable/Icon;)V
                      
                      E Offline
                      E Offline
                      ekkescorner
                      Qt Champions 2016
                      wrote on 6 Dec 2017, 13:22 last edited by
                      #14

                      @xtingray thx providing your experiences.
                      should be easier to add the android support library ;-)

                      will take some weeks until I can continue and add target sdk >23 file sharing support using FileProvider.

                      next week I'll add support the other way: HowTo provide the App to others as share target - there are also some traps HowTo deal with the multi instances of the app on Android and I have to figure out HowTo do it from iOS.

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

                      1 Reply Last reply
                      0
                      • X xtingray
                        6 Dec 2017, 13:11

                        Yesterday I started my own expedition to implement the share file feature from Android 7.0 Nougat., following the documentation from:
                        https://developer.android.com/training/secure-file-sharing/index.html

                        Here is a little report about my advance:

                        1. The first challenge I had to face was to include the Java library required to call the FileProvider class from my intent implementation. I was using Qt Creator 5.8 and I couldn't fix it from there, so I updated to 5.9 and then it was really easy. All I had to do was to edit the file: android/build.gradle
                          And to add the next line within the dependencies section:
                            compile 'com.android.support:support-v4:25.0.0'
                        
                        1. I had to edit the Android config file android/AndroidManifest.xml to add the Provider section inside the <application> tag:
                                 <provider
                                    android:name="android.support.v4.content.FileProvider"
                                    android:authorities="com.company.myapp.fileprovider"
                                    android:grantUriPermissions="true"
                                    android:exported="false">
                                    <meta-data
                                        android:name="android.support.FILE_PROVIDER_PATHS"
                                        android:resource="@xml/filepaths" />
                                </provider>
                        
                        1. I had to add an xml file to define a valid folder to locate all the files I want to share. Tip: If your files are not placed in that path, you will get an exception from Android 7. The xml must be created in the path android/res/xml/filepaths.xml and it must contain these lines:
                        <paths>
                            <files-path path="my_inner_dir/" name="mydir" />
                        </paths>
                        

                        Note: This directory (my_inner_dir) will be located at the "files" folder from your Android app installation path, so don't forget to create it in some point.
                        4. Inside my Intents section of the Java code, I added this new piece of code:

                        import android.support.v4.content.FileProvider;
                        ...
                            public static void shareFile(String path) {
                                String TAG = "Debug";
                        
                                if (QtNative.activity() == null)
                                    return;
                        
                                File file = new File(path);
                                if (file.exists()) {
                                    Uri fileUri;
                                    try {
                                        fileUri = FileProvider.getUriForFile(QtNative.activity(),
                                                      "com.company.myapp.fileprovider", file);
                                        Log.i("Uri: ", fileUri.toString());
                                    } catch (IllegalArgumentException e) {
                                        Log.e(TAG, "The selected file can't be shared: " + path);
                                        return;
                                    }
                        
                                    Intent myIntent = new Intent();
                                    myIntent.setAction(Intent.ACTION_SEND);
                                    myIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                                    myIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                                    myIntent.setDataAndType(fileUri, QtNative.activity().getContentResolver().getType(fileUri));
                        
                                    if (myIntent.resolveActivity(QtNative.activity().getPackageManager()) != null)
                                        QtNative.activity().startActivity(myIntent);
                                    else
                                        Log.i(TAG, "Fatal Error: Intent not resolved!");
                                } else {
                                    Log.i(TAG, "Fatal Error: File doesn't exist -> " + path);
                                }
                            }
                        
                        

                        Now, here is the far I could go: The compilation is clean and I can try to share files from my app.
                        What is my new issue: when I get the list of apps to share and I pick any of them, they allow me to choose the contact I want to send the file, but when I select it, nothing happens. The only app that is actually sharing the file with absolutely no issues is Google Hangout.

                        So, the million dollar question is: What I am missing?

                        PS: From the console, I can see this lines when I try to share something from WhatsApp, Telegram or any other app (except GH):

                        I/Uri:    ( 2869): content://com.company.myapp..fileprovider/mydir/test.png
                        I/ActivityManager(  945): START u0 {act=android.intent.action.SEND dat=content://com.company.myapp.fileprovider/mydir/test.png typ=image/png flg=0x3 cmp=android/com.android.internal.app.ResolverActivity} from pid 2869
                        V/HardwareRenderer( 2869): Gl20Renderer.startTrimMemory: not force render mem full trim.
                        W/dalvikvm( 2645): VFY: unable to resolve virtual method 12869: Landroid/widget/ImageView;.setImageIcon (Landroid/graphics/drawable/Icon;)V
                        
                        E Offline
                        E Offline
                        ekkescorner
                        Qt Champions 2016
                        wrote on 6 Apr 2018, 08:25 last edited by
                        #15

                        @xtingray I'm just implementing the FileProvider and using content Uri for SEND, VIEW, EDIT
                        over all looks good - so will go public soon and Qt Blog will also follow

                        but as always - there's also a problem

                        ACTION_EDIT doesn't work with Google Photos App. Getting toast message 'Editing is not supported for this image'
                        ACTION_VIEW works
                        downloaded another app (Photo Editor) from Google Play and it works for EDIT or VIEW
                        so my implementation seems to be ok

                        using the old SDK23 - FilePath same images can be EDITed with Google Photos with no problems
                        found this: https://productforums.google.com/forum/#!msg/photos/2MGDEOUhhl0/oNJR_nROAAAJ
                        but wasn't really helpful

                        are you using EDIT together with Google Photos ?

                        ekke ... Qt Champion 2016 | 2024 ... mobile business apps
                        5.15 --> 6.8 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