web-dev-qa-db-ja.com

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が必要です。

そのため、permission Android.permission.CAMERAまたはAndroidがないと、ネイティブダイアログ/アプリから画像をキャプチャすることはできません。 .permission.WRITE_EXTERNAL_STORAGE。あれは正しいですか?

ありがとう

14
stankocken

Android 4.4+の場合、MediaStore.EXTRA_OUTPUTをパッケージ固有のディレクトリの下のファイルとして指定できます。

Android 4.4以降、外部ストレージデバイス上のファイルの所有者、グループ、モードは、ディレクトリ構造に基づいて合成されるようになりました。これにより、アプリはパッケージ固有を管理できるようになります。外部ストレージ上のディレクトリは、広範なWRITE_EXTERNAL_STORAGE権限を保持している必要はありません。たとえば、パッケージ名com.example.fooのアプリは、Android/data /com.exampleに自由にアクセスできるようになりました。パーミッションのない外部ストレージデバイス上のfoo /。これらの合成されたパーミッションは、生のストレージデバイスをFuseデーモンでラップすることによって実現されます。

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

6
Derek Fung

これを試して:

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 を参照してください。

お役に立てば幸いです。

11
Jonathan Aste

これは、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への参照を保持し、そこから取得する必要があります。

2
Phazor

カメラアプリはアプリのプライベートディレクトリにアクセスできないため、写真ファイルをそのディレクトリに書き込むのはアプリケーションの義務です。私はこれについて本当によくわかりませんが、これは私にとってはうまくいきます:

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権限が必要です。

<uses-permission
    Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"
    Android:maxSdkVersion="18" />
2
osrl