我有一些要求来保护一些敏感数据。这些数据从一个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 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 加载。
VIEW content:// Intent
的情况下使用Content Resolver,而实际上它确实会这样做。我现在正在努力弄清楚为什么我的ContentProvider没有被回调。 - Neal Sanche