为什么 Android 打开文件意图会在打开图像时挂起?

Why would an Android Open File intent hang while opening an image?

我的问题:openFile() 次 Intent 尝试 StartActivityForResult 时,应用程序挂起并出现空白屏幕和圆形光标。文件存储到 app.

我做了什么: 在这个问题之前和之后,我研究了如何使用 Intents 打开文件。我发现了许多相似但不同的方法,并使用了文字示例或各种示例的组合来查看我是否可以找到并解决问题(请参见下面的一些)。我没有收到我发现的任何类型的错误消息,我之前遇到过 FileUriExposedException 但已解决。这些文件存储在应用程序中,这可能是一个权限问题,我已经尝试过我所知道的,包括更新清单以进行外部读写,并在访问意图上添加了一个标志设置。

我正在尝试做的事情:我正在尝试学习如何使用简单的 JPG 图像通过 intent 打开文件,然后最终扩展到打开各种文件类型了解如何操作。

下面是我正在使用的当前代码,它包含一个我尝试代替 "image/jpeg" 的 MimeTypeMap,以防我的语法在 MIME 类型上不正确,这似乎没有影响.

private void openFile(Uri uri, String fName) {

        MimeTypeMap myMime = MimeTypeMap.getSingleton();
        String mimeType = myMime.getMimeTypeFromExtension(getUpperBound(fName));

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.parse("content://" + uri), "image/jpeg");
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivityForResult(intent, 2);
    }

下面是导致问题挂起且永远无法打开的图片:

我试过的一些参考链接:

https://developer.android.com/guide/components/intents-common

ACTION_VIEW intent for a file with unknown MimeType

http://www.androidsnippets.com/open-any-type-of-file-with-default-intent.html

尝试使用 origin Uri 本身:

 intent.setDataAndType(uri, "image/jpeg");

结合 S-Sh 考虑使用 FileProvider 的第二个建议,我能够解决我的问题。我不得不进行一些改进并最终完成以下工作。我还提供了我使用的来源的链接。

解决方案的上下文:

作为对我的 Android 应用程序中此解决方案上下文的未来读者的说明,通过单击 [=16] 中的 "clickable" TableRow 启动以下代码=]. TableLayout 将每个文件名和文件 ID 列为 TableRow。单击一行后,将获取所选 TableRow 的 onClick 方法获取文件名,并使用 File class 和 FileProvider 并传递文件名以创建 Uri.然后将此 Uri 传递给我创建的 openFile(Uri uri) 方法,封装(可以这么说)用于打开文件的 Intent

代码

将 FileProvider 添加到 AndroidManifest.xml' within the` 标签:

<provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="com.mistywillow.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
    <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
</provider>

res 目录中创建 file_paths.xmlxml 目录 (res/xml/):

<?xml version="1.0" encoding="utf-8"?>
   <paths xmlns:android="http://schemas.android.com/apk/res/android">
      <files-path name="myFiles" path="." />
   </paths>

onClick 捕获文件名并准备要传递给 openFile() 的 Uri:

    row.setOnClickListener(v -> {

        TableRow tablerow = (TableRow) v;
        TextView sample = (TextView) tablerow.getChildAt(1);
        String result = sample.getText().toString();

        File filePaths = new File(getFilesDir().toString());
        File newFile = new File(filePaths, result);
        Uri contentUri = getUriForFile(getApplicationContext(), "com.mydomain.fileprovider", newFile);
        openFile(contentUri);

    });

包含打开文件的 Intent 的 openFile(Uri uri) 方法:

private void openFile(Uri uri){
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(uri);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivityForResult(intent, 2);
}

引用的链接:

https://developer.android.com/reference/androidx/core/content/FileProvider