使用 ACTION_VIEW 打开缓存目录中的文件

2023-11-22

我已经搜索这个有一段时间了,但我无法使其正常工作。让我解释。

我有一个保存文件的 Android 应用程序(图像、文档……)在缓存目录中。起初我曾经getExternalCacheDir()方法并将它们保存在那里,但因为它应该缓存在没有 SD 卡的设备上,所以我必须使用getCacheDir().

当我以前getExternalCacheDir()方法,在另一个应用程序中打开这些文件是没有问题的,如下所示:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), mimetype);

但当使用getCacheDir(),这些文件保存在应用程序沙箱中,无法从应用程序外部访问。所以我谷歌搜索它并来到 **ContentProvider。 ContentProvider 使得使用外部应用程序打开私有文件成为可能。但当我尝试实现它时,它不起作用。

由于这篇文章,我尝试实现 ContentProvider:如何使用Intent.ACTION_VIEW打开保存到内部存储的私人文件?但没有成功。

package com.myapplication.providers;

import java.io.File;
import java.io.FileNotFoundException;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;

public class FileProvider extends ContentProvider {

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        File privateFile = new File(getContext().getCacheDir(), uri.getPath());
        return ParcelFileDescriptor.open(privateFile, ParcelFileDescriptor.MODE_READ_ONLY);
    }

    @Override
    public int delete(Uri arg0, String arg1, String[] arg2) {
        return 0;
    }

    @Override
    public String getType(Uri arg0) {
        return null;
    }

    @Override
    public Uri insert(Uri arg0, ContentValues arg1) {
        return null;
    }

    @Override
    public boolean onCreate() {
        return false;
    }

    @Override
    public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
            String arg4) {
        return null;
    }

    @Override
    public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
        return 0;
    }
}

将此提供程序添加到应用程序清单中

<provider
    android:name="com.myapplication.providers.FileProvider"
    android:authorities="com.myapplication"
    android:exported="true" />

并使用此代码打开文件:

Uri uri = Uri.parse("content://com.myapplication/" + filename);

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(uri, mimetype);

提前致谢!


我发现我必须以不同的方式做事。

v4 支持库提供了一个可以使用的 FileProvider 类,而不是创建我自己的 ContentProvider。

In AndroidManifest.xml add

<application ...>

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="be.myapplication"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

</application>

FILE_PROVIDER_PATHS 是一个 xml 文件,描述其他应用程序可以读取哪些文件。

因此,我将 file_paths.xml 文件添加到 res/xml 文件夹中。

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

然后您唯一要做的就是创建并启动显示文件的意图。

File file = new File(getCacheDir(), "test.pdf");

Uri uri = FileProvider.getUriForFile(context, "be.myapplication", file);

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(uri, "application/pdf");

startActivity(intent);

事实上就是这样。

重要的: 请不要忘记设置FLAG_GRANT_READ_URI_PERMISSION意图的标志。否则它将无法工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 ACTION_VIEW 打开缓存目录中的文件 的相关文章

