在onActivityResult中使用相机意图捕获的图片文件空了一段时间

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在onActivityResult中使用相机意图捕获的图片文件空了一段时间相关的知识,希望对你有一定的参考价值。

我有一个非常奇怪的错误试图通过意图拍照。活动代码(稍微简化):

private void startCapture() throws IOException {
    // Create output file
    final File photoFile = makePhotoFile();
    _photoPath = photoFile.getAbsolutePath();

    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    /* IMPORTANT NOTE TO READERS
     * As of android N (which went out shortly after I posted this question),
     * you cannot use Uri.fromFile this way anymore.
     * You should use a FileProvider. */
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));

    if (cameraIntent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(cameraIntent, REQUEST_CODE_IMAGE_CAPTURE);
    }
    else {
        deleteCurrentPhoto();
    }
}

private File makePhotoFile() throws IOException {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(new Date());
    String imageFileName = "MyPhoto_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    return File.createTempFile(imageFileName, ".jpg", storageDir);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if(requestCode == REQUEST_CODE_IMAGE_CAPTURE) {
        if(resultCode == RESULT_OK) {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            final byte[] buffer = new byte[2048];
            int read;
            byte[] photoBytes;
            try(FileInputStream fis = new FileInputStream(_photoPath)) {

                for(int i=0; i<10; i++) { // Always working after first iteration though
                    if( (read = fis.read(buffer)) <= 0) {
                        // Why does this get printed once ??
                        Log.w("my.package.my.app", "Empty for now...");
                    }
                    else {
                        Log.w("my.package.my.app", "Working now !");
                        bos.write(buffer, 0, read);
                        break;
                    }
                }

                while((read = fis.read(buffer)) >= 0) {
                    bos.write(buffer, 0, read);
                }

                photoBytes = bos.toByteArray();
            } // Catch clauses removed for simplicity

            // Everything working OK after that (photoBytes decodes fine with the BitmapFactory)
        }
    }
}

并且日志输出:

03-01 16:32:34.139 23414-23414 / my.package.my.app W / my.package.my.app:现在为空...... 03-01 16:32:34.139 23414-23414 / my.package .my.app W / my.package.my.app:现在工作!

正如您所看到的,在拍摄照片后的onActivityResult中,第一次调用FileInputStream.read时文件为空......然后就可以正确读取了!我认为当相机意图返回到调用活动时,文件将被写入。有什么延迟吗?我也惊讶地发现它在for循环中只进行了一次迭代后总是工作。

请注意,如果我在onActivityResult的开头放置一个断点,它会延迟执行一点,并且一切正常(在第一次尝试时正确读取文件)。

我在Android 6.0.1下使用股票相机应用程序的股票Nexus 6P。


重要编辑:对于Android N,你应该使用FileProvider而不是像之前那样使用Uri.fromFile。见this blog postthese explanations from the Android team

答案

File.createTempFile.不要创建该文件。您唯一需要的是文件名。文件路径。 Camera应用程序将创建该文件。因此,重命名您的函数以创建新文件名。

以上是关于在onActivityResult中使用相机意图捕获的图片文件空了一段时间的主要内容,如果未能解决你的问题,请参考以下文章

使用相机意图时未调用 OnActivityResult()?

在onActivityResult中使用相机意图捕获的图片文件空了一段时间

在棒棒糖中通过相机拍摄照片后,在 onActivityResult() 方法中获取空意图

启动相机意图时未调用 onActivityResult?

相机意图resultCode始终为Nougat返回取消

在 onActivityResult 中使用相机时出现问题