barteksc:android-pdf-viewer:3.0.0-beta.5 – 如何使用pdfview.fromFile()。FileNotFoundException

huangapple go评论75阅读模式
英文:

barteksc:android-pdf-viewer:3.0.0-beta.5 - How to pdfview.fromFile(). FileNotFoundException

问题

我尝试了很多方法,查阅了Stackoverflow和其他论坛上发布的所有解决方案,但都没有成功。每一种可能的方式都给了我一个FileNotFound异常,要么是坏的路径,要么是错误的路径。

我正在尝试从下载文件夹打开文件,代码如下:

File pdfFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/download/my-pdf-file.pdf");
pdfView.fromFile(pdfFile).load();

注意:

  1. 我能够成功地从资产文件夹加载文件。
  2. 我正在使用Pixel 2 API R作为Android模拟器。
  3. 我已经设置了以下权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

以下日志可能有助于解答:

2020-09-08 07:48:01.503 14928-14928/com.example.roohanikhazainp01 E/PDFView: load pdf error
java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
    at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:344)
    at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:231)
    at com.github.barteksc.pdfviewer.source.FileSource.createDocument(FileSource.java:37)
    at com.github.barteksc.pdfviewer.DecodingAsyncTask.doInBackground(DecodingAsyncTask.java:49)
    at com.github.barteksc.pdfviewer.DecodingAsyncTask.doInBackground(DecodingAsyncTask.java:25)
    at android.os.AsyncTask$3.call(AsyncTask.java:394)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:923)

我认为我漏掉了某些东西。请帮忙,谢谢。

英文:

I have tried a lot and tried all the soltution posted on Stackoverflow and other forums but with no luck. Every possible way gave me FieNotFoundException with either Bad Path or Wrong Path.

File pdfFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + &quot;/download/my-pdf-file.pdf&quot;);
    pdfView.fromFile(pdfFile).load();

This is how I am trying to open the file from Download folder.
Note:

  1. I am able to load the file from Assets folder successfully.

  2. I am using Pixel 2 API R as Android Emulator.

  3. I have set permissions as

    uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"

This may help in asnwering.

2020-09-08 07:48:01.503 14928-14928/com.example.roohanikhazainp01 E/PDFView: load pdf error
java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
    at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:344)
    at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:231)
    at com.github.barteksc.pdfviewer.source.FileSource.createDocument(FileSource.java:37)
    at com.github.barteksc.pdfviewer.DecodingAsyncTask.doInBackground(DecodingAsyncTask.java:49)
    at com.github.barteksc.pdfviewer.DecodingAsyncTask.doInBackground(DecodingAsyncTask.java:25)
    at android.os.AsyncTask$3.call(AsyncTask.java:394)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:923)

I think there is something I am missing. Please help thanks

答案1

得分: 0

因为我使用的是API 29和30,所以不能再使用acceEnvironment.getExternalStorageDirectory()来访问外部存储了。因此,我必须为用户提供一个选项,让他们可以使用以下方法从外部驱动器打开PDF:

Intent intentOpenPdf = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intentOpenPdf.addCategory(Intent.CATEGORY_OPENABLE);
intentOpenPdf.setType("application/pdf");
intentOpenPdf.putExtra(DocumentsContract.EXTRA_INITIAL_URI, myBookPath);
startActivityForResult(intentOpenPdf, 786);

然后在onActivityResult()函数中,可以这样获取所选PDF文件的Uri:

protected void onActivityResult(int requestCode, int resultCode, Intent data){
    if (requestCode == 786 && data != null) {
        myPdfUri = data.getData();
        pdfView.fromUri(myPdfUri).load();
    }
}

注意:您还可以保存此Uri,以便用户无需每次都选择PDF文件。

我使用了以下方法:

protected void onActivityResult(int requestCode, int resultCode, Intent data){
    if (requestCode == 786 && data != null) {
        // 从Intent发送的数据中获取Uri
        myPdfUri = data.getData();

        // 保存接收到的Uri以便以后使用
        SharedPreferences sp = this.getPreferences(MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.commit();
        getContentResolver().takePersistableUriPermission(myPdfUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        // 使用FromUri加载PDF
        pdfView.fromUri(myPdfUri).load();
    }
}

然后在开头,您可以像这样检查Uri是否已保存:

List<UriPermission> permissions = getContentResolver().getPersistedUriPermissions();
if (permissions.isEmpty()) {
    openPDF(myBookPath);
} else {
    try {
        SharedPreferences sp2 = getPreferences(MODE_PRIVATE);
        String myPdfUriString = sp2.getString("myPdfUri", ""); // 默认返回值,如果"myPdfUri"不存在
        myPdfUri = Uri.parse(myPdfUriString);
        loadPdfView(null, myPdfUri, "");
    } catch (RuntimeException ex) {
        Helper.Toaster(this, "错误: " + ex.getMessage());
    }
}

这对我来说是有效的。谢谢。

英文:

As I was using API 29, 30 it is not possible anymore to access the external storage using

acceEnvironment.getExternalStorageDirectory()

so I have to give user an option to open the PDF from external drive using this.

Intent intentOpenPdf = new Intent((Intent.ACTION_OPEN_DOCUMENT));
intentOpenPdf.addCategory(Intent.CATEGORY_OPENABLE);
intentOpenPdf.setType(&quot;application/pdf&quot;);
intentOpenPdf.putExtra(DocumentsContract.EXTRA_INITIAL_URI, myBookPath);
startActivityForResult(intentOpenPdf, 786);

And then in the function onActivityResult(). get the Uri to the selected pdf file like this.

protected void onActivityResult(int requestCode, int resultCode, Intent data){
    if (requestCode == 786 &amp;&amp; data != null) {
        myPdfUri = data.getData();
        pdfView.fromUri(myPdfUri).load();
    }
}

Note: You can also save this Uri so that the use have not to select the PDF every time.

I used this approach.

protected void onActivityResult(int requestCode, int resultCode, Intent data){
    if (requestCode == 786 &amp;&amp; data != null) {
       //Get the uri from data sent by Intent
        myPdfUri = data.getData();

       //Save the received uri for later use
       SharedPreferences sp = this.getPreferences(MODE_PRIVATE);
       SharedPreferences.Editor editor = sp.edit();
       editor.commit();
       getContentResolver().takePersistableUriPermission(myPdfUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        // Load the PDF using FromUri
        pdfView.fromUri(myPdfUri).load();
    }
}

Then at the beginning you can check if the uri is saved like this.

List&lt;UriPermission&gt; permissions = getContentResolver().getPersistedUriPermissions();
       if(permissions.isEmpty())
        {
            openPDF(myBookPath);
        }else{
            try {
                SharedPreferences sp2 = getPreferences(MODE_PRIVATE);
                String myPdfUriString = sp2.getString(&quot;myPdfUri&quot;,&quot;&quot;); // default is return if &quot;myPdfUri&quot; does not exist
                myPdfUri = Uri.parse(myPdfUriString);
                loadPdfView(null, myPdfUri, &quot;&quot;);
            }catch (RuntimeException ex){
                Helper.Toaster(this, &quot;Error : &quot; + ex.getMessage());
            }
        }

This is working for me. Thanks

huangapple
  • 本文由 发表于 2020年9月8日 13:57:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/63787884.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定