安卓手机无法获取拍摄照片的大小.. 是一个bug吗?

3
在我的应用程序中,我有选择/拍摄照片、音频或视频文件的选项。我将每个文件路径写在自己的字符串中并执行一些操作。另外,我使用以下方法确定文件大小:
    public double getSize(String path) {

    File file = new File(path);

    if (file.exists()) {
        long size = file.length();

        return size;
    } else {
        Log.e("zero size", "the file size is zero!");
        return 0;

    }

}

它工作得很好,但是在尝试获取拍摄照片的大小时,该方法总是返回0。

   double s = 1.0 * getSize(taken_pic_path) / 1024 / 1024;

taken_pic_path 是 100% 正确的,有以下三个原因支持:1)我使用相同的路径创建预览时可以工作;2)我通过 Toast 显示该路径,看起来是正确的;3)我使用 file.exists() 检查了该路径,返回 true。我还尝试了以下操作:

File file = new File(taken_pic_path);
if (file.exists()){
   double test = file.lenght();
}

我总是得到一个零作为文件大小...同样的技术在拍摄视频、拍摄音频、选择图片/视频/音频时都可以完美地工作,但是当我尝试获取拍摄照片的大小时,只能得到0。我就是想不通原因...有什么想法吗?

编辑 我进行了所有可能的检查:

 if (file.exists()) {

            String b = file.getPath();
            boolean r = file.canRead();
            boolean w = file.canWrite();
            double d = file.length();
            Toast.makeText(getApplicationContext(), b, Toast.LENGTH_LONG)
                    .show();
            Toast.makeText(getApplicationContext(), Boolean.toString(r),
                    Toast.LENGTH_LONG).show();

            Toast.makeText(getApplicationContext(), Boolean.toString(w),
                    Toast.LENGTH_LONG).show();
            Toast.makeText(getApplicationContext(), Double.toString(d),
                    Toast.LENGTH_LONG).show();

        }

输出:正确的文件路径 / 真 / 真 / 0.0
这是什么鬼......


在你进行除法运算之前,它的值是否为0? - njzk2
我之前被告知要使用double,否则当结果小于1时会得到0。然后我使用了一个方法将其四舍五入到2位小数。是的,它已经是零了。在该路径下使用getSize始终返回0。 - Droidman
1
小于1?长度以字节为单位,文件长度小于1字节似乎不太可能... - njzk2
刚刚拍了一张照片:/mnt/sdcard/DCIM/Camera/1356018878923.jpg - Droidman
当您进行步进操作时,getSize()返回零是因为文件大小报告为零还是因为file.exists()返回false?这两个路径都会返回零。顺便说一下,不需要double。file.length()返回一个long int。 - Simon
显示剩余3条评论
2个回答

0

刚刚遇到了同样的问题。对于某些设备,当Android媒体提供程序通知提供程序添加新内容时,文件仍然报告长度为零。只有大约半秒钟后才会报告正确的长度。

我认为这是一个错误。

我的解决方法很丑陋:

/**
 * Careful: this method may take a few seconds to complete for some photos.
 * <p>
 * Do not attempt to read {@link Images.Media.SIZE}, since it is known to return
 * wrong results (up to 5% off). We used to use it until 2.2.0.
 * 
 * @return the file size, or zero if the file does not exist
 * @see #isFileReallyAvailable
 */
private static long getFileSize(File file) {
    if (!file.exists()) {
        return 0;
    } else {
        if (file.length() > 0) {
            return file.length();
        } else if (isFileReallyAvailable(file)) {
            return file.length();
        } else {
            Log.w(TAG, "The file " + file.getName() + " was not available. Will report size 0");
            return 0;
        }
    }
}

/**
 * Is this file really available to be read? That is, does it have a non-zero length?
 * <p>
 * Seems like
 * some photo-taking apps (even the standard one in some devices) notify the Media provider
 * too soon, so {@code file.getLength()} is still zero. In those cases, we will retry
 * a few times after some sleeps. Related story: #59448752
 * <p>
 * Careful: this method may take a few seconds to complete for some photos, so do not call
 * it from the GUI thread.
 * <p>
 * Also, do not attempt to read {@link Images.Media.SIZE}, since it is known to return
 * wrong results (up to 5% off). We used to use it until 2.2.0.
 * 
 * @return the file size, or zero if the file does not exist
 */
