Cho phép người dùng chọn máy ảnh hoặc thư viện cho hình ảnh


151

Những gì tôi đang cố gắng làm có vẻ rất đơn giản, nhưng sau vài ngày tìm kiếm, tôi không thể tìm ra nó.

Tôi có một ứng dụng cho phép người dùng chọn nhiều (tối đa 5) hình ảnh. Tôi đang sử dụng một ImageView. Khi người dùng nhấp vào ImageView, tôi muốn cho phép họ tùy chọn

  1. Chọn hình ảnh từ thư viện, hoặc
  2. Sử dụng máy ảnh để chụp ảnh.

Tôi bắt đầu bằng cách sử dụng ACTION_GET_CONTENTý định, và điều đó hoạt động tốt để đến phòng trưng bày. Vì vậy, sau đó tôi đã thử sử dụng ACTION_PICK_ACTIVITYý định cho phép người dùng chọn máy ảnh hoặc bộ sưu tập:

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);

Nhưng nó xuất hiện tôi chỉ có thể thêm một EXTRA_INTENT. Menu hiển thị như mong đợi, nhưng các tùy chọn duy nhất là Thư viện và Tệp .... không có Máy ảnh).

Có cách nào tốt hơn / dễ dàng hơn để làm điều này mà tôi đang thiếu không? Cảm ơn vì bất kì sự giúp đỡ.


Câu trả lời tương tự của FYI, bổ sung cho câu trả lời siêu hạng của David dưới đây. stackoverflow.com/a/11676554/294884 một lần nữa cảm ơn David từ mọi người !!!
Fattie

Hãy xem câu trả lời này với ý định hợp nhất cả hai yêu cầu (Camera & Thư viện) trong một Mục đích duy nhất: stackoverflow.com/a/32475805/2232889
Mario Velasco

Đơn giản: Sử dụng một thư viện như thế này .
Vansuita Jr.

Câu trả lời:


31

Bạn sẽ phải tạo hộp thoại cho người chọn của riêng mình để hợp nhất cả hai kết quả giải quyết ý định.

Để thực hiện việc này, bạn sẽ cần truy vấn Gói Trình quản lý với Gói Trình quản lý.queryIntentActivities () cho cả hai ý định ban đầu và tạo danh sách Ý định cuối cùng có thể với một Ý định mới cho mỗi hoạt động được truy xuất như sau:

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

(Tôi đã viết điều này trực tiếp ở đây để điều này có thể không được biên dịch)

Sau đó, để biết thêm thông tin về cách tạo hộp thoại tùy chỉnh từ danh sách, hãy xem https://developer.android.com/guide/topics/ui/dialogs.html#AlertDialog


321

Cách khởi chạy một Mục đích duy nhất để chọn hình ảnh từ Thư viện hoặc Máy ảnh hoặc bất kỳ ứng dụng nào đã đăng ký để duyệt hệ thống tệp.

Thay vì tạo Hộp thoại với danh sách các tùy chọn Ý định, sử dụng Intent.createChooser sẽ tốt hơn nhiều để có quyền truy cập vào các biểu tượng đồ họa và tên ngắn của các ứng dụng trình duyệt hệ thống tập tin của bên thứ ba, 'Thư viện' và thậm chí cả bên thứ ba chẳng hạn như 'Astro', v.v.

Phần này mô tả cách sử dụng mục đích của người chọn tiêu chuẩn và thêm ý định bổ sung vào đó.

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
Rất tốt! Chỉ cần một cải tiến nhanh chóng: trong lần đầu tiên khác là isCamera = MediaStore.ACTION_IMAGE_CAPTURE.equals (data.getAction ()); Một dòng để thống trị tất cả;)
Glatzial

