อนุญาตให้ผู้ใช้เลือกกล้องหรือแกลเลอรี่ภาพ


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แต่ปรากฏว่าฉันสามารถเพิ่มหนึ่ง เมนูแสดงขึ้นตามที่คาดไว้ แต่ตัวเลือกเท่านั้นคือคลังภาพและไฟล์ .... ไม่มีกล้อง)

มีวิธีที่ดีกว่า / ง่ายกว่าในการทำสิ่งนี้ที่ฉันขาดไป ขอบคุณสำหรับความช่วยเหลือ


FYI คล้ายกับคำตอบเพิ่มเติมจากคำตอบขั้นสุดยอดของเดวิดด้านล่าง stackoverflow.com/a/11676554/294884 ขอบคุณอีกครั้ง David จากทุกคน !!!
Fattie

ลองดูคำตอบนี้ด้วยความตั้งใจที่ผสานรวมคำขอทั้งสอง (กล้องถ่ายรูปและแกลเลอรี่) ด้วยความตั้งใจที่ไม่ซ้ำใคร: stackoverflow.com/a/32475805/2232889
Mario Velasco

ง่าย: ใช้ห้องสมุดเช่นนี้
Vansuita Jr.

คำตอบ:


31

คุณจะต้องสร้างกล่องโต้ตอบตัวเลือกของคุณเองเพื่อรวมผลลัพธ์การแก้ไขเจตนา

ในการทำเช่นนี้คุณจะต้องค้นหา PackageManager ด้วยPackageManager.queryIntentActivities ()สำหรับทั้ง intents ดั้งเดิมและสร้างรายการสุดท้ายของ Intent ที่เป็นไปได้ด้วย Intent ใหม่สำหรับแต่ละกิจกรรมที่ดึงมาเช่นนี้

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 หนึ่งครั้งเพื่อเลือกภาพจากคลังภาพหรือกล้องหรือแอปพลิเคชันใด ๆ ที่ลงทะเบียนไว้เพื่อเรียกดูระบบไฟล์

แทนที่จะสร้าง Dialog ด้วยรายการตัวเลือก Intent จะดีกว่าการใช้ Intent.createChooser เพื่อเข้าถึงไอคอนกราฟิกและชื่อย่อของ 'Camera', 'Gallery' และแม้แต่แอปเบราว์เซอร์ระบบไฟล์บุคคลที่สาม เช่น 'Astro' เป็นต้น

สิ่งนี้อธิบายวิธีการใช้ตัวเลือกมาตรฐานและเพิ่มความตั้งใจเพิ่มเติม

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
สิ่งนี้ใช้งานได้ดีสำหรับฉัน แต่ฉันมีปัญหาหนึ่งที่การใช้กล้องเนื่องจากแหล่งที่มาไม่ได้เรียกใช้ ActivityResult และตัวกล้องเองก็ไม่ได้ไล่ออก สาเหตุหลักคือการอนุญาตที่ขาดหายไปในรายการ: <ใช้สิทธิ์ Android: ชื่อ = "android.permission.WRITE_EXTERNAL_STORAG ​​E ที่" />
BitsEvolved

11
ตามที่ Rohan กล่าวสิ่งนี้จะเปลี่ยนไปใน 5.1.1 if (data == null || data.getData() == null)คุณจะต้องทำ
Ryan

22

ฉันพบนี้ โดยใช้:

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

สำหรับหนึ่งใน Intent แสดงให้ผู้ใช้เห็นตัวเลือกในการเลือก 'เอกสาร' ใน 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 และใช้เมธอด setItems () พร้อมกับผู้ฟัง 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

ฉันได้รวมโซลูชันบางอย่างเพื่อใช้ประโยชน์อย่างสมบูรณ์สำหรับการเลือกภาพจากคลังภาพหรือกล้อง นี่คือคุณสมบัติของImagePicker util (เช่นเดียวกับในGithub lib ):

  • ผสานความตั้งใจในการคัดลอกคลังภาพและคลังภาพ
  • ปรับขนาดภาพใหญ่ที่เลือก (เช่น: 2500 x 1600)
  • หมุนภาพถ้าจำเป็น

ภาพหน้าจอ:

ImagePicker เริ่มเจตนา

แก้ไข : นี่เป็นส่วนของรหัสที่จะรวมแอพ Intent for Gallery และ Camera เข้าด้วยกัน คุณสามารถดูรหัสเต็มได้ที่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) และมีค่าใดที่กลับมา? คุณกำลังทดสอบโทรศัพท์รุ่นใด
Mario Velasco

ฉันใช้ Sony Experia C และโปรแกรมจำลองสตูดิโอ Android ฉันใส่จุดพักเพื่อตรวจสอบสิ่งที่คุณถามและดูเหมือนว่าบูลีน isCamera เป็นเท็จในวิธีการ getRotation ซึ่งจะหยุดการเรียก getRotationFromCamera
365SplendidSuns

