【问题标题】:Can't open file from internal storage. Code crashing in Android 7.1无法从内部存储打开文件。 Android 7.1 中的代码崩溃
【发布时间】:2016-12-13 13:50:48
【问题描述】:

以下代码适用于 Android 5、6。但它在 Android 7.1 上崩溃

Intent intent1 = new Intent(Intent.ACTION_VIEW, Uri.parse(""));
        intent1.setDataAndType(Uri.parse("file:///" + "sdcard/path/"+fName), "application/pdf");
        startActivity(intent1);

Logcat:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.amey.newunipunebuddy, PID: 19574
              android.os.FileUriExposedException: file:///sdcard/unipunebuddy_data/timetables/Timetable.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:9022)
                  at android.content.Intent.prepareToLeaveProcess(Intent.java:8983)
                  at android.app.Instrumentation.execStartActivity(Instrumentation.java:1519)
                  at android.app.Activity.startActivityForResult(Activity.java:4225)
                  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:4522)
                  at android.app.Activity.startActivity(Activity.java:4490)
                  at com.amey.newunipunebuddy.Timetable$DownloadTask.onPostExecute(Timetable.java:498)
                  at com.amey.newunipunebuddy.Timetable$DownloadTask.onPostExecute(Timetable.java:415)
                  at android.os.AsyncTask.finish(AsyncTask.java:660)
                  at android.os.AsyncTask.-wrap1(AsyncTask.java)
                  at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:677)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:154)
                  at android.app.ActivityThread.main(ActivityThread.java:6145)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)

W/DynamiteModule:找不到 com.google.firebase.auth 的本地模块描述符类。 应用程序终止。

【问题讨论】:

  • 大多数 Android 设备上没有名为 /sdcard 的路径。这就是为什么开发人员应该永远不要硬编码路径。除此之外,使用 LogCat 检查与您的应用关联的 Java 堆栈跟踪。
  • 那么,解决办法是什么?
  • 请张贴你的logcat
  • 请查看更新后的问题。我已经添加了 logcat。
  • 如果您发现异常,您的应用不必崩溃。

标签: android performance android-sdcard android-internal-storage


【解决方案1】:

从 Android 6.0 开始,您需要提示用户授予写入外部存储的权限 (Manifest.permission.WRITE_EXTERNAL_STORAGE) - https://developer.android.com/training/permissions/requesting.html(尽管有标题,但假设它正在写入外部存储给定 /sdcard 的使用? )

【讨论】:

  • 我已申请许可。
  • 某些手机(例如 Nexus 系列)使用 /sdcard 作为用户数据的内部存储。操作系统仍将其解释为外部存储设备。 OP可能在他们之间有误解。
【解决方案2】:

Google documentation on external storage

您必须使用getExternalFilesDir()。查看其他选项(图片、音乐等)的链接

还要检查您的权限,我不记得什么时候了,但现在 Android 要求您在应用启动时验证权限。也许它与不同的系统有关。 (5, 6,...)

【讨论】:

    【解决方案3】:
     FileUriExposedException
    

    您将文件的 uri 暴露给外界。哪种牛轧糖不允许您再做任何事情。

    使用文件提供程序或文件内容提供程序来提供文件。

    【讨论】:

    • 我该怎么做?我能够完美地保存文件。但是打不开。
    • 你也可以打开它们。你的应用可以。但是您不能使用意图将文件路径传输到另一个应用程序。您必须使用文件提供程序来提供文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    相关资源
    最近更新 更多