Фотосъемка всегда возвращает RESULT_CANCELED (0) в onActivityResult(..)

Я пытаюсь создать приложение для хранения, используя пример приложения для хранения Firebase, и когда я сделайте снимок, я всегда получаю RESUL_CANCELED в onActivityResult(..). Вот код:

@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();
        }
    }
}

журналы: onActivityResult: 101: 0: Intent {}


person madim    schedule 10.07.2016    source источник
comment
Попробуйте другое приложение камеры. ACTION_IMAGE_CAPTURE реализации имеют историю ошибок. Кроме того, не забудьте поместить mFileUri в сохраненное состояние экземпляра Bundle, так как ваш процесс может быть завершен, пока приложение камеры находится на переднем плане.   -  person CommonsWare    schedule 10.07.2016
comment
@CommonsWare спасибо, это была проблема. Так это от версии андроида зависит?   -  person madim    schedule 10.07.2016


Ответы (2)


Так это от версии андроида зависит?

Это зависит от того, что вы подразумеваете под этим и что это за ошибка.

Как я отметил в своем комментарии, ACTION_IMAGE_CAPTURE реализации имеют историю ошибки. Существует множество таких ошибок, не обязательно привязанных к версии ОС Android.

Однако в вашем коде используется интересный подход к EXTRA_OUTPUT: использование FileProvider с расположением во внешнем хранилище. В долгосрочной перспективе FileProvider — хороший ответ, поскольку Android N начинает блокировать file: Uri значений. Однако во многих приложениях для камер возникают проблемы со значениями content: Uri, потому что разработчики этих приложений для камер не ожидали таких значений. Например, собственное приложение Google Camera не соответствует ACTION_VIDEO_CAPTURE значениям content: Uri, по крайней мере, пару месяцев назад, хотя для ACTION_IMAGE_CAPTURE оно нормально.

Хуже того, приложение не может рекламировать, какие схемы оно поддерживает за дополнительную плату. С аспектом «данные» Intent <intent-filter> может рекламировать поддерживаемые схемы, но это не работает для дополнительных функций. Таким образом, когда вы вызываете ACTION_IMAGE_CAPTURE с content: Uri в EXTRA_OUTPUT, вы не ограничены приложениями камеры, которые поддерживают значения content: Uri.

Вы можете временно опустить targetSdkVersion ниже 24, а затем использовать Uri.fromFile(file) вместо FileProvider.getUriForFile(...) и посмотреть, что произойдет. Если ваше исходное приложение камеры работает нормально, то это приложение не поддерживает правильно значения content: Uri, и именно это вызвало вашу первоначальную проблему.

В целом, я рекомендую разработчикам, использующим ACTION_IMAGE_CAPTURE, держать свои targetSdkVersion ниже 24 и использовать значения file: Uri в течение нескольких лет, пока более высокий процент пользователей не установит приложение камеры, поддерживающее значения content: Uri. Или предложите своим пользователям выбор между их существующими приложениями камеры (через ACTION_IMAGE_CAPTURE) и некоторыми возможностями камеры, которые вы встраиваете в свое собственное приложение (например, используя моя библиотека), чтобы повысить вероятность того, что что-то сработает.

person CommonsWare    schedule 10.07.2016

Просто добавьте некоторый код, вызывающий плавный обходной путь, добавленный в @CommonsWare. Проверка API и соответствующая обработка сработали отлично.

   private void startCamera() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        File photoFile = null;
        try {
            photoFile = ImgUtils.createTempImageFile(this);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        if (photoFile != null) {
            mTempPhotoPath = photoFile.getAbsolutePath();
            if(Build.VERSION.SDK_INT < 24) {

            //create Uri with 'file://' prefix 
                tempImgUri = Uri.fromFile(photoFile);
            }else{

            //create Uri with 'content://' prefix 
                tempImgUri = FileProvider.getUriForFile(this,
                        FILE_PROVIDER_AUTHORITY,
                        photoFile);
            }
            mImgUriString = tempImgUri.toString();

            // Add the URI so the camera can store the image
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempImgUri);
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    }
person sleethma    schedule 04.02.2018