คุณกำลังลองเวอร์ชั่น Android อะไร ฉันได้เพิ่มการดัดแปลงเมื่อสัปดาห์ที่แล้วที่บรรทัด 58 ตรวจสอบว่าแก้ไขได้หรือไม่:boolean isCamera = (imageReturnedIntent == null || imageReturnedIntent.getData() == null);
Mario Velasco

โอเคอีมูเลเตอร์คือเวอร์ชั่น 6.0 และดูเหมือนว่าบรรทัด 58 นั้นใช้งานได้ดี บน emulator isCamera นั้นเป็นจริงและ getRotationFromCamera นั้นถูกเรียกว่า fine แต่ int ปฐมนิเทศคือ 0 ซึ่งหมายถึง getRotationFromCamera กำลังส่งคืน 0 ... อุปกรณ์ Sony ใช้ Android 4.2 และบน imageReturnedIntent หรือ imageReturnedIntent.getData () เป็นโมฆะที่บรรทัดที่ 58 ความหมาย isCamera เป็นเท็จและฉันไม่ได้รับเท่าที่เรียก
365SplendidSuns

8

รหัสนี้จะช่วยคุณในการที่มีสองปุ่มหนึ่งสำหรับกล้องและอีกหนึ่งสำหรับแกลลอรี่และภาพจะปรากฏใน ImageView

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


5
แม้ว่าลิงก์นี้อาจตอบคำถามได้ดีกว่าหากรวมส่วนสำคัญของคำตอบไว้ที่นี่และให้ลิงก์สำหรับการอ้างอิง คำตอบสำหรับลิงก์อย่างเดียวอาจไม่ถูกต้องหากการเชื่อมโยงหน้าเปลี่ยนแปลง
MrEngineer13

6

สำหรับผู้ที่ได้รับข้อผิดพลาดตั้งแต่ 4.4 ขึ้นไปในขณะที่พยายามใช้การเลือกรูปภาพสามารถใช้รหัสด้านล่าง

แทนที่จะสร้าง Dialog ด้วยรายการตัวเลือก Intent จะดีกว่าการใช้ Intent.createChooser เพื่อเข้าถึงไอคอนกราฟิกและชื่อย่อของ 'Camera', 'Gallery' และแม้แต่แอปเบราว์เซอร์ระบบไฟล์บุคคลที่สาม เช่น 'Astro' เป็นต้น

สิ่งนี้อธิบายวิธีการใช้ตัวเลือกมาตรฐานและเพิ่มความตั้งใจเพิ่มเติม

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

สวัสดี ฉันได้ลองวิธีการแก้ปัญหาของคุณแล้ว แต่การเลือกภาพจาก gallary ไม่ทำงาน: ลองดูที่นี่: stackoverflow.com/questions/36884651/…

ในอุปกรณ์ขนมหวานของฉันสิ่งนี้จะเลอะเมื่อใช้กล้อง สำหรับฉันข้อมูลไม่ใช่โมฆะ แต่การดำเนินการทำให้ isCamera ถูกตั้งค่าเป็นเท็จ
JStephen

6

สิ่งนี้ควรดูแลปัญหา null outputFileUri ของ 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 );
      }
    }
}

หมายเหตุ: ฉันกำลังใช้รหัสนี้ใน 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
นี่เป็นการวางจากที่อื่นใน SO ตัวอย่างเช่น getOutputMediaFileUri ทำอะไร โปรดแบ่งปันตัวอย่างที่สมบูรณ์พร้อมคำอธิบาย
kilokahn

0

สิ่งนี้ง่ายโดยใช้ AlertDialog และ 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

จากคำตอบของเดวิดสองเพนนีของฉันใน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();

จากนั้นสร้างวิธีใช้งานแบบโต้ตอบและทำสิ่งนี้

@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

ฉันทำงานหนักในการเลือกรูปภาพจากกล้องหรือแกลเลอรีและสร้างคลาส util สำหรับงานนี้ ด้วยการใช้'การเลือกกล้องถ่ายรูปหรือแกลเลอรีระดับง่ายเกินไป' คุณต้องใช้เวลา 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

เราจำเป็นต้องเพิ่มการอนุญาตเหล่านี้ในรายการ:

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

ฉันหวังว่ามันจะช่วยคุณถ้าใครมีข้อเสนอแนะในการปรับปรุงชั้นเรียนเหล่านี้โปรดเพิ่มความคิดเห็นของคุณในความคิดเห็น


มันมีปัญหา MediaUtils คลาสที่ใช้ใน BitmapUtils และ ImagePickerUtils อยู่ที่ไหน
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.