简体   繁体   中英

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

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?

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.


Bit more digging has shown this seems to be a permission issue. 有点挖掘已经表明这似乎是一个许可问题。 Setting this permission fixed the issue, its very strange it worked at all with out them.

"android.permission.READ_EXTERNAL_STORAGE"


While this isnt an realy answer its more information to help identify it and provide a horrible work around, I cant make a comment yet.

I am having the same issue after downloading a PDF using AsyncTask.

doInBackground() completes correctly, all Read / Write streams are closed, onPostExecute() is called using this code.

  Intent target = new Intent(Intent.ACTION_VIEW); target.setDataAndType(Uri.fromFile(file), "application/pdf"); target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); Intent intent = Intent.createChooser(target, "View PDF Bill..."); 

and the PDF fails to launch with the invalid format error.

The 2nd load ( loading over the top of the existing PDF ) the launching of the PDF viewer works fine most of the time but does still occasionally fail.

If I debug it opens fine ( I assume due to the time it takes ), if I add a 10 second sleep it works fine, if I add a 9 second sleep it doens't. Its almost as if there is a failure on closing the file or some other termination call in the OS and it times out but no exceptions are thrown.

The 10 second delay applies even if I try to open the PDF from ES File Explorer

The code is working fine on all devices lower than Android 7.0.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM