我一直在寻找这个问题,但我无法让它正常工作。让我解释一下。
我有一个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);
提前致谢!
答案 0 :(得分:31)
我发现我必须以不同的方式做事。
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文件,描述了其他应用程序可以读取的文件。
所以我将一个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
标记。否则它将无法工作。