0

I am trying to download PDF file and save it to the device memory.

  public void downloadPdfAttachment(Activity activity, Attachment attachment) {
    Dexter.withActivity(activity)
      .withPermissions(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
      .withListener(new MultiplePermissionsListener() {
        @Override public void onPermissionsChecked(MultiplePermissionsReport report) {
          if (report.areAllPermissionsGranted() && attachment != null) {
            startPdfAttachmentDownload(activity, attachment);
          } else {
            view.displayStoragePermissionRequired();
          }
        }
        @Override public void onPermissionRationaleShouldBeShown(
          List<PermissionRequest> permissions, PermissionToken token) {
          token.continuePermissionRequest();
        }
      }).check();
  }

And I get all two permission here as granted. Then I try to download attachment and save it.

public static String savePdfToDisk(Context context, ResponseBody body, String pdfName) {
    try {
      File fileDirectory = new File(getPdfFolder(context));
      fileDirectory.mkdir();

      File file = new File(fileDirectory, pdfName);
      file.createNewFile();

      InputStream inputStream = null;
      OutputStream outputStream = null;

      try {
        byte[] fileReader = new byte[4096];

        long fileSize = body.contentLength();
        long fileSizeDownloaded = 0;

        inputStream = body.byteStream();
        outputStream = new FileOutputStream(file);

        while (true) {
          int read = inputStream.read(fileReader);

          if (read == -1) {
            break;
          }

          outputStream.write(fileReader, 0, read);

          fileSizeDownloaded += read;

          Log.d("PdfUtils", "file download: " + fileSizeDownloaded + " of " + fileSize);
        }

        outputStream.flush();

        return file.getAbsolutePath();
      } catch (IOException e) {
        Log.d("PdfUtils", e.getMessage());
        return null;
      } finally {
        if (inputStream != null) {
          inputStream.close();
        }

        if (outputStream != null) {
          outputStream.flush();
          outputStream.close();
        }
      }
    } catch (IOException e) {
      Log.d("PdfUtils", e.getMessage());
      return null;
    }
  }

  public static String getPdfFolder(Context context) {
    return context.getFilesDir()+ "/my_app_name/pdf_files";
  }

And at this line I get exception that Permision is denied.

      file.createNewFile();

I double check in the app settings and Storage permission is granted.

Here is my Manifest file:

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

Any idea?

Zookey
  • 2,637
  • 13
  • 46
  • 80
  • I recommend that you edit your question and post the entire Java stack trace. You appear to be writing to `getFilesDir()`, and you do not need permissions to do that. – CommonsWare Mar 05 '20 at 19:14
  • I do not have crash, but the only exception that I handle. I will post a screenshot of that exception in a minute. – Zookey Mar 05 '20 at 19:17
  • "I do not have crash, but the only exception that I handle" -- you could fix that by having `Log.e("PdfUtils", "Exception in file I/O", e);` instead of `Log.d("PdfUtils", e.getMessage());`. **Always** log the exception in full, not just a message. – CommonsWare Mar 05 '20 at 19:19
  • Thanks for the advice. It seems that now I have "No such file or directory" exception when I try "file.createNewFile". – Zookey Mar 05 '20 at 19:20
  • Which file? Full path please! `new File(getPdfFolder(context));`. How would we know which folder path that would be? mkdir() will already return false but you are not looking at the return value. – blackapps Mar 05 '20 at 19:28
  • This one: ```public static String getPdfFolder(Context context) { return context.getFilesDir()+ "/my_app_name/pdf_files"; }``` And with this one: ```File file = new File(fileDirectory, pdfName); file.createNewFile();``` – Zookey Mar 05 '20 at 19:30
  • try this if(file.exists()) file.mkdirs() just before you try to create the file – DemoDemo Mar 05 '20 at 19:39

2 Answers2

0

Try this,

public static String getPdfFolder(Context context) {
    return context.getFilesDir().getAbsolutePath() + "/my_app_name/pdf_files";
}

The return value of getFilesDir is of type File, so if you do a String Casting that way, you will not get the correct path.

Genesis
  • 358
  • 2
  • 8
0

The issue is that I am targeting Android 10, API 29 and they changed Storage permission.

Android Q: file.mkdirs() returns false

Zookey
  • 2,637
  • 13
  • 46
  • 80