IT박스

사용자가 Android의 갤러리에서 사진을 찍거나 이미지를 선택할 수 있도록하는 단일 의도

itboxs 2020. 11. 14. 10:03
반응형

사용자가 Android의 갤러리에서 사진을 찍거나 이미지를 선택할 수 있도록하는 단일 의도


Android 2.1 이상용 앱을 개발 중입니다. 사용자가 내 앱 내에서 프로필 사진을 선택할 수 있도록하고 싶습니다 (연락처 프레임 워크를 사용하지 않음).

이상적인 솔루션은 사용자가 갤러리에서 이미지를 선택할 수 있도록하는 인 텐트를 실행하는 것입니다. 그러나 적절한 이미지를 사용할 수없는 경우 카메라를 사용하여 사진을 찍습니다 (또는 그 반대로 사용자가 사진을 찍도록 허용하지만 이미 적절한 이미지가 있다는 것을 알고 있으므로 갤러리로 이동하여 해당 이미지를 선택하게합니다).

현재 나는 둘 중 하나만 할 수 있지만 둘 다 할 수는 없습니다.

MediaStore.ACTION_IMAGE_CAPTURE를 사용하여 카메라 모드로 직접 이동하면 갤러리에 드롭 할 수있는 옵션이 없습니다.

Intent.ACTION_PICK을 사용하여 갤러리로 직접 이동하면 이미지를 선택할 수 있지만 카메라 버튼 (갤러리의 오른쪽 상단 모서리)을 클릭하면 새 카메라 인 텐트가 실행됩니다. 따라서 촬영 한 사진은 내 응용 프로그램에 직접 반환되지 않습니다. (물론 뒤로 버튼을 눌러 갤러리로 돌아가서 이미지를 선택할 수 있지만 이것은 불필요한 단계이며 전혀 직관적이지 않습니다).

그렇다면 두 가지를 결합하는 방법이 있습니까? 아니면 애플리케이션 내에서 하나 또는 다른 작업을 수행하기 위해 메뉴를 제공해야합니까? 일반적인 사용 사례가 될 것 같습니다 ... 확실히 내가 뭔가를 놓치고 있습니까?


업데이트 : EXTRA_INITIAL_INTENTS이 시점에서 사용하는 다른 대답 이 더 좋습니다. 내 대답을 작성했을 때 EXTRA_INITIAL_INTENTSAPI 레벨 5에 추가되었으므로 아직 존재하지 않았습니다.

그렇다면 두 가지를 결합하는 방법이 있습니까? 아니면 애플리케이션 내에서 하나 또는 다른 작업을 수행하기 위해 메뉴를 제공해야합니까?

원하는 기능을 가진 나만의 갤러리를 작성하세요.

메뉴가 더 간단하다고 생각합니다.

일반적인 사용 사례가 될 것 같습니다 ... 확실히 내가 뭔가를 놓치고 있습니까?

옆에있는 개발자는 갤러리에서 로컬 갤러리에서 선택하거나 Flickr로 이동하여 거기에서 선택할 수 있어야한다고 생각할 것입니다. 또 다른 개발자는 카메라가 카메라를 통해 "사진 찍기"뿐만 아니라 갤러리에서 무언가를 선택하여 "사진 찍기"를 허용해야한다고 생각할 것입니다. 또 다른 개발자는 갤러리가 로컬 갤러리, Flickr, 카메라 또는 네트워크에 연결된 웹캠에서 선택할 수 있어야한다고 생각할 것입니다. 또 다른 개발자는 갤러리가 어리 석고 사용자는 파일 탐색기를 통해 파일을 선택해야한다고 생각할 것입니다. 등등.

이 모든 것은 OS 용 플래시가 중요한 환경 (휴대폰)에 있습니다.

따라서 IMHO, 핵심 Android 팀이 가능한 모든 패턴을 수용하려고 시도하기보다 적합하다고 생각되는대로 조립할 수있는 빌딩 블록을 제공하기로 선택한 것은 완전히 충격적이지 않습니다.


