사용자가 이미지를 위해 카메라 또는 갤러리를 선택할 수 있도록 허용


151

내가하려고하는 것은 매우 간단 해 보이지만 며칠 동안 검색 한 후에는 이해할 수 없습니다.

사용자가 여러 (최대 5) 이미지를 선택할 수있는 응용 프로그램이 있습니다. 을 사용하고 ImageView있습니다. 사용자가를 클릭 ImageView하면 옵션을 허용하고 싶습니다.

  1. 갤러리에서 이미지를 선택하거나
  2. 카메라를 사용하여 이미지를 캡처하십시오.

나는 ACTION_GET_CONTENT의도 를 사용하여 시작했으며 갤러리에 도착하는 데 효과적입니다. 그런 다음 ACTION_PICK_ACTIVITY사용자가 카메라 또는 갤러리를 선택할 수 있도록 의도를 사용했습니다.

Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
Intent gallIntent=new Intent(Intent.ACTION_GET_CONTENT);
gallIntent.setType("image/*"); 
Intent camIntent = new Intent("android.media.action.IMAGE_CAPTURE");
pickIntent.putExtra(Intent.EXTRA_INTENT, camIntent);
pickIntent.putExtra(Intent.EXTRA_INTENT, gallIntent)
pickIntent.putExtra(Intent.EXTRA_TITLE, "Select Source");
startActivityForResult(pickIntent, IMAGE_SELECTOR);

하지만 하나만 추가 할 수있는 것 같습니다 EXTRA_INTENT. 메뉴가 예상대로 표시되지만 갤러리 및 파일 ...... 카메라 없음) 만 사용할 수 있습니다.

누락 된이 작업을 수행하는 더 좋고 쉬운 방법이 있습니까? 도움을 주셔서 감사합니다.


참고로 아래의 David의 최상급 답변을 보완하는 유사한 답변. stackoverflow.com/a/11676554/294884 다시 한 번 감사드립니다!
Fattie

두 요청 (카메라 및 갤러리)을 고유 한 의도로 병합하려는 의도로이 답변을 살펴보십시오. stackoverflow.com/a/32475805/2232889
Mario Velasco

간단한 : 같은 라이브러리를 사용하여 .
Vansuita Jr.

답변:


31

의도 해결 결과를 병합하는 자체 선택기 대화 상자를 작성해야합니다.

이렇게하려면 원래 의도에 대해 PackageManager.queryIntentActivities () 를 사용하여 PackageManager를 쿼리하고 다음과 같이 검색된 각 활동에 대해 하나의 새로운 의도로 가능한 의도의 최종 목록을 작성해야합니다.

List<Intent> yourIntentsList = new ArrayList<Intent>();

List<ResolveInfo> listCam = packageManager.queryIntentActivities(camIntent, 0);
for (ResolveInfo res : listCam) {
    final Intent finalIntent = new Intent(camIntent);
    finalIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
    yourIntentsList.add(finalIntent);
}

List<ResolveInfo> listGall = packageManager.queryIntentActivities(gallIntent, 0);
for (ResolveInfo res : listGall) {
    final Intent finalIntent = new Intent(gallIntent);
    finalIntent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
    yourIntentsList.add(finalIntent);
}

(나는 이것을 컴파일하지 않을 수 있도록 여기에 직접 썼다)

그런 다음 목록에서 사용자 정의 대화 상자를 만드는 방법에 대한 자세한 내용은 https://developer.android.com/guide/topics/ui/dialogs.html#AlertDialog를 참조 하십시오.


321

갤러리 나 카메라 또는 파일 시스템을 탐색하도록 등록 된 모든 응용 프로그램에서 이미지를 선택하려는 단일 의도를 시작하는 방법

Intent 옵션 목록으로 대화 상자를 만드는 것보다 Intent.createChooser를 사용하여 다양한 '카메라', '갤러리'및 타사 파일 시스템 브라우저 앱의 그래픽 아이콘 및 짧은 이름에 액세스하는 것이 훨씬 좋습니다. '아스트로'등

표준 선택자 의도를 사용하고 그에 추가 의도를 추가하는 방법에 대해 설명합니다.

private Uri outputFileUri;

