Android - open pdf in external application

后端 未结 3 692
萌比男神i
萌比男神i 2021-01-15 03:39

i\'ve a pdf file in my app assets directory that i want open using an external app, so wrote my content provider and i\'m tryng to make it work but nothing...

here i

相关标签:
3条回答
  • 2021-01-15 03:58

    setType() resets your Uri to null. Try skipping the Uri in the constructor and using setDataAndType() instead.

    0 讨论(0)
  • 2021-01-15 04:05

    I am new to android development and spent the whole day looking for the reason that my locally stored PDF could not be opened by external apps. I am glad having found this thread.

    In the meantime Marco got it working and describes it here. Beware: Italian language- Google translation service might help ;-)

    http://www.marcofaion.it/?p=7
    http://web.archive.org/web/20111020204554/http://www.marcofaion.it/?p=7

    Additional notes to his howto for beginners:

    The line Marco mentions to be inserted in the Manifest.xml

    <provider android:name=".FileContentProvider" android:authorities="package.name" />
    

    should be inserted within the <application ...></application> tag.

    And if you plan to have custom filenames you should exchange

    InputStream is = am.open("file.pdf");
    

    with

    InputStream is = am.open(uri.getLastPathSegment());
    

    PDF files have to be put into already existing folder assets in your project (especially not in any newly added folder res/assets or sth.)! =)

    0 讨论(0)
  • 2021-01-15 04:25

    My implementation is below. Note that if your filename is MyPdf.pdf, the file should be assets/public_pdfs/MyPdf.pdf.mp3. The path public_pdfs is to only export the pdfs you really want to export, and the .mp3 extension is to prevent compression.

    AndroidManifest.xml

    <provider android:authorities="my.app.PdfContentProvider" android:enabled="true" android:exported="true" android:name="my.app.PdfContentProvider">
    </provider>
    

    Opening a PDF

    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    
    Uri uri = Uri.parse("content://my.app.PdfContentProvider/" + filename);
    intent.setDataAndType(uri, "application/pdf");
    
    startActivity(intent);
    

    PdfContentProvider.java

    public class PdfContentProvider extends ContentProvider
    {
      private static final String PDFPATH = "public_pdfs/";
    
      @Override
      public String getType(Uri uri)
      {
        return "application/pdf";
      }
    
      @Override
      public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException
      {
        AssetManager am = getContext().getAssets();
        String file_name = uri.getLastPathSegment();
    
        if (file_name == null) throw new FileNotFoundException();
        AssetFileDescriptor afd = null;
        try
        {
          afd = am.openFd(PDFPATH + file_name + ".mp3");
        }
        catch (IOException e)
        {
          e.printStackTrace();
        }
        return afd;
      }
    
      private final static String[] COLUMNS = {OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE};
    
      @Override
      /**
       * This function is required for it to work on the Quickoffice at Android 4.4 (KitKat)
       */
      public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
      {
        if (projection == null)
        {
          projection = COLUMNS;
        }
    
        String[] cols = new String[projection.length];
        Object[] values = new Object[projection.length];
        int i = 0;
        for (String col : projection)
        {
          if (OpenableColumns.DISPLAY_NAME.equals(col))
          {
            cols[i] = OpenableColumns.DISPLAY_NAME;
            values[i++] = uri.getLastPathSegment();
          }
          else if (OpenableColumns.SIZE.equals(col))
          {
            cols[i] = OpenableColumns.SIZE;
            values[i++] = AssetFileDescriptor.UNKNOWN_LENGTH;
          }
        }
    
        cols = copyOf(cols, i);
        values = copyOf(values, i);
    
        final MatrixCursor cursor = new MatrixCursor(cols, 1);
        cursor.addRow(values);
        return cursor;
      }
    
      private static String[] copyOf(String[] original, int newLength)
      {
        final String[] result = new String[newLength];
        System.arraycopy(original, 0, result, 0, newLength);
        return result;
      }
    
      private static Object[] copyOf(Object[] original, int newLength)
      {
        final Object[] result = new Object[newLength];
        System.arraycopy(original, 0, result, 0, newLength);
        return result;
      }
    
      @Override
      public boolean onCreate()
      {
        return true;
      }
    
      @Override
      public Uri insert(Uri uri, ContentValues values)
      {
        return null;
      }
    
      @Override
      public int delete(Uri uri, String selection, String[] selectionArgs)
      {
        return 0;
      }
    
      @Override
      public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
      {
        return 0;
      }
    }
    
    0 讨论(0)
提交回复
热议问题