1

这是我在我的应用程序中尝试做的事情。我下载文件(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".我得到了与前一点相同的错误。

  • 乌里= Environment.getExternalStorageDirectory() + "/Attachments/myfile.docx"。这次我可以在 Polaris Office 中打开文件,但我无法将其File设为只读。我试过了myFile.setReadOnly()myFile.setReadable(true)myFile.setWritable(false)最后我仍然能够修改文件。

所以我想现在我仍然会将这些文件存储在 sdcard 中,但我真的对写权限感到恼火。

有什么建议吗?

4

2 回答 2

2

在您的应用程序内部创建一个ContentProvider并使用对内容方案的引用启动查看器应用程序,例如content://com.mydomain.myapp/file/filename.jpg.

于 2013-04-12T14:11:05.110 回答
0

正如323go建议的那样,我实现了一个 ContentProvider。我的代码来自CommonsWare 的帖子

这是我下载文件的代码。下载文件后,我将其保存为“ComingFromSLIMSDatabase”+ 扩展名。扩展名可以是 docx、pptx、pdf 等。下载我的文件后,我会调用带有隐式 Intent 的 Activity 并提供内容提供者的 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 文件,我仍然可以修改它并将其保存在其他地方。目前这不是一个理想的功能。

我想知道是否有人知道在不让另一个应用程序将其保存在其他地方的情况下查看文件内容的方法

于 2013-04-16T13:59:45.667 回答