private void openImageIntent() {

    // Determine Uri of camera image to save.
    final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator);
    root.mkdirs();
    final String fname = Utils.getUniqueImageFilename();
    final File sdImageMainDirectory = new File(root, fname);
    outputFileUri = Uri.fromFile(sdImageMainDirectory);

    // Camera.
    final List<Intent> cameraIntents = new ArrayList<Intent>();
    final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    final PackageManager packageManager = getPackageManager();
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
    for(ResolveInfo res : listCam) {
        final String packageName = res.activityInfo.packageName;
        final Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(packageName, res.activityInfo.name));
        intent.setPackage(packageName);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        cameraIntents.add(intent);
    }

    // Filesystem.
    final Intent galleryIntent = new Intent();
    galleryIntent.setType("image/*");
    galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

    // Chooser of filesystem options.
    final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");

    // Add the camera options.
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[cameraIntents.size()]));

    startActivityForResult(chooserIntent, YOUR_SELECT_PICTURE_REQUEST_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == YOUR_SELECT_PICTURE_REQUEST_CODE) {
            final boolean isCamera;
            if (data == null) {
                isCamera = true;
            } else {
                final String action = data.getAction();
                if (action == null) {
                    isCamera = false;
                } else {
                    isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                }
            }

            Uri selectedImageUri;
            if (isCamera) {
                selectedImageUri = outputFileUri;
            } else {
                selectedImageUri = data == null ? null : data.getData();
            }
        }
    }
}

12
아주 좋아요! 빠른 개선 : 첫 번째 경우 isCamera = MediaStore.ACTION_IMAGE_CAPTURE.equals (data.getAction ()); 그들 모두를 지배하는 한 줄;)
Glatzial

7
내 경우 final String fname = Utils.getUniqueImageFilename();에는 작동하지 않습니다 ... 그것은 말합니다 Utils cannot be resolved:(
Shajeel Afzal

30
@Shajeel Utils.getUniqueImageFilename()은 고유 한 파일 이름을 생성하는 고유 한 방법입니다. 여러 가지 방법이 있습니다. 가장 간단한 방법 중 하나는 다음과 같은 것을 사용하는 것 "img_"+ System.currentTimeMillis() + ".jpg"입니다. 다른 하나는 File.createTempFile()입니다.
David Manpearl

10
이것은 나에게 효과적이지만 소스로 onActivityResult를 호출하지 않고 카메라 자체가 닫히지 않는 카메라를 사용하는 한 가지 문제가있었습니다. 근본 원인은 매니페스트에서 누락 된 권한을했다 : <사용-권한은 안드로이드 : 이름 = "android.permission.WRITE_EXTERNAL_STORAGE"/>
BitsEvolved

11
로한이 말했듯이, 이것은 5.1.1에서 변경되었습니다. 해야합니다 if (data == null || data.getData() == null).
Ryan

22

나는 이것을 발견 했다 . 사용 :

galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

의도 중 하나에 대해 사용자에게 Android 4에서 '문서'를 선택하는 옵션이 표시되어 매우 혼란 스럽습니다. 대신 이것을 사용하면 '갤러리'옵션이 표시됩니다.

Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

이것은 잘 작동합니다 .. 그러나 우리가 카메라 이미지를 탐색 할 때 세로 이미지가 가로 모드로 표시됩니다.

@ user5060065 및 기타 선택된 사진의 방향에 문제가있는 경우 올바른 방향을 얻으려면 stackoverflow.com/a/6931373/1975002 를 참조한 다음 필요한 경우 회전하십시오.
Michaël Polla

12

또한이 문제가 있었고 AlertDialog를 만들고 DialogInterface 리스너와 함께 setItems () 메서드를 사용했습니다.

AlertDialog.Builder getImageFrom = new AlertDialog.Builder(Fotos.this);
getImageFrom.setTitle("Select:");
final CharSequence[] opsChars = {getResources().getString(R.string.takepic), getResources().getString(R.string.opengallery)};
getImageFrom.setItems(opsChars, new android.content.DialogInterface.OnClickListener(){

    @Override
    public void onClick(DialogInterface dialog, int which) {
        if(which == 0){
            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
        }else
            if(which == 1){
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,
                    getResources().getString(R.string.pickgallery)), SELECT_PICTURE);
            }
        dialog.dismiss();
    }
});

11

갤러리 또는 카메라에서 이미지를 선택하기위한 완전한 유틸리티를 만들기 위해 몇 가지 솔루션을 병합했습니다. ImagePicker 유틸리티 의 기능은 다음과 같습니다 ( Github lib에도 있음 ).

  • 갤러리 및 카메라 요청에 대한 병합 의도.
  • 선택한 큰 이미지 크기 조정 (예 : 2500 x 1600)
  • 필요한 경우 이미지 회전

스크린 샷 :

ImagePicker 시작 의도

편집 : 다음은 갤러리 및 카메라 응용 프로그램에 대한 병합 된 의도를 얻는 코드 조각입니다. ImagePicker util ( Github lib ) 에서 전체 코드를 볼 수 있습니다 .

