1

First I would like to say that I have tried several solutions, methods, suggestions and referred to several links on here to open a PDF. You can call me slow, but I have at least tried. I would like to open a PDF in my Android Application. I am on a Nexus 10 tablet. I cannot use a web view. I want to open this pdf via my OnClickListener in one of my fragments. I think my biggest problem is I am unsure where to save my PDF. I have tried res and assets folders. Many example use /sdcard/ - is that just saving it on my device? If so where / how to get path? I have saved a .pdf file in adobe reader on my tablet can I access that path? I am using API min 16 target API 19.

I have tried many variations of this

public void onClick(View v) 
{
    switch(v.getId())
    {
    case R.id.bizbro3:
        File pdfFile = new File( // I don't know what to put here / where to save pdf. Have tried /sdcard/ , getresrouces, absolutepath, ect.); 
        if(pdfFile.exists()) 
        {
            Uri path = Uri.fromFile(pdfFile); 
            Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
            pdfIntent.setDataAndType(path, "application/pdf");
            pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

            try
            {
                startActivity(pdfIntent);
            }
            catch(ActivityNotFoundException e)
            {
                Toast.makeText(v.getContext(), "Something went wrong. Returning to the Main Menu",
                        Toast.LENGTH_LONG).show();

                fragment = new FragmentThree();
                fragment.setArguments(args);
                FragmentManager frgManager = getFragmentManager();
                frgManager.beginTransaction().replace(R.id.content_frame, fragment)
                        .commit();                  
            }
        }

    }
droidShot
  • 137
  • 2
  • 12

2 Answers2

2

first declare permissions in manifest

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

then try this

String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/yourfolder";
File file = new File(path,"file.pdf"); 
Naveed Ali
  • 2,609
  • 1
  • 22
  • 37
  • thanks for the response! is /yourfolder the path to a folder on my tablet, then? – droidShot Jul 02 '14 at 19:04
  • or if you have path of file then convert it uri like Uri myUri = Uri.parse(str); then pass it to pdfIntent.setDataAndType(uri, "application/pdf"); – Naveed Ali Jul 02 '14 at 19:10
  • 1
    Yes. `Environment.getExternalStorageDirectory().getAbsolutePath()` will give you the root directory, then concatenating it with `/yourpath` will go to whatever folder is under `/yourpath` from the root directory. – Shawnic Hedgehog Jul 02 '14 at 19:10
0

The reason your code fails is that the extracted APK folders, assets/ included, are application-private, and cannot be viewed by an external app. The fact that you have "invited" such an external app to view your data by issuing an intent, makes no difference.

You will need to copy the file to a non-private location (typically: sdcard) and things will start working:

void coptAssetToSdcard() {
  InputStream input = getAssets().open("myFile.pdf");

  File sdCard = Environment.getExternalStorageDirectory();
  File dir = new File (sdCard.getAbsolutePath() + "/myDir/");
  dir.mkdirs();
  File outFile = new File(dir, "destFile.pdf");

  OutputStream out = new FileOutputStream(outFile);

  byte[] buffer = new byte[10*1024];
  int nBytes;
  while ((nBytes = input.read(buffer)) != -1) {
      out.write(buffer, 0, nBytes);
  }
  out.flush();
  out.close();
  input.close();
}

Remember to place this func in an AsyncTask or something.

I also see that your code has a fall through (catch ActivityNotFoundException) for the case device has no pdf viewer, which is the correct thing to do.

Gilad Haimov
  • 5,767
  • 2
  • 26
  • 30