open a pdf file programmatically

后端 未结 7 2115
广开言路
广开言路 2021-01-06 15:45

I am working on pdf. I am trying to open a pdf file from my application using the code below. But I failed to open.

private void openPdf() {

        File fi         


        
相关标签:
7条回答
  • 2021-01-06 15:48

    I have nearly identical code that works fine, though I'm not opening a file from SD card in my app.

    Activity mActivity = /* your activity */...;
    String mFileName = /* path of my PDF file */...;
    
    Uri uri  = Uri.fromFile(mActivity.getFileStreamPath(mFileName));
    
    try
    {
        Intent intentUrl = new Intent(Intent.ACTION_VIEW);
        intentUrl.setDataAndType(uri, "application/pdf");
        intentUrl.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        mActivity.startActivity(intentUrl);
    }
    catch (ActivityNotFoundException e)
    {
        Toast.makeText(mActivity, "No PDF Viewer Installed", Toast.LENGTH_LONG).show();
    }
    

    so your approach is right on. Make sure you can open the file first ... i.e. use mActivity.openFileInput() to ensure you have a readable PDF.

    0 讨论(0)
  • 2021-01-06 15:49

    Try LuxuryMode's method: https://stackoverflow.com/a/8221594/1500067

    I think your just missing the adobe package intent.setPackage("com.adobe.reader");

    0 讨论(0)
  • 2021-01-06 15:49

    Download the source code here(Display PDF file inside my android application)

    Add this dependency in your Gradle file:

    compile 'com.github.barteksc:android-pdf-viewer:2.0.3'
    

    activity_main.xml

    <RelativeLayout android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffffff"
        xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="@color/colorPrimaryDark"
            android:text="View PDF"
            android:textColor="#ffffff"
            android:id="@+id/tv_header"
            android:textSize="18dp"
            android:gravity="center"></TextView>
    
        <com.github.barteksc.pdfviewer.PDFView
            android:id="@+id/pdfView"
            android:layout_below="@+id/tv_header"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    
        </RelativeLayout>
    

    MainActivity.java

    import android.app.Activity;
    import android.database.Cursor;
    import android.net.Uri;
    import android.provider.OpenableColumns;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.RelativeLayout;
    
    import com.github.barteksc.pdfviewer.PDFView;
    import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener;
    import com.github.barteksc.pdfviewer.listener.OnPageChangeListener;
    import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle;
    import com.shockwave.pdfium.PdfDocument;
    
    import java.util.List;
    
    public class MainActivity extends Activity implements OnPageChangeListener,OnLoadCompleteListener{
        private static final String TAG = MainActivity.class.getSimpleName();
        public static final String SAMPLE_FILE = "android_tutorial.pdf";
        PDFView pdfView;
        Integer pageNumber = 0;
        String pdfFileName;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
    
            pdfView= (PDFView)findViewById(R.id.pdfView);
            displayFromAsset(SAMPLE_FILE);
        }
    
        private void displayFromAsset(String assetFileName) {
            pdfFileName = assetFileName;
    
            pdfView.fromAsset(SAMPLE_FILE)
                    .defaultPage(pageNumber)
                    .enableSwipe(true)
    
                    .swipeHorizontal(false)
                    .onPageChange(this)
                    .enableAnnotationRendering(true)
                    .onLoad(this)
                    .scrollHandle(new DefaultScrollHandle(this))
                    .load();
        }
    
    
        @Override
        public void onPageChanged(int page, int pageCount) {
            pageNumber = page;
            setTitle(String.format("%s %s / %s", pdfFileName, page + 1, pageCount));
        }
    
    
        @Override
        public void loadComplete(int nbPages) {
            PdfDocument.Meta meta = pdfView.getDocumentMeta();
            printBookmarksTree(pdfView.getTableOfContents(), "-");
    
        }
    
        public void printBookmarksTree(List<PdfDocument.Bookmark> tree, String sep) {
            for (PdfDocument.Bookmark b : tree) {
    
                Log.e(TAG, String.format("%s %s, p %d", sep, b.getTitle(), b.getPageIdx()));
    
                if (b.hasChildren()) {
                    printBookmarksTree(b.getChildren(), sep + "-");
                }
            }
        }
    
    }
    
    0 讨论(0)
  • 2021-01-06 15:53

    for android 9 and 10 you should use this code

    1-create one class

    public class GenericFileProvider extends FileProvider {
    
    }
    

    2-in res directory create one directory to name of xml and create one file to name of provider_paths.xml and add this code

    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="external_files" path="."/>
    </paths>
    

    3-in manifests in application add this code

      <provider
        android:name=".Model.Utilitys.GenericFileProvider"
        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>
    

    4-you should get Permission Manifest.permission.READ_EXTERNAL_STORAGE

    5-and add this codes

    String fileName="yourfile.pdf";
    
    File file = new File(Environment.getExternalStorageDirectory()+"/Android/data/ir.tdaapp.paymanyar/files/File",fileName);
    
    String extension = MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString());
    
    String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
    
    Intent intent = new Intent(Intent.ACTION_VIEW);
    
    intent.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_NEW_TASK);
    
    Uri uri = FileProvider.getUriForFile(getContext(), getActivity().getApplicationContext().getPackageName() + ".provider", file);
    
    intent.setDataAndType(uri, mimeType);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    
    startActivity(Intent.createChooser(intent, "choseFile"));
    

    6-I suggest you add this code to the application in manifests

    android:requestLegacyExternalStorage="true"
    
    0 讨论(0)
  • 2021-01-06 16:01

    You can achieve this using 3rd party library integration. Working libraries are listed below, with SDK

    https://github.com/JoanZapata/android-pdfview
    https://github.com/jblough/Android-Pdf-Viewer-Library

    with NDK

    https://code.google.com/p/mupdf/downloads/detail?name=mupdf-1.2-source.zip&can=2&q=

    guide to use @

    http://dixitpatel.com/integrating-pdf-in-android-application/

    0 讨论(0)
  • 2021-01-06 16:04

    I know maybe is too late for an answer, but your problem is cause by these 2 line: intent.setData(path); intent.setType("application/pdf");

    When you setData and after that you setType, the second command will clean the path assingned in setData. In this situation, you should use setDataAndType(path,"application/pdf")

    /**
     * Set an explicit MIME data type.
     *
     * <p>This is used to create intents that only specify a type and not data,
     * for example to indicate the type of data to return.
     *
     * <p>This method automatically clears any data that was
     * previously set (for example by {@link #setData}).
     *
     * <p><em>Note: MIME type matching in the Android framework is
     * case-sensitive, unlike formal RFC MIME types.  As a result,
     * you should always write your MIME types with lower case letters,
     * or use {@link #normalizeMimeType} or {@link #setTypeAndNormalize}
     * to ensure that it is converted to lower case.</em>
     *
     * @param type The MIME type of the data being handled by this intent.
     *
     * @return Returns the same Intent object, for chaining multiple calls
     * into a single statement.
     *
     * @see #getType
     * @see #setTypeAndNormalize
     * @see #setDataAndType
     * @see #normalizeMimeType
     */
    public Intent setType(String type) {
        mData = null;
        mType = type;
        return this;
    }
    

    Javadoc Intent class

    0 讨论(0)
提交回复
热议问题