public static Intent getPickImageIntent(Context context) {
    Intent chooserIntent = null;

    List<Intent> intentList = new ArrayList<>();

    Intent pickIntent = new Intent(Intent.ACTION_PICK,
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    takePhotoIntent.putExtra("return-data", true);
    takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile(context)));
    intentList = addIntentsToList(context, intentList, pickIntent);
    intentList = addIntentsToList(context, intentList, takePhotoIntent);

    if (intentList.size() > 0) {
        chooserIntent = Intent.createChooser(intentList.remove(intentList.size() - 1),
                context.getString(R.string.pick_image_intent_text));
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new Parcelable[]{}));
    }

    return chooserIntent;
}

private static List<Intent> addIntentsToList(Context context, List<Intent> list, Intent intent) {
    List<ResolveInfo> resInfo = context.getPackageManager().queryIntentActivities(intent, 0);
    for (ResolveInfo resolveInfo : resInfo) {
        String packageName = resolveInfo.activityInfo.packageName;
        Intent targetedIntent = new Intent(intent);
        targetedIntent.setPackage(packageName);
        list.add(targetedIntent);
    }
    return list;
}

1
이것은 정말 잘 작동합니다. 감사. 내가 가지고있는 유일한 문제는 세로로 카메라로 찍은 사진이 가로로 표시된다는 것입니다. 필요한 회전 이미지를 얻으려면 어떻게해야합니까?
365SplendidSuns

@ 365SplendidSuns 메소드 getRotationFromCamera( ImagePicker.java)에 입력 되고 있는지 그리고 어떤 값을 반환하는지 확인할 수 있습니까 ? 어떤 전화에서 테스트하고 있습니까?
마리오 벨라스코

Sony Experia C와 Android Studio 에뮬레이터를 사용하고 있습니다. 방금 요청한 사항을 확인하기 위해 몇 가지 중단 점을 넣었으며 getRotationFromCamera가 호출되지 않도록하는 getRotation 메서드에서 부울 isCamera가 false 인 것 같습니다.
365SplendidSuns

어떤 Android 버전을 사용하고 있습니까? 지난주 58 행에 수정 사항을 추가했습니다. 문제가 해결되었는지 확인하십시오.boolean isCamera = (imageReturnedIntent == null || imageReturnedIntent.getData() == null);
Mario Velasco

좋아, 에뮬레이터는 버전 6.0이며 58 번째 줄이 올바르게 작동하는 것 같습니다. 에뮬레이터에서 isCamera는 true이고 getRotationFromCamera는 양호하지만 int 방향은 0입니다. getRotationFromCamera는 0을 반환합니다. Sony 장치는 Android 4.2를 사용하고 있으며이 장치에서는 imageReturnedIntent 또는 imageReturnedIntent.getData ()가 58 행에서 null입니다. 의미 isCamera가 거짓이며 getRotationFromCamera를 호출 할 때까지 걸리지 않습니다.
365SplendidSuns

8

이 코드는 카메라 버튼 하나와 갤러리 버튼 하나가 있으며 이미지는 ImageView에 표시되므로 도움이됩니다.

https://github.com/siddhpuraamitr/Choose-Image-From-Gallery-Or-Camera


5
이 링크가 질문에 대한 답변을 제공 할 수 있지만 여기에 답변의 필수 부분을 포함시키고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 무효화 될 수 있습니다
MrEngineer13

6

이미지 선택을 사용하려고 할 때 4.4 이상에서 오류가 발생하는 경우 아래 코드를 사용할 수 있습니다.

Intent 옵션 목록으로 대화 상자를 만드는 것보다 Intent.createChooser를 사용하여 다양한 '카메라', '갤러리'및 타사 파일 시스템 브라우저 앱의 그래픽 아이콘 및 짧은 이름에 액세스하는 것이 훨씬 좋습니다. '아스트로'등

표준 선택자 의도를 사용하고 그에 추가 의도를 추가하는 방법에 대해 설명합니다.

