Dialog, um ein Bild aus der Galerie oder der Kamera auszuwählen

122

Gibt es eine Standardmethode zum Aufrufen eines Dialogfelds, in dem Sie auswählen können, ob Sie ein Bild von der Kamera auswählen oder von der Galerie abrufen möchten (z. B. im integrierten Telefonbuch oder in Skype)?

Ich habe einen Blick auf genommen dies aber der Code öffnet die Bildgalerie , ohne es von der Kamera zu holen hindeutet.

Gerät: Samsung Galaxy Tab
Android: 2.3.3

Sergey Metlov
quelle
Schauen Sie sich diese Antwort mit einer Absicht an, die beide Anforderungen (Kamera & Galerie) in einer einzigartigen Absicht zusammenführt: stackoverflow.com/a/32475805/2232889
Mario Velasco

Antworten:

191

Der folgende Code kann zum Aufnehmen eines Fotos und zum Auswählen eines Fotos verwendet werden. Zeigen Sie einfach einen Dialog mit zwei Optionen an und verwenden Sie bei Auswahl den entsprechenden Code.

So fotografieren Sie mit der Kamera:

Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, 0);//zero can be replaced with any action code (called requestCode)

So wählen Sie ein Foto aus der Galerie aus:

Intent pickPhoto = new Intent(Intent.ACTION_PICK,
           android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickPhoto , 1);//one can be replaced with any action code

onActivityResult Code:

protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { 
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent); 
    switch(requestCode) {
    case 0:
        if(resultCode == RESULT_OK){  
            Uri selectedImage = imageReturnedIntent.getData();
            imageview.setImageURI(selectedImage);
        }

    break; 
    case 1:
        if(resultCode == RESULT_OK){  
            Uri selectedImage = imageReturnedIntent.getData();
            imageview.setImageURI(selectedImage);
        }
    break;
    }
}

Fügen Sie abschließend diese Berechtigung in die Manifestdatei ein:

 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Shankar Agarwal