随机推荐

  • 安装 tabulizer 包时遇到问题

    我使用以下代码来安装tabulizer包裹 ghit install github c ropenscilabs tabulizerjars ropenscilabs tabulizer INSTALL opts no multiarch
  • vb.net错误:由于其保护级别而无法访问

    我是第一次使用 vb net 代码 但我有 5 年的 C 经验 从以前的开发人员那里得知 服务器上的代码运行良好 没有任何错误 但是当我打开网站文件夹 该网站没有解决方案文件 时 我尝试构建该网站 然后得到了大量错误说 未声明 labelC
  • 如何用python将协议号转换为名称?

    tcp udp等协议都是用数字来表示的 import socket socket getprotocobyname tcp 上面的代码将返回 6 如果我知道协议号 如何获取协议名称 我想说几乎肯定有比这更好的方法 但是所有协议名称 和值 都
  • 如何从 Windows 卸载 mongodb

    我看到一个教程说要运行这个 C mongodb bin mongod exe config C mongodb mongod conf remove 但该命令不起作用 因为没有mongod conf文件位于我的 Windows 中的 mon
  • Eclipse CVS 变更列表

    有没有办法查看 eclipse 项目中所有最近更改的文件 包括其他 CVS 用户最近更改的文件 谢谢 这里还有一个 Eclipse 变更日志插件 http code google com a eclipselabs org p change
  • svn 签出时“网络连接意外关闭”

    当我尝试结账时 svn checkout svn ssh serveradmin email protected home 87292 data svn repository trunk 我收到这个 无用的 错误 svn 网络连接意外关闭
  • pycharm 中的“预期语句结束”[重复]

    这个问题在这里已经有答案了 为什么我会收到此错误 请参阅 linting 说 预计声明结束 在pycharm中 我对 python 很陌生 尝试在 Python3 中使用括号进行打印 即print x 代替print x
  • 在间隔列表中搜索间隔重叠?

    假设 a b 表示从 a 到 b 的实线上的区间 a 给定一个间隔列表 x1 y1 x2 y2 找到与 x y 重叠的所有此类间隔的最有效方法是什么 显然 我可以尝试每一个并在 O n 内得到它 但我想知道是否可以以某种巧妙的方式对间隔列表
  • 错误:(59, 8) 错误:无法访问 android.support.v4.app.ActivityCompatApi23 的 ActivityCompatApi23 类文件。

    这是我的 build gradle apply plugin com android application android compileSdkVersion 25 buildToolsVersion 26 0 2 android con
  • 如何使用 SelectionModel 以编程方式选择材质树节点?

    我有一棵带有复选框的树 我们在这里使用 Material 的例子 我希望开始检查水果节点 如何检查这些节点 我看到SelectionModel has a select 示例传递节点的方法 但在示例中 构成树的数据是一个数组TodoItem
  • Android 中的屏幕亮度值

    如何获取活动的当前屏幕亮度 以下方法可以很好地通过调用将亮度设置为最大setBrightness 100 private void setBrightness int brightness WindowManager LayoutParam
  • 如何在 Windows Azure 辅助角色中安排任务

    我运行一个简单的 Azure Worker 角色 每天中午 12 点执行一项任务 下面是完成此操作的代码 public override void Run try while true int time Convert ToInt32 Da
  • Keydown 哪个不工作 Chrome 扩展

    我一直在为谷歌扩展的想法而苦苦挣扎 而你一如既往地是我最后的希望 好吧 我想单击 chrome 扩展上的按钮 这将导致页面扩展上的 keydown 模拟正在运行 我认为 chrome 在我的想法上有一些安全问题 它会阻止键盘模拟 使事件 i
  • 如何获得选择最短旋转方向的角度

    我的游戏中有一个角色必须平滑旋转才能达到所需的角度 考虑angle作为当前角度和touchAngle作为所需的角度 始终在 0 到 360 之间 我想在每次游戏更新中将 1 1 添加到当前角度以获得所需的角度touchAngle 问题是首先
  • 提交响应后是否可以从 servlet 过滤器转发或重定向?

    逻辑是过滤器被命中 条件不为真 所以它通过过滤器链 提交响应后 过滤器被命中 并且条件现在为真 请求属性已设置 它进去执行转发 但页面从未转发 我知道这与提交的响应有关 因为我测试了它在第一次到达链之前转发的不同逻辑 并且它确实转发成功 p
  • 如何开发具有混响功能的 iPhone 应用程序?

    我正在开发 iPhone 应用程序 如音频处理 我必须给音频添加一些效果 如果是桌面应用程序 有很多选择 我们可以获得很好的例子和完整的项目 比如大胆 但我想为 iPhone 开发 我有一个带有混响选项的应用程序 看看下面的链接 只是我看
  • 为什么 .NET 创建新的子字符串而不是指向现有字符串?

    从使用 Reflector 的简要观察来看 它看起来像String Substring 为每个子字符串分配内存 我的说法正确吗 我认为这没有必要 因为字符串是不可变的 我的根本目标是创建一个IEnumerable
  • 在 Windows 中更改模拟器电池电量

    如何更改 Windows 操作系统中模拟器的电池电量 从 50 更改为 70 且不充电 有一些指南 但它们都是针对 Ubuntu 的 Windows 支持telnet从命令提示符处 至少在 XP 和 Vista 上 如果您在其他 Windo
  • 从 FOP 的 JAR 加载字体

    我有一个 TTF 字体fonts我的应用程序位于 JAR 目录中 myapp jar fop config xml font ttf 我这样创建我的 FOP FopFactory fopFactory FopFactory newInsta
  • 使用 ACTION_VIEW 打开缓存目录中的文件

    我已经搜索这个有一段时间了 但我无法使其正常工作 让我解释 我有一个保存文件的 Android 应用程序 图像 文档 在缓存目录中 起初我曾经getExternalCacheDir 方法并将它们保存在那里 但因为它应该缓存在没有 SD 卡的