Java 从资产打开PDF时遇到的问题

Java 从资产打开PDF时遇到的问题,java,android,pdf,assets,Java,Android,Pdf,Assets,我在尝试从我的资产文件夹打开pdf(a.pdf)时遇到一些问题。 这是java代码: package com.tischer.alessandro.ecocardiochecklist; import android.content.Context; import android.content.Intent; import android.content.res.AssetManager; import android.net.Uri; import android.os.Bundle;

我在尝试从我的资产文件夹打开pdf(a.pdf)时遇到一些问题。 这是java代码:

package com.tischer.alessandro.ecocardiochecklist;


import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Bibliografia extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bibliografia);
        AssetManager assetManager = getAssets();

        InputStream in = null;
        OutputStream out = null;
        File file = new File(getFilesDir(), "a.pdf");
        try
        {
            in = assetManager.open("a.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() + "/a.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);
        }
    }

}
这是logcat:

11/10 11:52:42: Launching app
Cold swapped changes.
$ adb shell am start -n "com.tischer.alessandro.ecocardiochecklist/com.tischer.alessandro.ecocardiochecklist.SplashScreen" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Client not ready yet..Waiting for process to come online
Connected to process 3259 on device Nexus_5X_API_24 [emulator-5554]
I/InstantRun: Instant Run Runtime started. Android package is com.tischer.alessandro.ecocardiochecklist, real application class is null.

              [ 11-10 10:52:44.162  1489: 1510 D/         ]
              HostConnection::get() New Host Connection established 0x8d361440, tid 1510
W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
W/gralloc_ranchu: Gralloc pipe failed

                  [ 11-10 10:52:45.193  3259: 3259 D/         ]
                  HostConnection::get() New Host Connection established 0x9d027140, tid 3259


                  [ 11-10 10:52:45.239  3259: 3278 D/         ]
                  HostConnection::get() New Host Connection established 0x9d0d6d40, tid 3278
I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Swap behavior 1
D/OpenGLRenderer: endAllActiveAnimators on 0x90937d80 (RippleDrawable) with handle 0x9d07eb80
E/tag: MODE_WORLD_READABLE no longer supported
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.tischer.alessandro.ecocardiochecklist, PID: 3259
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tischer.alessandro.ecocardiochecklist/com.tischer.alessandro.ecocardiochecklist.Bibliografia}: android.os.FileUriExposedException: file:///data/user/0/com.tischer.alessandro.ecocardiochecklist/files/a.pdf exposed beyond app through Intent.getData()
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
                      at android.app.ActivityThread.-wrap12(ActivityThread.java)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6077)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
                   Caused by: android.os.FileUriExposedException: file:///data/user/0/com.tischer.alessandro.ecocardiochecklist/files/a.pdf exposed beyond app through Intent.getData()
                      at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799)
                      at android.net.Uri.checkFileUriExposed(Uri.java:2346)
                      at android.content.Intent.prepareToLeaveProcess(Intent.java:8933)
                      at android.content.Intent.prepareToLeaveProcess(Intent.java:8894)
                      at android.app.Instrumentation.execStartActivity(Instrumentation.java:1517)
                      at android.app.Activity.startActivityForResult(Activity.java:4224)
                      at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:48)
                      at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:75)
                      at android.app.Activity.startActivityForResult(Activity.java:4183)
                      at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:856)
                      at android.app.Activity.startActivity(Activity.java:4507)
                      at android.app.Activity.startActivity(Activity.java:4475)
                      at com.tischer.alessandro.ecocardiochecklist.Bibliografia.onCreate(Bibliografia.java:48)
                      at android.app.Activity.performCreate(Activity.java:6664)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
                      at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:154) 
                      at android.app.ActivityThread.main(ActivityThread.java:6077) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 

我运行的是安卓7.0,但旧版本的应用程序也会崩溃。。。问题出在哪里?

您将文件复制到应用程序的私有目录,其他应用程序无法访问该目录。然后您尝试在另一个应用程序中打开此文件(它只是无法从应用程序的私有目录访问该文件)

要解决此问题,您只有几个选项:

  • 将文件复制到某个公共目录,如
    Environment.getExternalStorageDirectory()
  • 在应用程序中实现
    ContentProvider
  • 第一条路比较容易,如果我这样做的话,我会走这条路。

    第二种方式更正确,但对我来说显然是过热。

    我想你应该先了解一下上下文

    Context context=getApplicationContext();
    
     AssetManager assetManager = context.getAssets();
    

    问题出在哪里?FileUriExposedException-看起来像是自解释的异常。。。已经问过很多次了。。。显而易见的解决方案是使用FileProvider抱歉,但我是android开发新手。。。我仍然不明白我必须在代码中更改什么。。。你能帮我吗?在FileUri上进行internet搜索ExposedExceptioni将file://修改为content://如此处所述:但它仍然会破坏internet搜索点中的第二个链接,从而与此处的问题完全相同,因此有了答案…我想实现内容提供商,也是因为我创建此应用程序是因为我想学习,所以我想把事情做得尽可能好。你能帮我插入内容提供者吗?我发现:,这似乎很好,但对我不起作用…@AlessandroTischer,我可以,但它与你的问题主题不完全匹配。我想你应该问一个新问题。但首先,你应该用谷歌搜索一下,因为互联网上已经有关于内容提供商的课程,我没有理由从其中一个网站上复制粘贴代码lessons@AlessandroTischer,该库主题为grait,但实际上什么
    对您不起作用呢(assets/public_pdfs/filename.pdf.mp3)。该应用程序打开pdf查看器,但无法看到pdf…(我无法附加日志,因为我无法在模拟器上安装pdf阅读器)@Vlad