private void openImageIntent(){

    // Determine Uri of camera image to save.
    final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "amfb" + File.separator);
    root.mkdir();
    final String fname = "img_" + System.currentTimeMillis() + ".jpg";
    final File sdImageMainDirectory = new File(root, fname);
    outputFileUri = Uri.fromFile(sdImageMainDirectory);

    // Camera.
    final List<Intent> cameraIntents = new ArrayList<Intent>();
    final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    final PackageManager packageManager = getPackageManager();
    final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
    for (ResolveInfo res : listCam){
        final String packageName = res.activityInfo.packageName;
        final Intent intent = new Intent(captureIntent);
        intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
        intent.setPackage(packageName);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        cameraIntents.add(intent);
    }

    //FileSystem
    final Intent galleryIntent = new Intent();
    galleryIntent.setType("image/");
    galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

    // Chooser of filesystem options.
    final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
    // Add the camera options.
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
    startActivityForResult(chooserIntent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);

}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    //super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
            final boolean isCamera;
            if (data == null) {
                isCamera = true;
            } else {
                final String action = data.getAction();
                if (action == null) {
                    isCamera = false;
                } else {
                    isCamera = action.equals(MediaStore.ACTION_IMAGE_CAPTURE);
                }
            }

            Uri selectedImageUri;
            if (isCamera) {
                selectedImageUri = outputFileUri;
                //Bitmap factory
                BitmapFactory.Options options = new BitmapFactory.Options();
                // downsizing image as it throws OutOfMemory Exception for larger
                // images
                options.inSampleSize = 8;
                final Bitmap bitmap = BitmapFactory.decodeFile(selectedImageUri.getPath(), options);
                preview.setImageBitmap(bitmap);
            } else {
                selectedImageUri = data == null ? null : data.getData();
                Log.d("ImageURI", selectedImageUri.getLastPathSegment());
                // /Bitmap factory
                BitmapFactory.Options options = new BitmapFactory.Options();
                // downsizing image as it throws OutOfMemory Exception for larger
                // images
                options.inSampleSize = 8;
                try {//Using Input Stream to get uri did the trick
                    InputStream input = getContentResolver().openInputStream(selectedImageUri);
                    final Bitmap bitmap = BitmapFactory.decodeStream(input);
                    preview.setImageBitmap(bitmap);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    } else if (resultCode == RESULT_CANCELED){
        // user cancelled Image capture
        Toast.makeText(getApplicationContext(),
                "User cancelled image capture", Toast.LENGTH_SHORT)
                .show();
    } else {
        // failed to capture image
        Toast.makeText(getApplicationContext(),
                "Sorry! Failed to capture image", Toast.LENGTH_SHORT)
                .show();
    }
}

안녕하세요. 나는 당신의 해결책을 시도했지만,

내 마시맬로 장치에서 카메라를 사용할 때 엉망이됩니다. 나에게 데이터는 null이 아니지만 동작은 isCamera가 false로 설정되도록합니다.
JStephen

6

이것은 Tina의 null outputFileUri 문제를 처리해야합니다.

private static final String STORED_INSTANCE_KEY_FILE_URI = "output_file_uri";

@Override
public void onSaveInstanceState( Bundle outState ) {
    super.onSaveInstanceState( outState );

    if ( outputFileUri != null ) {
        outState.putString( STORED_INSTANCE_KEY_FILE_URI, outputFileUri.toString() );
    }
}

@Override
public void onViewStateRestored( Bundle savedInstanceState ) {
    super.onViewStateRestored( savedInstanceState );

    if ( savedInstanceState != null ) {
      final String outputFileUriStr = savedInstanceState.getString( STORED_INSTANCE_KEY_FILE_URI );
      if ( outputFileUriStr != null && !outputFileUriStr.isEmpty() ) {
          outputFileUri = Uri.parse( outputFileUriStr );
      }
    }
}

참고 : android.support.v4.app.Fragment 에서이 코드를 사용하고 있습니다. 사용중인 Fragment / Activity 버전에 따라 재정의 된 메소드가 변경 될 수 있습니다.


5

옵션 대화 상자를 만들 수 있습니다

오픈 카메라:

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                                MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString());
                        if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) {
                            startActivityForResult(cameraIntent, CAMERA_IMAGE);
                        }

오픈 갤러리 :

if (Build.VERSION.SDK_INT <= 19) {
            Intent i = new Intent();
            i.setType("image/*");
            i.setAction(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            startActivityForResult(i, GALLARY_IMAGE);
        } else if (Build.VERSION.SDK_INT > 19) {
            Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(intent, GALLARY_IMAGE);
        }

선택 결과를 얻으려면

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == GALLARY_IMAGE) {
                Uri selectedImageUri = data.getData();
                String selectedImagePath = getRealPathFromURI(selectedImageUri);
            } else if (requestCode == CAMERA_IMAGE) {
                Bundle extras = data.getExtras();
                Bitmap bmp = (Bitmap) extras.get("data");
                SaveImage(bmp);
            }
        }
    }

 public String getRealPathFromURI(Uri uri) {
        if (uri == null) {
            return null;
        }
        String[] projection = {MediaStore.Images.Media.DATA};
        Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
        if (cursor != null) {
            int column_index = cursor
                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        }
        return uri.getPath();
    }

