【问题标题】:Open file in cache directory with ACTION_VIEW使用 ACTION_VIEW 打开缓存目录中的文件
【发布时间】:2014-05-23 13:10:31
【问题描述】:

我一直在寻找这个,但我无法让它正常工作。让我解释一下。

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

当我使用getExternalCacheDir() 方法时,在另一个应用程序中打开这些文件是没有问题的:

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

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

感谢这篇文章,我尝试实现 ContentProvider:How to open private files saved to the internal storage using 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);

提前致谢!

【问题讨论】:

    标签: android caching android-intent


    【解决方案1】:

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

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

    AndroidManifest.xml添加

    <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 文件,用于描述其他应用程序可以读取哪些文件。

    所以我在 res/xml 文件夹中添加了一个 file_paths.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 标志。否则将无法正常工作。

    【讨论】:

    • 我错过了 FLAG_GRANT_READ_URI_PERMISSION,谢谢!
    • 我也是,我错过了这个标志。救生员:)
    • 我错过了标志。它甚至在 Android 文档中提到过吗?
    • 感谢分享。我花了 2 个小时才解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 2019-08-02
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 2014-09-18
    相关资源
    最近更新 更多