quelle
20
Die Kamera-Berechtigungen sind nicht erforderlich, da die Standard-App geöffnet wird.
Tasomaniac
2
@ Jeremy Nein, das ist falsch. Wenn Sie die Berechtigung überhaupt nicht haben, können Sie sie einfach verwenden. Weil es nicht Ihre App ist, die die Kamera öffnet. Die Nuance ist, dass wenn Sie die Berechtigung haben und der Benutzer die Berechtigung abgelehnt hat, die Verwendung Intentals Fallback eine SecurityException auslöst. Weitere Informationen: plus.google.com/+AndroidDevelopers/posts/e9kyM7VXajz
tasomaniac
2
Die Erlaubnis der Kamera ist jetzt erforderlich, um die Kameraabsicht @tasomaniac
Saad Bilal
26
mit ACTION_IMAGE_CAPTURE erhalte ich imageReturnedIntent.getData () == null warum?
Xan
3
Laut offizieller Dokumentation wird developer.android.com/training/camera/photobasics beim Fotografieren kein Bild in Uri speichern, das von den Absichten getData () zurückgegeben wurde. Sie können nur eine Miniaturansicht von der Ergebnisabsicht (intent.getBundle (). Get ("data)) erhalten. Das Bild in voller Größe kann in eine für diesen Zweck vorbereitete Datei geschrieben werden, bevor startActivityForResult aufgerufen wird.
marioc64
56

Ich habe einige Lösungen zusammengeführt, um ein Bild aus der Galerie oder Kamera vollständig auszuwählen. Dies sind die Funktionen von ImagePicker util gist (auch in einer Github-Bibliothek ):

  • Zusammengeführte Absichten für Galerie- und Kamera-Anfragen.
  • Ändern Sie die Größe ausgewählter großer Bilder (z. B. 2500 x 1600).
  • Bild bei Bedarf drehen

Bildschirmfoto:

Startabsicht von ImagePicker

Bearbeiten : Hier ist ein Codefragment, um eine zusammengeführte Absicht für Galerie- und Kamera-Apps zusammenzuführen. Den vollständigen Code finden Sie unter ImagePicker util gist (auch in einer Github-Bibliothek ):

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;
}
Mario Velasco
quelle
4
Es funktioniert perfekt, Mario. Ich danke dir sehr! Ich habe es in einem Samsung GT-I9100, einem LG L7, getestet, aber es schlägt fehl, wenn wir versuchen, das Bild von der Kamera in ein Nexus 6 mit Android 6 zu integrieren. Die Lösung wäre, dies Ihrer 58-Zeile in ImagePicker.java hinzuzufügen:boolean isCamera = (imageReturnedIntent == null || imageReturnedIntent.getData() == null);
Gabi Moreno
1
Vielen Dank, dass Sie @GabrielMorenoIbarra. Du hast es behoben, jetzt ist es auch in meinem Code.
Mario Velasco
Was ist getTempFileund wie wird diese Funktion verwendet? Bitte aktualisieren Sie die Antwort
Basheer AL-MOMANI
1
Es ist eine Funktion, um eine temporäre Datei zu erhalten. Werfen Sie einen Blick auf den Link und Sie werden ein detaillierteres Skript finden
Mario Velasco
1
@Brainware, ja, es hängt von der Android-Version ab. Erwägen Sie die Verwendung FileProviderfür API> = 23 und Urifür weniger.
CoolMind
19

Diese Bibliothek macht es einfach.

Ruf einfach an:

PickImageDialog.on(MainActivity.this, new PickSetup(BuildConfig.APPLICATION_ID));

Lassen Sie dann Ihre Aktivität IPickResult implementieren und überschreiben Sie die folgende Methode.

@Override
public void onPickResult(PickResult r) {
    if (r.getError() == null) {
        imageView.setImageBitmap(r.getBitmap());

        //or

        imageView.setImageURI(r.getUri());
    } else {
        //Handle possible errors
        //TODO: do what you have to do with r.getError();
    }
}
Vansuita Jr.
quelle
Ich habe Amazon Fotos in meinem Telefon S7 Edge, wann immer ich Galerie Option wähle, es wird auf Amazon Anmeldeseite umleiten und in anderen Handys ist es in Ordnung .. aber ich teste in S7 Edge
Nafees Ahmed
Dies ist ein sehr chaotischer Ansatz, der sich auf den gesamten Code auswirken kann. Ich weiß nicht, warum der Typ ein separates MVN-Repo erstellt hat.
Freude
Ermöglicht dies Mehrfachauswahl- oder Mehrfachaufnahmebilder?
Adnan
12

Sie können diesen Code implementieren, um ein Bild aus der Galerie oder Kamera auszuwählen: -

private ImageView imageview;
private Button btnSelectImage;
private Bitmap bitmap;
private File destination = null;
private InputStream inputStreamImg;
private String imgPath = null;
private final int PICK_IMAGE_CAMERA = 1, PICK_IMAGE_GALLERY = 2;

Jetzt können Sie beim Klicken auf die Schaltfläche Ihre Methode zur Auswahl von Bild aufrufen. Dies befindet sich in onCreate der Aktivität.

imageview = (ImageView) findViewById(R.id.imageview);
btnSelectImage = (Button) findViewById(R.id.btnSelectImage);

//OnbtnSelectImage click event...
btnSelectImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            selectImage();
        }
    });

Außerhalb Ihrer Aktivität oncreate.