캡처 한 이미지를 저장하는 방법

 private void SaveImage(final Bitmap finalBitmap) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                String root = Environment.getExternalStorageDirectory().toString();

                File myDir = new File(root + "/Captured Images/");
                if (!myDir.exists())
                    myDir.mkdirs();

                String fname = "/image-" + System.currentTimeMillis() + ".jpg";
                File file = new File(myDir, fname);
                try {
                    FileOutputStream out = new FileOutputStream(file);
                    finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
                    out.flush();
                    out.close();
                    localImagePath = myDir + fname;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }


        });
        t.start();

    }

2

너무 큰 이미지 문제가 해결되어 메모리 부족을 피하십시오.

    private static final int SELECT_PICTURE = 0;
    private static final int REQUEST_CAMERA = 1;
    private ImageView mImageView;

    private void selectImage() {
        final CharSequence[] items = {"Take Photo", "Choose from Library",
                "Cancel"};
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle("Add Photo!");
        builder.setItems(items, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int item) {
                if (items[item].equals("Take Photo")) {
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    File f = new File(android.os.Environment
                            .getExternalStorageDirectory(), "temp.jpg");
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
                    startActivityForResult(intent, REQUEST_CAMERA);
                } else if (items[item].equals("Choose from Library")) {
                    Intent intent = new Intent(
                            Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    intent.setType("image/*");
                    startActivityForResult(
                            Intent.createChooser(intent, "Select File"),
                            SELECT_PICTURE);
                } else if (items[item].equals("Cancel")) {
                    dialog.dismiss();
                }
            }
        });
        builder.show();
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == REQUEST_CAMERA) {
                File f = new File(Environment.getExternalStorageDirectory()
                        .toString());
                for (File temp : f.listFiles()) {
                    if (temp.getName().equals("temp.jpg")) {
                        f = temp;
                        break;
                    }
                }
                try {
                    Bitmap bm;
                    BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
                    btmapOptions.inSampleSize = 2;
                    bm = BitmapFactory.decodeFile(f.getAbsolutePath(),
                            btmapOptions);

                    // bm = Bitmap.createScaledBitmap(bm, 70, 70, true);
                    mImageView.setImageBitmap(bm);

                    String path = android.os.Environment
                            .getExternalStorageDirectory()
                            + File.separator
                            + "test";
                    f.delete();
                    OutputStream fOut = null;
                    File file = new File(path, String.valueOf(System
                            .currentTimeMillis()) + ".jpg");
                    fOut = new FileOutputStream(file);
                    bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
                    fOut.flush();
                    fOut.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else if (requestCode == SELECT_PICTURE) {
                Uri selectedImageUri = data.getData();
                String tempPath = getPath(selectedImageUri, this.getActivity());
                Bitmap bm;
                btmapOptions.inSampleSize = 2;
                BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
                bm = BitmapFactory.decodeFile(tempPath, btmapOptions);
                mImageView.setImageBitmap(bm);
            }
        }
    }
    public String getPath(Uri uri, Activity activity) {
        String[] projection = {MediaStore.MediaColumns.DATA};
        Cursor cursor = activity
                .managedQuery(uri, projection, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

1

내 솔루션 추가-카메라와 상관없이 의도와 함께 콜리에서 콜백을 반환합니다.

public class ImagePickerManager extends BaseAdapter {

private List<ResolveInfo> mApplications;
private TreeSet<Integer> mImageCaptureIntents;
private TreeSet<Integer> mImagePickerIntents;
private Context mContext;
private final ImagePickerManagerListener listener;

private static enum intentType {
    choosePhoto,
    takePhoto,
    unknown;

    public int getIntValue() {
        switch (this) {
            case choosePhoto:
                return 0;
            case takePhoto:
                return 1;
            case unknown:
                return 2;
        }
        return 0;
    }
}

public interface ImagePickerManagerListener {
    void onChooseImage(Intent intent);
    void onCaptureImage(Intent intent);
}

public ImagePickerManager(Context context,ImagePickerManagerListener listenr) {
    this.mContext = context;
    this.listener = listenr;

    mImageCaptureIntents = new TreeSet<>();
    mImagePickerIntents = new TreeSet<>();

    //Picking photo intent
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType("image/*");
    mApplications = mContext.getPackageManager().queryIntentActivities(intent, 0);

    int index = 0;
    for (int i = 0; i < mApplications.size(); i++) {
        mImagePickerIntents.add(index);
        index++;
    }

    //Capture photo intent
    intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    List<ResolveInfo> resolveInfoList = mContext.getPackageManager().queryIntentActivities(intent, 0);
    mApplications.addAll(resolveInfoList);
    for (int i = 0; i < mApplications.size(); i++) {
        mImageCaptureIntents.add(index);
        index++;
    }
}

public static void openChooseAndCaptureImageDialog(final Context context, final ImagePickerManagerListener listener) {

    Log.d("openChooseAndCaptureImageDialog", "enter");

    final AlertDialog.Builder builder = new AlertDialog.Builder(context);
    final ImagePickerManager imagePickerManager = new ImagePickerManager(context,listener);
    builder.setTitle(context.getString(R.string.image_picker_dialog_box_title));
    builder.setAdapter(imagePickerManager, new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialoginterface, int i) {
            ResolveInfo resolveInfo = (ResolveInfo) imagePickerManager.getItem(i);
            Intent pickerIntent = imagePickerManager.getIntentForPackage(context,resolveInfo,i);
            switch (imagePickerManager.getIntentType(i)){
                case choosePhoto:
                    listener.onChooseImage(pickerIntent);
                    break;
                case takePhoto:
                    listener.onCaptureImage(pickerIntent);
                    break;
                case unknown:
                    break;
            }
        }
    });

    builder.setCancelable(true);
    builder.setInverseBackgroundForced(true);
    AlertDialog dialog = builder.create();
    dialog.show();
}


private intentType getIntentType(int index) {

    if (mImageCaptureIntents.contains(index)) {
       return intentType.takePhoto;
    } else if(mImagePickerIntents.contains(index)) {
        return intentType.choosePhoto;
    }
    return intentType.unknown;
}

private Intent getIntentForPackage(Context context, ResolveInfo info,int index) {
    Intent intent = context.getPackageManager().getLaunchIntentForPackage(info.activityInfo.packageName);

    ComponentName chosenName = new ComponentName(
            info.activityInfo.packageName,
            info.activityInfo.name);

    intent.setComponent(chosenName);
    intent.setFlags(Intent.FLAG_ACTIVITY_TASK_ON_HOME);
    if (mImageCaptureIntents.contains(index)) {
        intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
    } else if(mImagePickerIntents.contains(index)) {
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_PICK);
    }
    return intent;
}

