4

我正在处理pdf。我正在尝试使用下面的代码从我的应用程序中打开一个 pdf 文件。但是我没有打开。

private void openPdf() {

        File file = new File("mnt/sdcard.test.pdf");
        Uri path = Uri.fromFile(file);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.setAction(Intent.ACTION_VIEW);
        intent.setData(path);
        intent.setType("application/pdf");
        try {
            startActivity(intent);
        } catch (ActivityNotFoundException e) {
            Toast.makeText(getActivity(), "No application found",
                    Toast.LENGTH_SHORT).show();
        }
    }

当我在模拟器中尝试此代码时,它显示一个吐司说“未找到应用程序”(bcoz,通常模拟器中没有安装 pdf 查看应用程序)。当我在设备中测试相同的东西(特别是在 funbook 选项卡和索尼选项卡中)时,它既没有显示 Toast 消息,也没有打开 pdf 文件。任何人都可以指出我的代码中的错误。实际上,我是第一次使用 pdf。所以我的问题是,

  1. 在设备中它没有显示 toast 消息,这意味着我的手机中安装了一个 pdf 查看应用程序?这样对吗?
  2. 如果是这样,为什么不使用第三方应用程序打开 pdf。
  3. 如果我想向用户列出我手机中安装的所有 pdf 查看应用程序,我应该在此代码中进行哪些更改?
4

7 回答 7

4

我得到了上述问题的解决方案,所以尝试一次;

脚步:-

  1. 在您的应用名称下的 src 中创建 assets 文件夹。

  2. 在此资产文件夹中保存您的 pdf 文件,例如 schedule1.pdf。

  3. 现在来你的活动,即 MainActivity.java

  4. setListener 在任何你想要的 UI 组件上,即 ( Button, ImageView, ImageButton);

  5. 在此侦听器中调用一个用户定义的方法,即openPDFFiles()

openPDFFiles() 方法有以下代码:

private void openPDFFiles() {
    AssetManager assetManager = getAssets();

    InputStream in = null;
    OutputStream out = null;
    File file = new File(getFilesDir(), “schedule1.pdf”);//here schedule1.pdf is the pdf file name which is keep in assets folder.
    try {
        in = assetManager.open(“schedule1.pdf”);
        out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);

        copyFile(in, out);
        in.close();
        in = null;
        out.flush();
        out.close();
        out = null;
    } catch (Exception e) {
        Log.e(“tag”, e.getMessage());
    }

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.parse(“file://” + getFilesDir() + “/schedule1.pdf”), “application/pdf”);

    startActivity(intent);
}

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);
    }
}
于 2015-03-16T06:50:45.050 回答
4

因为android 9 and 10你应该使用这个代码

1-创建一个class

public class GenericFileProvider extends FileProvider {

}

2-inres目录创建一个目录命名xml 并创建一个文件命名provider_paths.xml并添加此代码

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

3- manifestsinapplication添加此代码

  <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-您应该获得许可Manifest.permission.READ_EXTERNAL_STORAGE

5-并添加此代码

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-我建议您将此代码添加applicationmanifests

android:requestLegacyExternalStorage="true"
于 2020-06-23T07:42:07.087 回答
3

试试 LuxuryMode 的方法:https ://stackoverflow.com/a/8221594/1500067

我认为您只是缺少 adobe 包 intent.setPackage("com.adobe.reader");

于 2012-07-09T15:44:00.417 回答
2

尽管我没有在我的应用程序中打开 SD 卡中的文件,但我有几乎相同的代码可以正常工作。

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();
}

所以你的方法是正确的。确保您可以先打开文件...即使用 mActivity.openFileInput() 来确保您拥有可读的 PDF。

于 2012-07-09T20:08:46.257 回答
2

您可以使用 3rd 方库集成来实现此目的。下面列出了工作库,带有 SDK

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

使用 NDK

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

使用指南@

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

于 2015-08-17T10:30:49.007 回答
0

在此处下载源代码(在我的 android 应用程序中显示 PDF 文件

在 Gradle 文件中添加此依赖项:

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 + "-");
            }
        }
    }

}
于 2017-02-17T06:27:36.897 回答
0

我知道答案可能为时已晚,但是您的问题是由以下 2 行引起的: intent.setData(path); intent.setType("application/pdf");

当你 setData 之后你 setType,第二个命令将清除在 setData 中分配的路径。在这种情况下,您应该使用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 意图类

于 2020-01-03T18:01:16.213 回答