private static boolean isFileReallyAvailable(File file) {
    boolean available = false;
    final long timeout = 2000; // In the Nexus 4 I tried, 700 ms seems like the average
    final long sleepEveryRetry = 100;
    long sleepSoFar = 0;
    do {
        try { Thread.sleep(sleepEveryRetry); } catch (Exception e) {}
        final long fileSize = file.length();
        available = fileSize > 0;
        sleepSoFar += sleepEveryRetry;
        Log.v(TAG, "The file " + file.getName() + " is still not valid after " + sleepSoFar + " ms");
    } while (!available && sleepSoFar < timeout);

    return available;
}

这些是我能够重现此问题的唯一手机(运行4.3的Nexus 4)生成的日志:

10-30 18:17:03.324: V/Scanner(21167): The file IMG_20131030_181702.jpg is still not valid after 100 ms
10-30 18:17:03.424: V/Scanner(21167): The file IMG_20131030_181702.jpg is still not valid after 200 ms
10-30 18:17:03.524: V/Scanner(21167): The file IMG_20131030_181702.jpg is still not valid after 300 ms
10-30 18:17:03.634: V/Scanner(21167): The file IMG_20131030_181702.jpg is still not valid after 400 ms
10-30 18:17:03.734: V/Scanner(21167): The file IMG_20131030_181702.jpg is still not valid after 500 ms
10-30 18:17:03.774: V/Scanner(21167): Found a new undiscovered image in the local phone: upload wrapper for IMG_20131030_181702.jpg (ID = <none>, 25 KB, JUST_DISCOVERED) (source item ID is 3126)

10-30 18:17:06.537: V/Scanner(21167): The file IMG_20131030_181705.jpg is still not valid after 100 ms
10-30 18:17:06.637: V/Scanner(21167): The file IMG_20131030_181705.jpg is still not valid after 200 ms
10-30 18:17:06.737: V/Scanner(21167): The file IMG_20131030_181705.jpg is still not valid after 300 ms
10-30 18:17:06.837: V/Scanner(21167): The file IMG_20131030_181705.jpg is still not valid after 400 ms
10-30 18:17:06.937: V/Scanner(21167): The file IMG_20131030_181705.jpg is still not valid after 500 ms
10-30 18:17:07.038: V/Scanner(21167): The file IMG_20131030_181705.jpg is still not valid after 600 ms
10-30 18:17:07.058: V/Scanner(21167): Found a new undiscovered image in the local phone: upload wrapper for IMG_20131030_181705.jpg (ID = <none>, 24 KB, JUST_DISCOVERED) (source item ID is 3127)

10-30 18:17:07.969: V/Scanner(21167): The file IMG_20131030_181707.jpg is still not valid after 100 ms
10-30 18:17:08.069: V/Scanner(21167): The file IMG_20131030_181707.jpg is still not valid after 200 ms
10-30 18:17:08.169: V/Scanner(21167): The file IMG_20131030_181707.jpg is still not valid after 300 ms
10-30 18:17:08.289: V/Scanner(21167): The file IMG_20131030_181707.jpg is still not valid after 400 ms
10-30 18:17:08.389: V/Scanner(21167): The file IMG_20131030_181707.jpg is still not valid after 500 ms
10-30 18:17:08.499: V/Scanner(21167): The file IMG_20131030_181707.jpg is still not valid after 600 ms
10-30 18:17:08.509: V/Scanner(21167): Found a new undiscovered image in the local phone: upload wrapper for IMG_20131030_181707.jpg (ID = <none>, 20 KB, JUST_DISCOVERED) (source item ID is 3128)

0

尝试

double s = 1.0 * (double) getSize(taken_pic_path) / 1024.0 / 1024.0;

文件 file = new File(taken_pic_path);如果(file.exists()){ Toast.makeText(getApplicationContext(), "文件存在!", Toast.LENGTH_LONG).show(); s = 1.0 * (double) getSize(taken_pic_path) / 1024.0 / 1024.0; Toast.makeText(getApplicationContext(), Double.toString(s), Toast.LENGTH_LONG).show(); } 结果:文件存在!0.0 - Droidman
文档显示:File.length():此抽象路径名表示的文件的字节数,如果文件不存在,则为0L。看起来您没有正确保存图像。 - alistair
图像已经被相机应用自动保存。如果没有保存,我就无法从同一路径创建位图以用作预览,但这并不是事实。位图已经正确创建。 - Droidman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接