@Override
public int getCount() {
    return mApplications.size();
}

@Override
public Object getItem(int position) {
    return mApplications.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ResolveInfo item = mApplications.get(position);
    if (convertView == null) {
        TextView applicationTextView = new TextView(mContext);
        LayoutParams param = new LayoutParams(
                LayoutParams.MATCH_PARENT,
                LayoutParams.WRAP_CONTENT);
        applicationTextView.setLayoutParams(param);
        final int horizontalPadding = (int) FVRGeneralUtils.convertDpToPx(mContext, 15);
        final int verticalPadding = (int) FVRGeneralUtils.convertDpToPx(mContext, 5);
        applicationTextView.setPadding(horizontalPadding,verticalPadding, horizontalPadding, verticalPadding);
        applicationTextView.setGravity(android.view.Gravity.CENTER_VERTICAL);
        Resources.Theme th = mContext.getTheme();
        TypedValue tv = new TypedValue();

        if (th.resolveAttribute(android.R.attr.textAppearanceMedium, tv, true)) {
            applicationTextView.setTextAppearance(mContext, tv.resourceId);
        }

        applicationTextView.setMinHeight((int) FVRGeneralUtils.convertDpToPx(mContext, 25));
        applicationTextView.setCompoundDrawablePadding((int) FVRGeneralUtils.convertDpToPx(mContext, 7));
        convertView = applicationTextView;
    }

    TextView textView = (TextView) convertView;
    textView.setText(item.loadLabel(mContext.getPackageManager()));
    textView.setCompoundDrawablesWithIntrinsicBounds(item.loadIcon(mContext.getPackageManager()), null, null, null);
    return textView;
} }

1

당신은 이것을 시도 할 수 있습니다 :

갤러리를 열려면

private void browseImage() {

        try {
  Intent galleryIntent = new Intent(Intent.ACTION_PICK,
                    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
  startActivityForResult(galleryIntent, GALLERY_IMAGE_PICK); //GALLERY_IMAGE_PICK it is a string
  } catch (Exception e) {}
     }

카메라를 열려면 :

 private void captureImage() {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

    // start the image capture Intent

    startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);

}

