1

I have a pdf file in the Download Storage and I try show it using intent, I already have three PDF viewer apps, but none of them sucessfully show the file, but if I open the pdf directly via file explorer its show just fine.

here is my code :

File kuda = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File file1 = new File(kuda,"KK.pdf");

Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri= FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID+".provider",file1);
            
intent.setDataAndType(uri, "application/pdf");                
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);

my manifest :

 <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
  </provider>

provider paths :

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
 <external-path name="external_files" path="Download/"/>
 <files-path name="files" path="files/" />
</paths>

I'm using android 10

please help. thanks

Gusti Arya
  • 1,281
  • 3
  • 15
  • 32
  • Has your device android Q/10 ? – blackapps Sep 17 '20 at 08:17
  • Please give an example of the value of uri.toString(). – blackapps Sep 17 '20 at 08:18
  • `I have a pdf file in the Download Storage`. Ok. How did the file land there? Did your app do it? How? – blackapps Sep 17 '20 at 08:23
  • @blackapps yes, android 10, uri.toString() = content://id.geektro.polisisehat.provider/external_files/KK.pdf, I put pdf file manually to that folder. – Gusti Arya Sep 17 '20 at 08:37
  • On Android 10 your app has no access to Download folder. No access to all getExternalStoragePublicDirectory()'s. Unless you did something extra. Now did you? If you would try to open an inputstream for your uri (`InputStream is = getContentResolver().openInputStream(uri);`) and tried to read from it it would not go already. Or openen a FileInputStream for your file and trying to read. – blackapps Sep 17 '20 at 08:39
  • @blackapps oh thanks for the info, so which i folder I should put my pdf files? so I don't do something extra. – Gusti Arya Sep 17 '20 at 08:54
  • In getExternalFilesDir(null). – blackapps Sep 17 '20 at 09:07

1 Answers1

1

Yea, things changed after OS 10, you have to write logic in new way. Sample where we get some response using retrofit and using those byte[], working in my apps. Put this code in your android component(activity for example). Invoking viewModel.getPdfBytes() is response from backend!

private static final int CREATE_FILE = 23;

 private void saveFileToStorageIntent() {
        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType(MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf"));
        intent.putExtra(Intent.EXTRA_TITLE, getString(R.string.text_export_pdf_file_first) + getDateString() + getString(R.string.text_export_pdf_file));
        startActivityForResult(intent, CREATE_FILE);
    }

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CREATE_FILE) {
            if (resultCode == Activity.RESULT_OK && data != null) {
                writePDFToFile(data.getData(), viewModel.getPdfBytes());
            }
        }
    }



private void writePDFToFile(Uri uri, ResponseBody body){
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            byte[] fileReader = new byte[4096];

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

            inputStream = body.byteStream();
            outputStream = getContentResolver().openOutputStream(uri);

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

                if (read == -1) {
                    break;
                }
                outputStream.write(fileReader, 0, read);
                fileSizeDownloaded += read;
                Logger.print(TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
            }
            outputStream.flush();
            openFileWithIntent(uri,"pdf", getString(R.string.open_file));
        } catch (Exception e) {
            Logger.print(TAG, e.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

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




private void openFileWithIntent(Uri fileUri, String typeString, String openTitle) {
        Intent target = new Intent(Intent.ACTION_VIEW);
        target.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        target.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        target.setDataAndType(
                fileUri,
                MimeTypeMap.getSingleton().getMimeTypeFromExtension(typeString)
        ); // For now there is only type 1 (PDF).
        Intent intent = Intent.createChooser(target, openTitle);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        try {
            startActivity(intent);
        } catch (ActivityNotFoundException e) {
            if (BuildConfig.DEBUG) e.printStackTrace();
            Toast.makeText(context, getString(R.string.error_no_pdf_app), Toast.LENGTH_SHORT).show();
            FirebaseCrashlytics.getInstance().log(getString(R.string.error_no_pdf_app));
            FirebaseCrashlytics.getInstance().recordException(e);
        }
    }
DM developing
  • 423
  • 5
  • 15