以下是我在我的应用中尝试做的事情。我下载文件(docx,pptx,pdf,mov等)并将它们存储在File
中。下载文件后,我希望用户能够打开并阅读它。 我不希望用户能够修改File
!
以下是我试图实现这一目标的方法。
String uri = nameFileStatic + extension;
RestClientGetAsFile client = new RestClientGetAsFile(url, getActivity(), uri) {
@Override
protected void onPostExecute(File results) {
if (results != null) {
if (results.exists()) {
Uri path = Uri.fromFile(results);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(path, type); //type
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(DescriberAttachments.this.getActivity(),
"No Application Available to View file with extension " + extension, Toast.LENGTH_SHORT).show();
}
}
}
}
};
client.execute();
基本上,我在AsyncTask实例中下载文件。然后在onPostExecute()
方法中,我用Intent打开文件。
现在问题是:在哪里存储文件?这是我试过的:
getDir("SLIMS", Context.MODE_WORLD_READABLE ).getAbsolutePath() + "/Attachments/myfile.docx"
。在保存文件之前,我总是确保目录存在。 File directoryMain = new File(getDir("SLIMS", Context.MODE_PRIVATE).getAbsolutePath()); directoryMain.mkdir(); File directoryAttachments = new File( getDir("SLIMS", Context.MODE_PRIVATE).getAbsolutePath() + "/Attachments"); directoryAttachments.mkdir();
不幸的是,之后我无法打开文件...我收到了一条消息错误(来自Polaris Office)但在我的日志中找不到任何相关消息。
uri = getFilesDir() + "/Attachments/myfile.docx".
我得到了与上一点相同的错误。
uri = Environment.getExternalStorageDirectory() + "/Attachments/myfile.docx"
。这次我可以在Polaris Office中打开文件,但我无法将File
设为只读。我尝试了myFile.setReadOnly()
,myFile.setReadable(true)
和myFile.setWritable(false)
但我仍然可以在最后修改文件。
所以我想现在我仍然会将这些文件存储在SD卡中,但我对写入权限感到非常恼火。
有什么建议吗?
答案 0 :(得分:2)
在您的应用内创建ContentProvider
并启动查看器应用,并引用内容方案,例如content://com.mydomain.myapp/file/filename.jpg
。
答案 1 :(得分:0)
正如323go建议的那样,我实现了一个ContentProvider。我的代码来自CommonsWare's post。
这是我下载文件的代码。下载文件后,我将其保存为“ComingFromSLIMSDatabase”+扩展名。扩展名可以是docx,pptx,pdf等。下载文件后,我调用一个隐含Intent的Activity启动一个Activity,并给出内容Provider的uri。
String uri = nameFileStatic + extension;
RestClientGetAsFile client = new RestClientGetAsFile(url, getActivity(), uri) {
@Override
protected void onPostExecute(File results) {
if (results != null) {
if (results.exists()) {
results.setReadable(true);
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(AttachmentProvider.CONTENT_URI
+ "ComingFromSLIMSDatabase" + extension)));
} catch (ActivityNotFoundException e) {
Toast.makeText(DescriberAttachments.this.getActivity(),
"No Application Available to View file with extension " + extension, Toast.LENGTH_SHORT).show();
}
}
}
}
};
client.execute();
然后ContentProvider捕获该调用并打开我想要显示的文件。
public class FileProvider extends ContentProvider {
public static final Uri CONTENT_URI=Uri.parse("content://com.commonsware.android.cp.files/");
private static final HashMap<String, String> MIME_TYPES=new HashMap<String, String>();
static {
MIME_TYPES.put(".pdf", "application/pdf");
}
@Override
public boolean onCreate() {
File f=new File(getContext().getFilesDir(), "test.pdf");
if (!f.exists()) {
AssetManager assets=getContext().getResources().getAssets();
try {
copy(assets.open("test.pdf"), f);
}
catch (IOException e) {
Log.e("FileProvider", "Exception copying from assets", e);
return(false);
}
}
return(true);
}
@Override
public String getType(Uri uri) {
String path=uri.toString();
for (String extension : MIME_TYPES.keySet()) {
if (path.endsWith(extension)) {
return(MIME_TYPES.get(extension));
}
}
return(null);
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
String path = uri.getPath();
File f=new File(getContext().getFilesDir(),path);
if (f.exists()) {
return(ParcelFileDescriptor.open(f,
ParcelFileDescriptor.MODE_READ_ONLY));
}
throw new FileNotFoundException(uri.getPath());
}
@Override
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sort) {
throw new RuntimeException("Operation not supported");
}
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
throw new RuntimeException("Operation not supported");
}
@Override
public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
throw new RuntimeException("Operation not supported");
}
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
throw new RuntimeException("Operation not supported");
}
static private void copy(InputStream in, File dst) throws IOException {
FileOutputStream out=new FileOutputStream(dst);
byte[] buf=new byte[1024];
int len;
while((len=in.read(buf))>0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
使用此方法,即使文件存储在Context.getFilesDir()中,用户也可以打开该文件。现在我还是很困惑。因为如果我打开一个doc文件,我仍然可以修改它并将其保存在其他地方。目前它并不是一个理想的功能。
我想知道是否有人知道查看文件内容的方法,而不让其他应用程序将其保存在其他地方。