拍照总是在onActivityResult(..)中返回RESULT_CANCELED(0)

mad*_*dim 1 android android-camera firebase-storage

我尝试使用firebase存储示例应用程序构建存储应用程序,当我拍照时,我总是在onActivityResult(..)中得到RESUL_CANCELED.这是代码:

@AfterPermissionGranted(RC_STORAGE_PERMS)
private void launchCamera() {
    Log.d(LOG_TAG, "launchCamera");

    // Check that we have permission to read images from external storage.
    String perm = Manifest.permission.WRITE_EXTERNAL_STORAGE;
    if (!EasyPermissions.hasPermissions(this, perm)) {
        EasyPermissions.requestPermissions(this, getString(R.string.rationale_storage),
                RC_STORAGE_PERMS, perm);
        return;
    }

    // Choose file storage location, must be listed in res/xml/file_paths.xml
    File externalDir = Environment.getExternalStorageDirectory();
    File file = new File(externalDir, "photos/" + UUID.randomUUID().toString() + ".jpg");

    // Create content:// URI for file, required since Android N
    // See: https://developer.android.com/reference/android/support/v4/content/FileProvider.html
    mFileUri = FileProvider.getUriForFile(this,
           "com.google.firebase.quickstart.firebasestorage.fileprovider", file);

    // Create and launch the intent
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mFileUri);

    startActivityForResult(takePictureIntent, RC_TAKE_PICTURE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(LOG_TAG, "onActivityResult:" + requestCode + ":" + resultCode + ":" + data);
    if (requestCode == RC_TAKE_PICTURE) {
        if (resultCode == RESULT_OK) {
            if (mFileUri != null) {
                uploadFromUri(mFileUri);
            } else {
                Log.w(LOG_TAG, "File URI is null");
            }
        } else {
            Toast.makeText(this, "Taking picture failed.", Toast.LENGTH_SHORT).show();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

logs:onActivityResult:101:0:Intent {}

Com*_*are 7

那么它取决于Android的版本?

这取决于你的意思和错误是什么.

正如我在评论中提到的,ACTION_IMAGE_CAPTURE实现有错误的历史.存在大量此类错误,不一定与Android OS版本相关.

但是,您的代码采用了一种有趣的方法EXTRA_OUTPUT:使用FileProvider外部存储上的位置.长期来看,这FileProvider是一个很好的答案,因为Android N开始禁止file: Uri价值观.但是,有许多相机应用程序会出现问题content: Uri,因为这些相机应用程序的开发人员并不期望这样的价值观.例如,谷歌自己的相机应用程序失败了ACTION_VIDEO_CAPTUREcontent: Uri值,至少在几个月前,虽然它是罚款ACTION_IMAGE_CAPTURE.

更糟糕的是,应用程序无法宣传它支持的额外计划.通过a的"数据"方面Intent,<intent-filter>可以广告支持的方案,但这不适用于额外的.因此,当您ACTION_IMAGE_CAPTURE使用content: Uriin 调用时EXTRA_OUTPUT,您不仅限于碰巧支持content: Uri值的相机应用程序.

您可以考虑暂时将您的targetSdkVersion24 岁以下,然后使用Uri.fromFile(file)而不是FileProvider.getUriForFile(...),并看看会发生什么.如果你的原始相机应用程序工作正常,那么该应用程序不能content: Uri正确支持值,这就是导致原始问题的原因.

总的来说,我建议开发人员使用ACTION_IMAGE_CAPTURE保持targetSdkVersion低于24且使用file: Uri值几年,直到更高比例的用户安装了支持content: Uri值的相机应用程序.或者,让您的用户在现有的相机应用程序(通过ACTION_IMAGE_CAPTURE)和您构建到自己的应用程序中的某些相机功能(例如,使用我的库)之间进行选择,以增加某些功能可行的几率.