1

I want to display a PDF stored in the assets folder using an external library. This library requires a path to a file.

I read that the pdf stored in the assets folder is not stored as a file. What I need is

  1. Read the pdf-file from the assets into a (temporary) file object
  2. get the path of that object for the external pdf-viewer-library

What I got so far is the following:

stream = getAssets().open("excerpt.pdf");
BufferedReader reader = new BufferedReader(
                new InputStreamReader(stream));

I'm not really sure what to do next unfortunately...

EDIT: I tried the following code:

private void copyAssets() {
    AssetManager assetManager = getAssets();
    String[] files = null;
try {
    files = assetManager.list("");
} catch (IOException e) {
    Log.e("tag", "Failed to get asset file list.", e);
  }
 for(String filename : files) {
    InputStream in = null;
    OutputStream out = null;
    try {
      in = assetManager.open(filename);

      String dirout= Environment.getExternalStorageDirectory().getAbsolutePath() + "/X/Y/Z/" ; 
      File outFile = new File(dirout, filename);

      out = new FileOutputStream(outFile);
      copyFile(in, out);
      in.close();
      in = null;
      out.flush();
      out.close();
        out = null;
      } catch(IOException e) {
          Log.e("tag", "Failed to copy asset file: " + filename, e);
         }       
       }
     }
 ...

I am getting an exception in "out = new FileOutputStream(outFile);" (no such file or directory). I thought the code create a file there?

deimos1988
  • 5,896
  • 7
  • 41
  • 57
  • This external library accepts `InputStream` as input? – Wakim Jun 19 '14 at 17:49
  • @Wakim The external library I am using is this one: https://github.com/jblough/Android-Pdf-Viewer-Library It accepts the path of the pdf-file as string. – deimos1988 Jun 19 '14 at 17:50
  • I suggested `InputStream` because it's easy to retrieve an `InputStream` from resources (like you did or with `openRawResource`). I don't know but it's not possible to get a filepath from resources because they are compiled with the apk, but there is a workaround... You can get this `BufferedReader`, store in the device storage and get a path to the file. It's not the best solution but works :) – Wakim Jun 19 '14 at 17:54
  • Check this answer, it might help you http://stackoverflow.com/questions/8474821/how-to-get-the-android-path-string-to-a-file-on-assets-folder – TyMarc Jun 19 '14 at 18:06
  • @tyMarc I tried a similar approach, please check my updated question – deimos1988 Jun 19 '14 at 18:15
  • 1
    When directories /X/Y/Z do not exist you first have to create them with mkdirs(). new FileOutPutStream will create the file. Not the directories. – greenapps Jun 19 '14 at 18:28
  • @deimos1988 You can check the answer I gave you. – TyMarc Jun 19 '14 at 20:04

2 Answers2

0
  1. Copy the file to a public location that other applications can access using a process similar to that described in this question.

  2. Keep a reference to the external file you created for launching your Intent(Intent.ACTION_VIEW).

  3. Build an Intent to view your pdf, ex:

     public void viewPdf(File YOUR_PUBLIC_FILE_FROM_STEP_1) {
    
     PackageManager packageManager = getPackageManager();
     Intent viewPdf = new Intent(Intent.ACTION_VIEW);
     viewPdf.setType("application/pdf");
     List<ResolveInfo> list =packageManager.queryIntentActivities(viewPdf,PackageManager.MATCH_DEFAULT_ONLY);
    
    // Check available PDF viewers on device
    if (list.size() > 0) {
         Intent from_external_app = new Intent(Intent.ACTION_VIEW);
         from_external_app.setDataAndType(Uri.fromFile(YOUR_PUBLIC_FILE_FROM_STEP_1),
                            "application/pdf");
         from_external_app.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
         startActivity(from_external_app);
    

    }

Community
  • 1
  • 1
Submersed
  • 8,810
  • 2
  • 30
  • 38
  • Thank you for you suggestion, I tried a similar approach which doesn't work, please check my edited question. – deimos1988 Jun 19 '14 at 18:16
0

Does the directory exists?

If not, it will send an IOException.

Just to make sure, try this approach:

final File directory = new File("/sdcard/X/Y/Z/");
if (!directory.exists()) {
    directory.mkdirs();
}

It will create the parent directories if they don't exist. If they exist, it will return false and it will NOT delete the content in it. After this, just continue the same way you were doing it.

File outFile = new File(directory, filename);

Don't forget to add the permissions to your AndroidManifest!

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
TyMarc
  • 932
  • 7
  • 13