7
Trong trường hợp của tôi final String fname = Utils.getUniqueImageFilename();không hoạt động ... nó nói Utils cannot be resolved:(
Shajeel Afzal

30
@Shajeel, Utils.getUniqueImageFilename()là phương pháp của riêng tôi để tạo một tên tệp duy nhất. Có rất nhiều cách để làm điều đó. Một trong những cách đơn giản nhất là sử dụng một cái gì đó như "img_"+ System.currentTimeMillis() + ".jpg". Khác là File.createTempFile().
David Manpearl

10
Điều này làm việc rất tốt cho tôi nhưng tôi gặp một vấn đề khi sử dụng máy ảnh vì nguồn không gọi onActivityResult và bản thân máy ảnh không bị loại bỏ. Nguyên nhân gốc là sự thiếu quyền trong tệp kê khai: <
used

11
Như Rohan đã nói, điều này được thay đổi vào ngày 5.1.1. Bạn sẽ cần phải làm if (data == null || data.getData() == null).
Ryan

22

Tôi tìm thấy này . Sử dụng:

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

đối với một trong những ý định cho người dùng thấy tùy chọn chọn 'tài liệu' trong Android 4, điều mà tôi thấy rất khó hiểu. Sử dụng điều này thay vì hiển thị tùy chọn 'thư viện':

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

điều này hoạt động tốt..nhưng khi chúng ta duyệt hình ảnh camera, hình ảnh chân dung hiển thị ở chế độ ngang ..

@ user5060065 và những người khác gặp vấn đề với hướng của ảnh đã chọn, xem stackoverflow.com/a/6931373/1975002 để có hướng chính xác, sau đó xoay nó nếu cần.
Michaël Polla

12

Tôi cũng gặp vấn đề này và những gì tôi đã làm là tạo AlertDialog và sử dụng phương thức setItems () cùng với trình nghe DialogInterface:

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

Tôi đã hợp nhất một số giải pháp để sử dụng hoàn chỉnh để chọn một hình ảnh từ Thư viện hoặc Máy ảnh. Đây là các tính năng của ImagePicker produc (cũng trong lib Github ):

  • Ý định hợp nhất cho các cuộc phục hồi Gallery và Camera.
  • Thay đổi kích thước hình ảnh lớn được chọn (ví dụ: 2500 x 1600)
  • Xoay hình ảnh nếu thận

Ảnh chụp màn hình:

Ý định bắt đầu của ImagePicker

Chỉnh sửa : Đây là một đoạn mã để có được một ý định hợp nhất cho các ứng dụng Thư viện và Máy ảnh với nhau. Bạn có thể xem mã đầy đủ tại ImagePicker produc (cũng trong lib Github ):

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
Điều này hoạt động thực sự tốt. Cảm ơn. Vấn đề duy nhất tôi gặp phải là những bức ảnh được chụp bằng máy ảnh chân dung sẽ xuất hiện dưới dạng phong cảnh. Tôi cần làm gì để có được những hình ảnh cần thiết?
365SplendidSun 2/11/2015

@ 365SplendidSun Bạn có thể kiểm tra xem nó có đang nhập vào phương thức getRotationFromCamera( ImagePicker.java) không và nó đang trả về giá trị nào? Bạn đang thử nghiệm điện thoại nào?
Mario Velasco

Tôi đang sử dụng Sony Experia C và trình giả lập Android Studio. Tôi chỉ đưa vào một số điểm dừng để kiểm tra những điều bạn đã hỏi và có vẻ như isCamera boolean là sai trong phương thức getRotation đang ngăn không cho getRotationFromCamera được gọi.
365SplendidSun 2/11/2015

Phiên bản Android nào bạn đang thử? Tôi đã thêm một sửa đổi vào tuần trước trên dòng 58, kiểm tra xem nó có giải quyết được không:boolean isCamera = (imageReturnedIntent == null || imageReturnedIntent.getData() == null);
Mario Velasco

Ok, trình giả lập là phiên bản 6.0 và có vẻ như dòng 58 đang hoạt động tốt trong việc này. Trên trình giả lập isCamera là đúng và getRotationFromCamera đang được gọi là fine nhưng int direction là 0, có nghĩa là getRotationFromCamera đang trả về 0 ... Thiết bị Sony đang sử dụng Android 4.2 và trên đó không phải là imageReturnedIntent hay imageReturnedIntent.getData có nghĩa là isCamera là sai và tôi không nhận được bằng cách gọi getRotationFromCamera.
365SplendidSun

8

mã này sẽ giúp bạn, trong đó có hai nút một cho Camera và một nút cho Thư viện và Hình ảnh sẽ được hiển thị trong ImageView

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


5
Mặc dù liên kết này có thể trả lời câu hỏi, tốt hơn là bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở nên không hợp lệ nếu trang được liên kết thay đổi
MrEngineer13

6

Đối với những người gặp lỗi từ 4.4 trở lên trong khi cố gắng sử dụng lựa chọn Hình ảnh có thể sử dụng mã bên dưới.

Thay vì tạo Hộp thoại với danh sách các tùy chọn Ý định, sử dụng Intent.createChooser sẽ tốt hơn nhiều để có quyền truy cập vào các biểu tượng đồ họa và tên ngắn của các ứng dụng trình duyệt hệ thống tập tin của bên thứ ba, 'Thư viện' và thậm chí cả bên thứ ba chẳng hạn như 'Astro', v.v.

Phần này mô tả cách sử dụng mục đích của người chọn tiêu chuẩn và thêm ý định bổ sung vào đó.

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

Chào. Tôi đã thử giải pháp của bạn, nhưng chọn một hình ảnh từ thư viện không hoạt động: hãy xem tại đây: stackoverflow.com/questions/36884651/iêu

Trên thiết bị marshmallow của tôi, điều này gây rối khi sử dụng máy ảnh. Đối với tôi dữ liệu không phải là null, nhưng hành động là, khiến isCamera được đặt thành false.
JStephen

6

Điều này sẽ giải quyết vấn đề null outputFileUri của Tina:

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

Lưu ý: Tôi đang sử dụng mã này bên trong android.support.v4.app. Việc sử dụng các phương thức được ghi đè của bạn có thể thay đổi tùy thuộc vào phiên bản Fragment / Activity nào bạn đang sử dụng.


5

Bạn có thể tạo hộp thoại tùy chọn

Mở camera:

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

Mở Thư viện:

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

Để có kết quả lựa chọn

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

Phương pháp lưu ảnh đã chụp

 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

Đã giải quyết vấn đề hình ảnh quá lớn và tránh ra khỏi bộ nhớ.

    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

Thêm giải pháp của tôi - nó sẽ trả về một cuộc gọi lại cho dù đó là từ máy ảnh hoặc từ bếp cùng với ý định:

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

Bạn có thể thử điều này:

Để mở Thư viện:

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) {}
     }

