如何在处理动作发送意图的应用程序中获取通过EXTRA_STREAM接收的数据大小?

时间:2013-09-09 15:53:14

标签: android android-intent inputstream android-contentprovider

当另一个应用程序将文件发送到我的应用程序时,我通过intent.getExtras().get(EXTRA_STREAM)属性获得了一个Uri。然后,我可以使用输入流获取文件的字节:new BufferedInputStream(activity.getContentResolver().openInputStream(uri));

到目前为止,一切都还可以。现在我想向我的用户展示一些进展,但是我不确定如何在不事先读取流的情况下获取文件的总字节数(这会破坏进度条的整个目的) )...

我尝试了ParcelFileDescriptor fileDesc = activity.getContentResolver().openFileDescriptor(uri, "r");,但这仅适用于file://...类型的uris。

例如,如果我从Skydrive收到一个文件,我会收到一个content://.. Uri,如:content://com.microsoft.skydrive.content.external/external_property/10C32CC94ECB90C4!155/Sunset.480p.mp4

在这样的Uri上,我(不出所料)得到了“FileNotFoundException:Not a whole file”异常。

获得我将获得的数据流总大小的确定方法?

2 个答案:

答案 0 :(得分:9)

即使InputStream.available()(几乎)从来都不是推荐的获取文件大小的方法,但在您的情况下它可能是一个可行的解决方案。

内容已在本地提供。不涉及服务器。因此,以下内容应返回确切的文件大小:

try {

    InputStream inputStream = getContentResolver().openInputStream(uri);

    Log.i("TEST", "File Size: " + inputStream.available());

} catch (FileNotFoundException fnfe) {

    fnfe.printStackTrace();

} catch (IOException ioe) {

    ioe.printStackTrace();

}

我使用SkyDrive和Dropbox进行了测试。返回的文件大小是正确的。

答案 1 :(得分:1)

除了读取整个流之外,没有获取流大小的通用解决方案。这很容易证明:可以创建一个Web服务器,对于某些URL,它会生成随机时间终止的随机文本流。 (事实上​​,我确信这些URL存在,无论是否设计:-)在这种情况下,直到最后一个字节生成才知道流的大小,从不心灵收到了

因此,如果服务器发送了流大小,则必须以特定于应用程序的方式发送。

我从未使用过SkyDrive,但谷歌搜索其API却出现this link,其中有以下Android Java应用示例:

public void readFile() {
    String fileId =  "file.a6b2a7e8f2515e5e.A6B2A7E8F2515E5E!141";
       client.getAsync(fileId, new LiveOperationListener() {
        public void onError(LiveOperationException exception, LiveOperation operation) {
               resultTextView.setText("Error reading file: " + exception.getMessage());
           }
           public void onComplete(LiveOperation operation) {
            JSONObject result = operation.getResult();
            String text = "File info:" +
                "\nID = " + result.optString("id") +
                "\nName = " + result.optString("name");
               resultTextView.setText(text);
           }
       });
}

基于该页面上的其他示例,我会猜测类似result.optString("size")(或者result.optInt("size")?)这样的内容会为您提供文件的大小。