2

I am using following code to download and read a PDF file from internal storage on device.

I am able to download the files successfully to the directory:

data/data/packagename/app_books/file.pdf

But I am unable to read the file using a PDF reader application like Adobe Reader.

Code to download file

//Creating an internal dir;
File mydir = getApplicationContext().getDir("books", Context.MODE_WORLD_READABLE);

try {
    File file = new File(mydir, outputFileName);
    URL downloadUrl = new URL(url);
    URLConnection ucon = downloadUrl.openConnection();
    ucon.connect();

    InputStream is = ucon.getInputStream();

    FileOutputStream fos = new FileOutputStream(file);  

    byte data[] = new byte[1024];

    int current = 0;
    while ((current = is.read(data)) != -1) {
        fos.write(data, 0, current);
    }        
    is.close();
    fos.flush();
    fos.close();
    isFileDownloaded=true;
} catch (IOException e) {
    e.printStackTrace();
    isFileDownloaded = false;
    System.out.println(outputFileName + " not downloaded");
}
if (isFileDownloaded)
    System.out.println(outputFileName + " downloaded");
return isFileDownloaded;

Code to read the file

PackageManager packageManager = getPackageManager();

Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");

List list = packageManager.queryIntentActivities(testIntent,
        PackageManager.MATCH_DEFAULT_ONLY);

try {
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);                        

    File fileToRead = new File(
            "/data/data/com.example.filedownloader/app_books/Book.pdf");
    Uri uri = Uri.fromFile(fileToRead.getAbsoluteFile());

    intent.setDataAndType(uri, "application/pdf");
    startActivity(intent);
} catch (Exception ex) {
    Log.i(getClass().toString(), ex.toString());
    Toast.makeText(MainActivity.this,
            "Cannot open your selected file, try again later",
            Toast.LENGTH_SHORT).show();
}

All works fine but the reader app says "File Path is not valid".

Hardik Mistry
  • 178
  • 1
  • 3
  • 13

4 Answers4

1

Your path is only valid for your app. Place the file in a place where other apps can 'see' it. Use GetExternalFilesDir() or getExternalStorageDirectory().

greenapps
  • 11,154
  • 2
  • 16
  • 19
0

Note about files which are created inside the directory created by Context.getDir(String name, int mode) that they will only be accessible by your own application; you can only set the mode of the entire directory, not of individual files.

So you can use Context.openFileOutput(String name, int mode). I'm re-using your code for an example:

try {
    // Now we use Context.MODE_WORLD_READABLE for this file
    FileOutputStream fos = openFileOutput(outputFileName,
            Context.MODE_WORLD_READABLE);

    // Download data and store it to `fos`
    // ...

You might want to take a look at this guide: Using the Internal Storage.

0

How to download PDF file from asset folder to storage by making folder

make sure you have storage permission are given like marshmallow device support etc then follow these steps

private void CopyReadAssets()
{
    AssetManager assetManager = getContext().getAssets();

    FileInputStream in = null;

    FileOutputStream out = null;
    File sdcard = Environment.getExternalStorageDirectory();
    File dir = new File(Environment.getExternalStorageDirectory()+File.separator+ "A_level");
    File dir2;
    if (dir.exists() && dir.isDirectory()){
         
        Log.e("tag out", ""+ dir);
    }else {
        dir.mkdir();
        Log.e("tag out", "not exist");
    }

    File file = new File(dir, mTitle+".pdf");

    try
    {
        Log.e("tag out", ""+ file);
       out = new FileOutputStream(file);
        in = new FileInputStream (new File(mPath));

        Log.e("tag In", ""+ in);

        copyFile(in, out);
        in.close();
        in = null;
        out.flush();
        out.close();
        out = null;
    } catch (Exception e)
    {
        Log.e("tag out", ""+ out);
        Log.e("tag In", ""+ in);
        Log.e("tag", e.getMessage());
        Log.e("tag", ""+file);
        Log.i("tag",""+sdcard.getAbsolutePath() + "A_level");
    }

}

private void copyFile(InputStream in, OutputStream out) throws IOException
{
    byte[] buffer = new byte[1024];
    int read;
    while ((read = in.read(buffer)) != -1)
    {
        out.write(buffer, 0, read);
    }
}
Community
  • 1
  • 1
Najaf Ali
  • 1,433
  • 16
  • 26
0

If you would like to keep the file app specific, you can use PdfRenderer available for Lollipop and above builds. There are great tutorials on google and youtube that work well. The method you are using is a secure way to store a PDF file that is only readable from inside the app ONLY. No outside application like Adobe PDF Reader will be able to even see the file.It took me a lot of seaching but I found a solution to my specific usage by using this site and especially youtube.

BCope
  • 1
  • 1
  • 2