Để mở Camera:

 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
Đây là một dán từ nơi khác trên SO. Ví dụ: getOutputMediaFileUri làm gì? Hãy chia sẻ các ví dụ đầy đủ, với lời giải thích.
kilokahn

0

Điều này thật đơn giản bằng cách sử dụng AlertDialog và Intent.ACTION_PICK

    //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

Dựa trên câu trả lời của David, hai đồng xu của tôi onActivityResult(). Nó quan tâm đến những thay đổi được giới thiệu trong 5.1.1 và phát hiện xem người dùng đã chọn một hoặc nhiều hình ảnh từ thư viện.

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

Hãy thử cách này

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

Sau đó tạo phương thức onactivityresult và làm một cái gì đó như thế này

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

Xem này http: //www.th OKguruz.com/blog/android-take-photo-camera-gallery-code-sample


0

Chọn máy ảnh hoặc thư viện cho hình ảnh trong Android

Tôi đã làm việc chăm chỉ trên Camera hoặc thư viện Lựa chọn hình ảnh và tạo một số lớp tiện dụng cho công việc này. Với việc sử dụng các lớp này 'Chọn máy ảnh hoặc thư viện ảnh quá dễ dàng', bạn chỉ mất 5-10 phút để phát triển.

Bước 1: Thêm các lớp này trong mã của bạn.

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

Chúng ta cần thêm các quyền này trong bảng kê khai:

  <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" />

Chức năng lớp này (checkAndRequestPermissions) tự động kiểm tra quyền trong Android-Marshmallow và Android - Nougat.

Bước 2. Gọi lớp camera để khởi chạy ý định camera:

 //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);

Bước 3: Thêm onActivityResult trong Hoạt động của bạn để nhận dữ liệu từ Ý định

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

Tôi hy vọng nó sẽ giúp bạn, Nếu bất kỳ ai có bất kỳ đề xuất nào để cải thiện các lớp này, vui lòng thêm đánh giá của bạn trong các bình luận.


Nó có một vấn đề. Lớp MediaUtils được sử dụng trong BitmapUtils và ImagePickerUtils ở đâu?
Roger RV

@RogerRV, cảm ơn vì đã thông báo cho tôi, tôi vừa cập nhật Câu trả lời với tệp lớp mới.
A-Droid Tech

Nhờ bạn tôi sẽ kiểm tra nó ngay bây giờ. Tôi đã cố gắng tự giải quyết nó nhưng nó không hoạt động
Roger RV

0

Theo câu trả lời của David Manpearl
https://stackoverflow.com/a/12347567/7226732

chúng ta chỉ cần sửa đổi onActivityResult () như

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

và thiết lập chụp hoặc chọn hình ảnh trong chế độ xem hình ảnh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.