1. 程式人生 > >android呼叫系統相機拍攝多張照片

android呼叫系統相機拍攝多張照片

Android通過呼叫一次系統相機,拍攝多張照片並返回給activity,其實Android時沒有提供這樣的api的,但是可以通過其他的方式實現這個功能。

思路:在呼叫系統相機之前記下時間戳,等拍照後去系統圖片媒體庫中查詢圖片建立時間大於時間戳的圖片。

呼叫系統拍照,拍多張:

 intent.setAction(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
 activity.startActivityForResult(intent, TAKEONCAMERA);

呼叫系統拍一張的方法是,還有有點區別的:

Intent intentCamera = new Intent();
intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
activity.startActivityForResult(intentCamera, requestCode);

拍照完畢後返回到activity會回撥onActivityResult方法,在方法裡進行圖片的查詢:

    /**
     * 獲取拍攝的照片,在呼叫takeOnCamera之後返回介面時呼叫該方法。
     */
    public static List<String> getTakePhoto(Context context){

        Cursor cursor = null;
        try {
            cursor = context.getContentResolver()
                    .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, PROJECTION,
                            null, null,
                            MediaStore.Images.Media.DATE_ADDED +  " DESC LIMIT 0,30");
            if (cursor != null){
                List<String> photoList = new ArrayList<>(cursor.getCount());
                cursor.moveToFirst();
                while (!cursor.isAfterLast()){
                    long createTemp = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.DATE_ADDED));
                    if (isAfterStart(startTemp, createTemp)){
                        photoList.add(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)));
                    }
                    cursor.moveToNext();
                }
                return photoList;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (cursor != null){
                cursor.close();
            }
        }
        return null;
    }

完整的程式碼:

/**
 * -  相簿或拍照選取多張照片工具類
 * <p>
 * Created by Sunxy on 2018/9/8.
 */
public class GetPhotoUtils {

    public static final int TAKEONCAMERA = 1002;

    private  static final String[] PROJECTION = {MediaStore.Images.Media._ID,
            MediaStore.Images.Media.DATE_ADDED,
            MediaStore.Images.Media.DATA};

    private static long startTemp = Long.MAX_VALUE;
    private static int state = 0;


    /**
     * 得到手機中所有的照片(async)
     */
    public static List<String> getAllPhoto(Context context){

        Cursor cursor = null;
        try {
            cursor = context.getContentResolver()
                    .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, PROJECTION,
                            null, null,
                            MediaStore.Images.Media.DATE_ADDED +  " DESC");
            if (cursor != null){
                List<String> photoList = new ArrayList<>(cursor.getCount());
                cursor.moveToFirst();
                while (!cursor.isAfterLast()){
                    photoList.add(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)));
                    cursor.moveToNext();
                }
                return photoList;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (cursor != null){
                cursor.close();
            }
        }
        return null;
    }

    /**
     * 調手機相機拍多張照片
     */
    public static void takeOnCamera(Activity activity) {
        //開啟相機之前,記錄時間1
        startTemp = System.currentTimeMillis();
        Intent intent = new Intent();
        //此處之所以諸多try catch,是因為各大廠商手機不確定哪個方法
        try {
            intent.setAction(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
            activity.startActivityForResult(intent, TAKEONCAMERA);
        } catch (Exception e) {
            try {
                intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE_SECURE);
                activity.startActivityForResult(intent, TAKEONCAMERA);
            } catch (Exception e1) {
                try {
                    intent.setAction(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE);
                    activity.startActivityForResult(intent, TAKEONCAMERA);
                } catch (Exception ell) {
                    ToastUtils.showToast(activity, "開啟攝像機失敗,請從相簿選擇照片");
                }
            }
        }
    }


    /**
     * 獲取拍攝的照片,在呼叫takeOnCamera之後返回介面是呼叫該方法。
     */
    public static List<String> getTakePhoto(Context context){

        Cursor cursor = null;
        try {
            cursor = context.getContentResolver()
                    .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, PROJECTION,
                            null, null,
                            MediaStore.Images.Media.DATE_ADDED +  " DESC LIMIT 0,30");
            if (cursor != null){
                List<String> photoList = new ArrayList<>(cursor.getCount());
                cursor.moveToFirst();
                while (!cursor.isAfterLast()){
                    long createTemp = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media.DATE_ADDED));
                    if (isAfterStart(startTemp, createTemp)){
                        photoList.add(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)));
                    }
                    cursor.moveToNext();
                }
                return photoList;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (cursor != null){
                cursor.close();
            }
        }
        return null;
    }

    /**
     * 判斷照片建立時間是不是在開始之後,
     * 時間戳可能是10位或者是13位,要先統一位數
     *
     */
    private static boolean isAfterStart(long startTemp, long createTemp){
        if (state == 0){
            int startTempLength = String.valueOf(startTemp).length();
            int createTempLength = String.valueOf(createTemp).length();
            if (startTempLength == createTempLength){
                state = 1;
            }else if(startTempLength == 10 && createTempLength == 13){
                state = 2;
            }else if(startTempLength == 13 && createTempLength == 10){
                state = 3;
            }
        }
        if (state == 2){
            startTemp = startTemp * 1000;
        }else if(state == 3){
            startTemp = startTemp / 1000;
        }
        return createTemp - startTemp >= 0;
    }

}