Захват изображения без разрешения с Android 6.0

Мне нужно разрешить пользователю делать снимок (из галереи или из приложения для камеры) с Android 6.0.

Поскольку мне не нужно управлять камерой, я хотел бы использовать намерение, описанное здесь:

Однако, если вам не нужен такой контроль, вы можете просто использовать намерение ACTION_IMAGE_CAPTURE для запроса изображения. Когда вы запустите намерение, пользователю будет предложено выбрать приложение для камеры (если оно еще не было приложением по умолчанию для камеры), и это приложение будет делать снимок. Приложение камеры возвращает изображение в ваше приложение onActivityResult().

https://developer.android.com/preview/features/runtime-permissions.html

Но для этого ACTION_IMAGE_CAPTURE вам нужно заполнить дополнительный "MediaStore.EXTRA_OUTPUT" , который является Uri для временного файла (без этого параметра у меня будет только эскизы). Этот временный файл должен находиться во внешнем хранилище (для доступа к приложению камеры). Для создания файла во внешнем хранилище вам потребуется разрешение WRITE_EXTERNAL_STORAGE.

Таким образом, невозможно захватить изображение через собственные диалоги/приложения без разрешения android.permission.CAMERA или android.permission.WRITE_EXTERNAL_STORAGE. Это правильно?

Спасибо

Ответ 1

Возможно, если вы в android 4.4+, вы можете указать MediaStore.EXTRA_OUTPUT, чтобы быть файлом под вашим пакетом каталоги

Начиная с Android 4.4, владелец, группа и режимы файлов на внешние устройства хранения теперь синтезируются на основе каталога состав. Это позволяет приложениям управлять своими пакетами каталогов на внешнем хранилище, не требуя, чтобы они Разрешение WRITE_EXTERNAL_STORAGE. Например, приложение с пакетом name com.example.foo теперь может свободно получать доступ Android/data/com.example.foo/на внешних устройствах хранения без разрешений.. Эти синтезированные разрешения выполняются посредством обертывание необработанных устройств хранения данных в демоном FUSE.

https://source.android.com/devices/storage/

Ответ 2

Попробуйте следующее:

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(getActivity().getApplicationContext().getExternalFilesDir(android.os.Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator + "yourPicture.jpg");
Uri uri = Uri.fromFile(file);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, url);

В этом случае вы получаете доступ к "внешнему" хранилищу, доступному для записи приложений для камеры, но файлы просто видны из вашего приложения. Чтобы узнать немного больше о пространствах памяти в android, см. https://www.youtube.com/watch?v=C28pvd2plBA

Надеюсь, это поможет вам!

Ответ 3

Так как приложение-камера не может получить доступ к частным серверам вашего приложения, то ваши приложения должны записывать файл фотографий в этот каталог. Я не уверен в этом, но это работает для меня:

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault())
            .format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    return File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
}

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
    // Create the File where the photo should go
    File photoFile = null;
    try {
        photoFile = createImageFile();
        takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
    } catch (IOException ex) {
        // Error occurred while creating the File
        Log.e(TAG, "Unable to create Image File", ex);
    }

    // Continue only if the File was successfully created
    if (photoFile != null) {
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(photoFile));
    } else {
        takePictureIntent = null;
    }
}

Но вам еще нужно разрешение WRITE_EXTERNAL_STORAGE перед KITKAT:

<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18" />

Ответ 4

Это возможно без каких-либо разрешений CAMERA и WRITE_EXTERNAL_STORAGE.

Вы можете создать временную папку в кэше приложений и предоставить другим приложениям доступ к ней. Это делает файл записываемым приложением камеры:

File tempFile = File.createTempFile("photo", ".jpg", context.getCacheDir());
tempFile.setWritable(true, false);

Теперь вам просто нужно передать этот файл в качестве выходного файла для намерения камеры:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempFile));  // pass temp file
startActivityForResult(intent, REQUEST_CODE_CAMERA);

Примечание: файл Uri не будет передан вам в результате действия, вам нужно будет сохранить ссылку на tempFile и получить его оттуда.