// Select image from camera and gallery
private void selectImage() {
    try {
        PackageManager pm = getPackageManager();
        int hasPerm = pm.checkPermission(Manifest.permission.CAMERA, getPackageName());
        if (hasPerm == PackageManager.PERMISSION_GRANTED) {
            final CharSequence[] options = {"Take Photo", "Choose From Gallery","Cancel"};
            android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(activity);
            builder.setTitle("Select Option");
            builder.setItems(options, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int item) {
                    if (options[item].equals("Take Photo")) {
                        dialog.dismiss();
                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        startActivityForResult(intent, PICK_IMAGE_CAMERA);
                    } else if (options[item].equals("Choose From Gallery")) {
                        dialog.dismiss();
                        Intent pickPhoto = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                        startActivityForResult(pickPhoto, PICK_IMAGE_GALLERY);
                    } else if (options[item].equals("Cancel")) {
                        dialog.dismiss();
                    }
                }
            });
            builder.show();
        } else
            Toast.makeText(this, "Camera Permission error", Toast.LENGTH_SHORT).show();
    } catch (Exception e) {
        Toast.makeText(this, "Camera Permission error", Toast.LENGTH_SHORT).show();
        e.printStackTrace();
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    inputStreamImg = null;
    if (requestCode == PICK_IMAGE_CAMERA) {
        try {
            Uri selectedImage = data.getData();
            bitmap = (Bitmap) data.getExtras().get("data");
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 50, bytes);

            Log.e("Activity", "Pick from Camera::>>> ");

            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
            destination = new File(Environment.getExternalStorageDirectory() + "/" +
                    getString(R.string.app_name), "IMG_" + timeStamp + ".jpg");
            FileOutputStream fo;
            try {
                destination.createNewFile();
                fo = new FileOutputStream(destination);
                fo.write(bytes.toByteArray());
                fo.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            imgPath = destination.getAbsolutePath();
            imageview.setImageBitmap(bitmap);

        } catch (Exception e) {
            e.printStackTrace();
        }
    } else if (requestCode == PICK_IMAGE_GALLERY) {
        Uri selectedImage = data.getData();
        try {
            bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 50, bytes);
            Log.e("Activity", "Pick from Gallery::>>> ");

            imgPath = getRealPathFromURI(selectedImage);
            destination = new File(imgPath.toString());
            imageview.setImageBitmap(bitmap);

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

public String getRealPathFromURI(Uri contentUri) {
    String[] proj = {MediaStore.Audio.Media.DATA};
    Cursor cursor = managedQuery(contentUri, proj, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

Atlast, füge endlich die Kamera hinzu und schreibe die externe Speicherberechtigung in AndroidManifest.xml

Es funktioniert sehr gut für mich, hoffe es funktioniert auch für Sie.

Nikhil
quelle
1
Ich füge Kamera-Erlaubnis hinzu, aber akkurate Fehler und zeige "Kamera-Erlaubnis-Fehler" an
roghayeh hosseini
7

Ich denke, es liegt an Ihnen, diesen Dialog zur Auswahl zu zeigen. Für die Galerie verwenden Sie diesen Code, und für die Kamera versuchen Sie dies .

Igor Filippov
quelle
1
Aber Bild in diesem Beispiel auf den Kopf gestellt
Sunny
3

Wenn Sie das Bild aus der Galerie abrufen oder das Bild aufnehmen und im Hochformat auf die Bildansicht einstellen möchten, hilft Ihnen der folgende Code.

In onCreate ()

imageViewRound.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            selectImage();
        }
    });




    private void selectImage() {
    Constants.iscamera = true;
    final CharSequence[] items = { "Take Photo", "Choose from Library",
            "Cancel" };

     TextView title = new TextView(context);
     title.setText("Add Photo!");
        title.setBackgroundColor(Color.BLACK);
        title.setPadding(10, 15, 15, 10);
        title.setGravity(Gravity.CENTER);
        title.setTextColor(Color.WHITE);
        title.setTextSize(22);


    AlertDialog.Builder builder = new AlertDialog.Builder(
            AddContactActivity.this);



    builder.setCustomTitle(title);

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

                Intent intent = new Intent(
                        android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                /*
                 * File photo = new
                 * File(Environment.getExternalStorageDirectory(),
                 * "Pic.jpg"); intent.putExtra(MediaStore.EXTRA_OUTPUT,
                 * Uri.fromFile(photo)); imageUri = Uri.fromFile(photo);
                 */
                // startActivityForResult(intent,TAKE_PICTURE);

                Intent intents = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

                fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

                intents.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

                // start the image capture Intent
                startActivityForResult(intents, TAKE_PICTURE);

            } 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 Picture"),
                        SELECT_PICTURE);
            } else if (items[item].equals("Cancel")) {
                dialog.dismiss();
            }
        }
    });
    builder.show();
}




    @SuppressLint("NewApi")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {
    case SELECT_PICTURE:
        Bitmap bitmap = null;
        if (resultCode == RESULT_OK) {
            if (data != null) {


                try {
                    Uri selectedImage = data.getData();
                    String[] filePath = { MediaStore.Images.Media.DATA };
                    Cursor c = context.getContentResolver().query(
                            selectedImage, filePath, null, null, null);
                    c.moveToFirst();
                    int columnIndex = c.getColumnIndex(filePath[0]);
                    String picturePath = c.getString(columnIndex);
                    c.close();
                    imageViewRound.setVisibility(View.VISIBLE);
                    // Bitmap thumbnail =
                    // (BitmapFactory.decodeFile(picturePath));
                    Bitmap thumbnail = decodeSampledBitmapFromResource(
                            picturePath, 500, 500);

                    // rotated
                    Bitmap thumbnail_r = imageOreintationValidator(
                            thumbnail, picturePath);
                    imageViewRound.setBackground(null);
                    imageViewRound.setImageBitmap(thumbnail_r);
                    IsImageSet = true;
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        break;
    case TAKE_PICTURE:
        if (resultCode == RESULT_OK) {

            previewCapturedImage();

        }

        break;
    }

}



 @SuppressLint("NewApi")
private void previewCapturedImage() {
    try {
        // hide video preview

        imageViewRound.setVisibility(View.VISIBLE);

        // bimatp 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(fileUri.getPath(),
                options);

        Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, 500, 500,
                false);

        // rotated
        Bitmap thumbnail_r = imageOreintationValidator(resizedBitmap,
                fileUri.getPath());

        imageViewRound.setBackground(null);
        imageViewRound.setImageBitmap(thumbnail_r);
        IsImageSet = true;
        Toast.makeText(getApplicationContext(), "done", Toast.LENGTH_LONG)
                .show();
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
}






    // for roted image......
private Bitmap imageOreintationValidator(Bitmap bitmap, String path) {

    ExifInterface ei;
    try {
        ei = new ExifInterface(path);
        int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);
        switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            bitmap = rotateImage(bitmap, 90);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            bitmap = rotateImage(bitmap, 180);
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            bitmap = rotateImage(bitmap, 270);
            break;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    return bitmap;
}



private Bitmap rotateImage(Bitmap source, float angle) {

    Bitmap bitmap = null;
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    try {
        bitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(),
                source.getHeight(), matrix, true);
    } catch (OutOfMemoryError err) {
        source.recycle();
        Date d = new Date();
        CharSequence s = DateFormat
                .format("MM-dd-yy-hh-mm-ss", d.getTime());
        String fullPath = Environment.getExternalStorageDirectory()
                + "/RYB_pic/" + s.toString() + ".jpg";
        if ((fullPath != null) && (new File(fullPath).exists())) {
            new File(fullPath).delete();
        }
        bitmap = null;
        err.printStackTrace();
    }
    return bitmap;
}




