3

So I've been making these 2 apps and I want app 1 to be able to send pdf files to app 2. They're both signed with different keys as app 1 should be usable by any other apps as well.

The way I want it to work is as follows. App 2 sends a startActivityForResult to app 1 with an intent including a Uri with a file from App 2s fileprovider. Then app 1 should take the Uri and write the pdf onto the file provided by app 2. Then going back to app 2 the file should be written onto the file owned by app 2 in the first place.

Put simply the app 2 should provide a file where app 1 should write the pdf.

So I have it all set up like that but when trying to access the file to write to it, I get the java.lang.SecurityException: Permission Denial: opening provider androidx.core.content.FileProvider error message.

Full Error Message: Permission Denial: opening provider androidx.core.content.FileProvider from ProcessRecord{511cc8 14209:com.eureka.documentscanner/u0a159} (pid=14209, uid=10159) that is not exported from UID 10155

Code to copy the pdf's:

//This method is called once the app has selected the right pdf file and wants to return back to app 2.
    private void writeToSharedFile(){
        Intent StartingIntent = getIntent();

        //Get the shared file (the file to write to from app 2).
        Uri sharedFileUri = StartingIntent.getParcelableExtra(Intent.EXTRA_STREAM);

        //Get the file that I need to write into the shared file.
        Uri fileToWrite = Uri.fromFile(scanResult.pdfFile);

        //Write the file into the shared file.
        copyPDFs(fileToWrite,sharedFileUri);
    }


    private void copyPDFs(Uri from, Uri to){
        ParcelFileDescriptor pfdTo = null;
        FileOutputStream out = null;
        ParcelFileDescriptor pfdFrom = null;
        FileInputStream in = null;
        ContentResolver cr = context.getContentResolver();
        final String WRITE_ACCESS = "w";
        final String READ_ACCESS = "r";

        try {
            pfdTo = cr.openFileDescriptor(to, WRITE_ACCESS);
            out = new FileOutputStream(pfdTo.getFileDescriptor());

            pfdFrom = cr.openFileDescriptor(from, READ_ACCESS);
            in = new FileInputStream(pfdFrom.getFileDescriptor());

            //Reads from the input stream and writes the data to the output stream.
            int n;
            while ((n = in.read()) != -1) {
                out.write(n);
            }
        } catch (SecurityException e){
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            // Let the document provider know you're done by closing the stream.
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (pfdTo != null) {
                try {
                    pfdTo.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (pfdFrom != null) {
                try {
                    pfdFrom.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } //Close the Streams and Descriptors.
    }

The security exception is always thrown on the pfdTo = cr.openFileDescriptor(to, WRITE_ACCESS); line.

I'm 100% sure there is read and write access on the intent used to start the activity for result, and that there is read and write permissions granted on the external storage.

Any suggestions or help would be appreciated.

Michael
  • 31
  • 4
  • How is `Uri to` created? Where is it coming from? – CommonsWare Jul 30 '21 at 12:26
  • Where do you use the function copyPDFs for? There is nothing in your post about it. Please add code so we can see which parameters you use. Make clear where both uries come from. Also tell which app uses that function. – blackapps Jul 30 '21 at 12:48
  • `Put simply the app 2 should provide a file where app 1 should write the pdf.` You mean: simply app 2 should provide an uri where app 1 should copy? the pdf. – blackapps Jul 30 '21 at 12:54
  • So there is already a pdf file!? Then why not start with it? – blackapps Jul 30 '21 at 12:57
  • `I want app 1 to be able to send pdf files to app 2.` It looks you are trying to do so in a very complicated way. Simple: let app 1 send the uri of the pdf file to app2. App 2 can do the copy then. – blackapps Jul 30 '21 at 13:00
  • Hi I've edited the code if that would make it a bit easier. And no the file does not exist, the app needs to create it first then send it back. I've tried providing a Uri and doing the copying on the app 2, but the issue arrives everywhere. I get the SecurityException everytime I try and access the Uri no matter what. – Michael Jul 30 '21 at 13:08
  • 2
    second app that is generating the uri must add this permission to let other app write on this location using the uri ``shareContentIntent.addFlags( Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);`` – Ariful Jannat Arif Nov 08 '21 at 03:24

0 Answers0