Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 7 - Cannot display PDF (pdf_name is of invalid format)

Tags:

java

android

pdf

I have an App that is working properly for Android 4, 5 and 6. That App lists remote files in a server and lets you download them from the server (PDF files). Once you click on a file, it downloads it on the "Android Downloads folder" and when it's finished it opens it with default PDF reader.

The problem is that the same code in Android 7 fails giving the next error: "Cannot display PDF (pdf_name is of invalid format)".

It's funny because:

  • if I access Downloads folder and click on the downloaded file, it opens properly.
  • When it finishes downloading, it shows a notification, that click on it opens it properly.

So the problem happens only when the same App tries to open the file automatically after download it.

How I do the download:

fileName="file.pdf";
request = new DownloadManager.Request(Uri.parse(Constants.GetURL()));
request.setMimeType(mime)
    .setTitle(fileName).setVisibleInDownloadsUi(true)
    .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
    .setDescription(mContext.getString(R.string.app_name))
    .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
    .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
enqueue = dm.enqueue(request);

Once is downloaded:

    Uri path = Uri.parse(c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)));
//path contains the route where file was downloaded. Something like: file:///storage/emulated/0/Download/file.pdf
    Intent pdfOpenintent = IntentHelper.getViewPDFIntent(path);                                            
    mContext.startActivity(pdfOpenintent);

How I open it:

public static Intent getViewPDFIntent(Uri path){
    Intent i = new Intent(Intent.ACTION_VIEW);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    pdfOpenintent.setDataAndType(path, "application/pdf");
    return i;
}

About FileProvider: I have implemented using FileProvider and the problem is the same. It is not related with permissions, Download Folder is public folder and there is no SecurityException raising or any other exception related with permissions.

It is not related with any PDF App, because it happens the same sharing with Gmail for sending the document.

Extrange behaviour: When I debug the App step by step, it works perfectly. When I execute normal, it fails. If I put sleep or delays of 5 secs, does not work. So only works debugging.

About Android 7: Reading the official changes of Android 7 (https://developer.android.com/about/versions/nougat/android-7.0-changes.html) it says it should work, but dont recommend any more this way. Otherwise, it does not work.

Any new idea?

like image 834
Christian Avatar asked Dec 06 '16 13:12

Christian


People also ask

Why can't I open a PDF file on my Android device?

This is not a programming problem. I suggest that in your emulator or device, you install a pdf reader ( Google PDF Viewer ). If you are using an emulator, it may be necessary for you to use a version that has Google Play already installed. And then you can install the pdf reader.

What do I need to open a PDF file?

I suggest that in your emulator or device, you install a pdf reader ( Google PDF Viewer ). If you are using an emulator, it may be necessary for you to use a version that has Google Play already installed.

How do I download PDF files to my Emulator or device?

I suggest that in your emulator or device, you install a pdf reader ( Google PDF Viewer ). If you are using an emulator, it may be necessary for you to use a version that has Google Play already installed. And then you can install the pdf reader.


1 Answers

After some days of research and some people involved, we arrived to the conclusion that Android changed the behaviour of DownloadManager on Android 7 to add the permissions of FileProvider. (In Android 7 Changelog they explain)

My feeling is that Android since Android 7 (and 7.1), is probably saving the File in a temporal folder, then sends the Broadcast FileDownloadedSuccessfully, and then it moves the file to the final destination folder.

Because the FileDownloaded Broadcast jumps before the file is moved, it is not able to open it. That is why while debugging or putting a sleep of 10 seconds, then it works.

Did not find any solution for this problem more than stop using DownloaderManager for download&open and implement my own. (Only will use for just a download of a file, without any other action involved).

Hope it helps for the next who finds this problem.

like image 68
Christian Avatar answered Oct 13 '22 07:10

Christian