public static Bitmap decodeSampledBitmapFromResource(String pathToFile,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(pathToFile, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth,
            reqHeight);

    Log.e("inSampleSize", "inSampleSize______________in storage"
            + options.inSampleSize);
    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(pathToFile, options);
}




public static int calculateInSampleSize(BitmapFactory.Options options,
        int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        // Calculate ratios of height and width to requested height and
        // width
        final int heightRatio = Math.round((float) height
                / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will
        // guarantee
        // a final image with both dimensions larger than or equal to the
        // requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

    }

    return inSampleSize;
}




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






private static File getOutputMediaFile(int type) {

    // External sdcard location
    File mediaStorageDir = new File(
            Environment
                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            IMAGE_DIRECTORY_NAME);

    // Create the storage directory if it does not exist
    if (!mediaStorageDir.exists()) {
        if (!mediaStorageDir.mkdirs()) {
            Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
                    + IMAGE_DIRECTORY_NAME + " directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
            Locale.getDefault()).format(new Date());
    File mediaFile;
    if (type == MEDIA_TYPE_IMAGE) {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator
                + "IMG_" + timeStamp + ".jpg");
    } else {
        return null;
    }

    return mediaFile;
}






public Uri getOutputMediaFileUri(int type) {
    return Uri.fromFile(getOutputMediaFile(type));
}

Hoffe das wird dir helfen .... !!!

Wenn targetSdkVersion höher als 24 ist, wird FileProvider verwendet, um den Zugriff zu gewähren.

Erstellen Sie eine XML-Datei (Pfad: res \ xml) provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

Fügen Sie einen Provider in AndroidManifest.xml hinzu

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

und ersetzen

return Uri.fromFile(getOutputMediaFile(type));

Zu

               return FileProvider.getUriForFile(this,  BuildConfig.APPLICATION_ID + ".provider", getOutputMediaFile(type));
Pratibha Sarode
quelle