我有一些保护敏感数据的要求。数据从URL下载为PDF,并使用以下代码保存为应用程序专用文件:
public File downloadPDF(final Context fileContext, Uri reportUri, final String fileName)
{
try
{
HttpGet get = new HttpGet(reportUri.toString());
File file = httpClient.execute(get, new ResponseHandler<File>()
{
@Override
public File handleResponse(HttpResponse response) throws ClientProtocolException, IOException
{
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
response.getEntity().writeTo(fileContext.openFileOutput(fileName, Context.MODE_WORLD_READABLE));
return fileContext.getFileStreamPath(fileName);
}
return null;
}
});
return file;
}
catch (IOException e)
{
Log.e(TAG, "Unable to download report.", e);
}
return null;
}
现在,我想要做的是将其更改为使用Context.MODE_PRIVATE并创建一个ContentProvider,以便我的应用程序可以完全控制将此文件共享到PDF阅读器(如Adobe Reader)。这可能吗?我目前使用以下代码将报告URI传递给当前配置的PDF阅读器。
// Fire up a PDF viewer intent for the URL.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
同样的工作是通过ContentProvider类型的URI吗? content:// package / fileid类型的URI?我明天会尝试一下,看看能否,但如果有人知道只允许使用file:// URI,那将非常有帮助。
更新
通过实现覆盖以下方法的ContentProvider子类,我能够令人满意地解决我的问题:
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException
{
// The filename is the path in the URI without the initial slash.
String fileName = uri.getPath().substring(1);
File file = getContext().getFileStreamPath(fileName);
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
}
然后,当我触发查看意图时,它会被重写为以下内容:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.withAppendedPath(Uri.parse("content://providername/"),filePath);
intent.setData(uri);
startActivity(intent);
就我而言,我使用Adobe Reader,它正确地实现了从content://
URI的加载。
答案 0 :(得分:5)
同样的工作是通过ContentProvider类型的URI吗? content:// package / fileid类型URI?
它应该。您需要ContentProvider
返回application/pdf
getType()
。并且,某些PDF阅读器可能无法处理content://
Uri
值。
您可以做的是ContentProvider
,然后使用PackageManager
查看ACTION_VIEW
{{1}上是否有任何理解Intent
content://
Uri
}}。如果有什么东西响应,你就会被设定。如果没有,您可以回过头来使文件具有世界可读性并使用您当前的实现。或者,由于将文件更改为世界可读可能会很麻烦,您可以尽早运行测试(例如,当您的应用启动时),使用Uri
支持的一些剪贴簿ContentProvider
,这样您就可以了知道下载时要采取的路线。
答案 1 :(得分:1)
没有内容提供商不保护文件
实际上,应用程序可能对内容提供程序中的文件执行的第一件事就是在其缓存目录中创建一个临时副本。我想你应该重温这个。