다음과 같이 시도 할 수 있습니다.

// ...
// Within your enclosing Class
// ...
private static final int SELECT_PICTURE = 1;

// ... 

Intent pickIntent = new Intent();
pickIntent.setType("image/*");
pickIntent.setAction(Intent.ACTION_GET_CONTENT);

Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
chooserIntent.putExtra
(
  Intent.EXTRA_INITIAL_INTENTS, 
  new Intent[] { takePhotoIntent }
);

startActivityForResult(chooserIntent, SELECT_PICTURE);

활동 결과를 처리하는 방법을 보려면 이 질문을 참조하십시오.


참고 : 중요한 점은 카메라 또는 갤러리가 사용되었는지 여부를 확인하는 방법입니다. 다음 코드 예제에 표시됩니다. https://stackoverflow.com/a/12347567/294884


활동에서 다음과 같이 진행할 수 있습니다.

private static final int REQUEST_CODE_PICTURE= 1;

    /**
     * Click on View to change photo. Sets into View of your layout, android:onClick="clickOnPhoto"
     * @param view View
     */
    public void clickOnPhoto(View view) {
        Intent pickIntent = new Intent();
        pickIntent.setType("image/*");
        pickIntent.setAction(Intent.ACTION_GET_CONTENT);
        Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        String pickTitle = "Take or select a photo";
        Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { takePhotoIntent });
        startActivityForResult(chooserIntent, REQUEST_CODE_PICTURE);
    }

그런 다음 항상 활동에 onActivityResult 메서드를 추가합니다.

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_PICTURE && resultCode == Activity.RESULT_OK) {
            if (data == null) {
                return;
            }
            try {
                InputStream inputStream = getContentResolver().openInputStream(data.getData());
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                imgPhoto.setImageBitmap(bitmap);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

내 답변은 @Macarse 솔루션과 거의 동일하지만 갤러리 앱 (예 : Google 포토)을 표시하는 추가 인 텐트를 추가하고 Kotlin으로 작성되었습니다.

val REQUEST_CODE_GET_IMAGE = 101

private fun addProfileImage() {
    val pickImageFileIntent = Intent()
    pickImageFileIntent.type = "image/*"
    pickImageFileIntent.action = Intent.ACTION_GET_CONTENT

    val pickGalleryImageIntent = Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)

    val captureCameraImageIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)

    val pickTitle = "Capture from camera or Select from gallery the Profile photo"
    val chooserIntent = Intent.createChooser(pickImageFileIntent, pickTitle)
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(captureCameraImageIntent, pickGalleryImageIntent))
    startActivityForResult(chooserIntent, REQUEST_CODE_GET_IMAGE)
}

결과 의도에서 이미지 추출 :

private var imageTempFile: File? = null
private var imageMimeType: String? = null

private fun extractImage(intent: Intent?) {
    val imageUri = intent?.data
    imageUri?.let {
        Glide.with(this)
                .load(imageUri)
                .into(profileImageCiv)
        imageTempFile = MediaUtils.copyContentFromUriToCacheFile(this, imageUri, Settings.DIRECTORY_CACHE_TEMP_PROFILE_IMAGE)
        imageMimeType = MediaUtils.getMimeType(this, imageUri)
    } ?: run {
        intent?.extras?.get("data")?.let { bitmap ->    // Bitmap was returned as raw bitmap
            Glide.with(this)
                    .load(bitmap)
                    .into(profileImageCiv)
            imageTempFile = MediaUtils.writeBitmapToCacheFile(this, bitmap as Bitmap, Settings.DIRECTORY_CACHE_TEMP_PROFILE_IMAGE)
            imageMimeType = "image/jpeg"    // The bitmap was compressed as JPEG format. The bitmap itself doesn't have any format associated to it
        } ?: run {
            imageTempFile = null
            imageMimeType = null
            Log.e("Intent data is null.")
            Log.d("Error during photo selection")
        }
    }
}

참고URL : https://stackoverflow.com/questions/2708128/single-intent-to-let-user-take-picture-or-pick-image-from-gallery-in-android

반응형