1
이것은 다른 곳의 페이스트입니다. 예를 들어 getOutputMediaFileUri는 무엇을합니까? 설명과 함께 완전한 예제를 공유하십시오.
kilokahn

0

AlertDialog 및 Intent를 사용하면 간단합니다.

    //camOption is a string array contains two items (Camera, Gallery)
    AlertDialog.Builder builder = new AlertDialog.Builder(CarPhotos.this);
    builder.setTitle(R.string.selectSource)
    .setItems(R.array.imgOption, new DialogInterface.OnClickListener() {

    public void onClick(DialogInterface dialog, int which)

     {

        if (which==0) {
        Intent intent = new Intent(this, CameraActivity.class);
        startActivityForResult(intent, REQ_CAMERA_IMAGE);               }

        if (which==1) {
        Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(i, RESULT_LOAD_IMAGE);
            }

     }
            });
             builder.create();
             builder.show();

0

다윗의 대답을 바탕으로 내 두 동전이 나왔습니다 onActivityResult(). 5.1.1에서 도입 된 변경 사항을 처리하고 사용자가 라이브러리에서 단일 또는 다중 이미지를 선택했는지 여부를 감지합니다.

private enum Outcome {
    camera, singleLibrary, multipleLibrary, unknown
}

/**
 * Returns a List<Uri> containing the image uri(s) chosen by the user
 *
 * @param data      The data intent coming from the onActivityResult()
 * @param cameraUri The uri that had been passed to the intent when the chooser was invoked.
 * @return A List<Uri>, never null.
 */
public List<Uri> getPicturesUriFromIntent(Intent data, Uri cameraUri) {

    Outcome outcome = Outcome.unknown;

    if (data == null || (data.getData() == null && data.getClipData() == null)) {
        outcome = Outcome.camera;
    } else if (data.getData() != null && data.getClipData() == null) {
        outcome = Outcome.singleLibrary;
    } else if (data.getData() == null) {
        outcome = Outcome.multipleLibrary;
    } else {
        final String action = data.getAction();
        if (action != null && action.equals(MediaStore.ACTION_IMAGE_CAPTURE)) {
            outcome = Outcome.camera;
        }
    }

    // list the uri(s) we got back
    List<Uri> uris = new ArrayList<>();
    switch (outcome) {
        case camera:
            uris.add(cameraUri);
            break;

        case singleLibrary:
            uris.add(data.getData());
            break;

        case multipleLibrary:
            final ClipData clipData = data.getClipData();
            for (int i = 0; i < clipData.getItemCount(); i++) {
                ClipData.Item item = clipData.getItemAt(i);
                uris.add(item.getUri());
            }
            break;
    }

    return uris;
}

0

이 방법으로 시도

final CharSequence[] items = { "Take Photo", "Choose from Library",
            "Cancel" };

    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
    builder.setTitle("Add Photo!");
    builder.setItems(items, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int item) {
            if (items[item].equals("Take Photo")) {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                File f = new File(android.os.Environment
                        .getExternalStorageDirectory(), "temp.jpg");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
                startActivityForResult(intent, REQUEST_CAMERA);
            } else if (items[item].equals("Choose from Library")) {
                Intent intent = new Intent(
                        Intent.ACTION_PICK,
                        android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                intent.setType("image/*");
                startActivityForResult(
                        Intent.createChooser(intent, "Select File"),
                        SELECT_FILE);
            } else if (items[item].equals("Cancel")) {
                dialog.dismiss();
            }
        }
    });
    builder.show();

그런 다음 onactivityresult 메소드를 작성하고 이와 같은 작업을 수행하십시오.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        if (requestCode == REQUEST_CAMERA) {
            File f = new File(Environment.getExternalStorageDirectory()
                    .toString());
            for (File temp : f.listFiles()) {
                if (temp.getName().equals("temp.jpg")) {
                    f = temp;
                    break;
                }
            }
            try {
                Bitmap bm;
                BitmapFactory.Options btmapOptions = new BitmapFactory.Options();

                bm = BitmapFactory.decodeFile(f.getAbsolutePath(),
                        btmapOptions);

                // bm = Bitmap.createScaledBitmap(bm, 70, 70, true);
                ivImage.setImageBitmap(bm);

                String path = android.os.Environment
                        .getExternalStorageDirectory()
                        + File.separator
                        + "Phoenix" + File.separator + "default";
                f.delete();
                OutputStream fOut = null;
                File file = new File(path, String.valueOf(System
                        .currentTimeMillis()) + ".jpg");
                try {
                    fOut = new FileOutputStream(file);
                    bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
                    fOut.flush();
                    fOut.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (requestCode == SELECT_FILE) {
            Uri selectedImageUri = data.getData();

            String tempPath = getPath(selectedImageUri, MainActivity.this);
            Bitmap bm;
            BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
            bm = BitmapFactory.decodeFile(tempPath, btmapOptions);
            ivImage.setImageBitmap(bm);
        }
    }
}

http://www.theappguruz.com/blog/android-take-photo-camera-gallery-code-sample 참조


0

Android에서 이미지를위한 카메라 또는 갤러리 선택

나는 카메라 또는 갤러리 이미지 선택 에서 열심히 일 했으며이 작업을 위해 유틸리티 클래스를 만들었습니다. 이 클래스 '이미지 카메라 또는 갤러리를 선택하는 것은 너무 쉽습니다'를 사용 하면 개발에 5-10 분이 걸렸습니다.

1 단계 : 코드에 이러한 클래스를 추가하십시오.

ImagePickerUtils : - http://www.codesend.com/view/f8f7c637716bf1c693d1490635ed49b3/

BitmapUtils : - http://www.codesend.com/view/81c1c2a3f39f1f7e627f01f67be282cf/

ConvertUriToFilePath : - http://www.codesend.com/view/f4668a29860235dd1b66eb419c5a58b5/

MediaUtils : - https://codeshare.io/5vKEMl

이 권한을 menifest에 추가해야합니다.

  <uses-permission android:name="android.permission.CAMERA" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-feature android:name="android.hardware.camera" />
  <uses-feature android:name="android.hardware.camera.autofocus" />

클래스 함수 (checkAndRequestPermissions) 는 Android-Marshmallow 및 Android-Nougat 의 권한자동으로 확인합니다 .

2 단계. 카메라 의도를 시작하기위한 카메라 클래스 호출 :

 //Create a global veriable .  
     private Uri mCameraUri;
     private static final int CAMERA_REQUEST_CODE = 100;

// Call this function when you wants to select or capture an Image.
       mCameraUri = ImagePickerUtils.createTakePictureIntent(this, CAMERA_REQUEST_CODE);

3 단계 : 의도에서 데이터를 수신하기 위해 활동에 onActivityResult 추가

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            Uri fileUri = ImagePickerUtils.getFileUriOfImage(this, data, mCameraUri);
            try {
                Bitmap bitmap = null;
                if (CAMERA_REQUEST_CODE == requestCode) {
                    bitmap = new BitmapUtils().getDownsampledBitmap(this, fileUri, imageView.getWidth(), imageView.getHeight());
                }
                if (bitmap != null)
                imageView.setImageBitmap(bitmap);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

도움이 되길 바랍니다.이 수업을 개선하기위한 제안이 있으시면 의견을 달아주세요.


문제가 있습니다. BitmapUtils 및 ImagePickerUtils에서 사용되는 MediaUtils 클래스는 어디에 있습니까?
Roger RV

@RogerRV, 알림 주셔서 감사합니다. 방금 새 클래스 파일로 답변을 업데이트했습니다.
A-Droid Tech

덕분에 지금 확인하겠습니다. 나는 그것을 해결하려고 노력했지만 전혀 작동하지는 않았다
Roger RV

0

David Manpearl 답변에 따라
https://stackoverflow.com/a/12347567/7226732

우리는 다음 과 같이 onActivityResult () 를 수정해야합니다.

 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        if (requestCode == YOUR_SELECT_PICTURE_REQUEST_CODE) {
            final boolean isCamera;
            if (data.getExtras() == null) {
                isCamera = true;
            } else {
                final String action = data.getAction();
                if (action == null) {
                    isCamera = false;
                } else {
                    isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                }
            }
            Uri selectedImageUri;
            if (isCamera) {
                selectedImageUri = fileUri;
                try {
                    Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);
                    Toast.makeText(CreateWaterType.this, "Image Saved!", Toast.LENGTH_SHORT).show();
                    image_view.setImageBitmap(bitmap);

                } catch (IOException e) {
                    e.printStackTrace();
                    Toast.makeText(CreateWaterType.this, "Failed!", Toast.LENGTH_SHORT).show();
                }

            } else {
                selectedImageUri = data == null ? null : data.getData();
                try {
                    Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);

                    Toast.makeText(CreateWaterType.this, "Image Saved!", Toast.LENGTH_SHORT).show();
                    image_view.setImageBitmap(bitmap);

                } catch (IOException e) {
                    e.printStackTrace();
                    Toast.makeText(CreateWaterType.this, "Failed!", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
}

이미지보기에서 캡처 또는 선택 이미지를 설정합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.