相信很多朋友在開發(fā)安卓App時都會有這樣需求,圖片選擇或拍照選擇,需求實現(xiàn)很簡單,如下:
- 圖片選擇:調用系統(tǒng)圖庫進行選擇
- 拍照選擇:調用系統(tǒng)相機進行拍照
看了上面的實現(xiàn)后發(fā)現(xiàn)很容易啊,都有現(xiàn)成的調用;但我們錯了,對于產品的BT需求,我們遠遠無法這么簡單的滿足,比如:圖片多選上傳了?額,這個時候我們調用系統(tǒng)的圖庫就蒙B了,因為系統(tǒng)圖庫并不支持多選;那怎么辦了?不急,請慢慢往下看,這就是這篇Blog的意義所在,定義一個自己的圖片選擇器
本項目已經開發(fā)完畢了,下面是相應的地址
GitHub:https://github.com/JaySong/PhotoPicker
Gradle引用:'com.jay.ui:photopicker:last-version';目前版本:1.0.0
此工程實現(xiàn)的功能:
- 圖片的單選或多選<可自定最大選擇數量>
- 可根據不同圖片文件夾進行篩選
- 圖片的預覽
- 相機拍照選擇
總結:微信選擇圖片的功能基本都有,可滿足大部分需求,UI界面采用MD風格設計
需要解決的技術問題
- 得到手機中所有的圖片并顯示在列表
- 實現(xiàn)列表的單選或多選
1.得到手機中所有的圖片并顯示在列表
實現(xiàn):采用LoaderManager.LoaderCallbacks<Cursor>時行圖片的查詢,下面見核心代碼
PS:當前需要實現(xiàn)加載的類可實現(xiàn)此接口或自己自定義一個類實現(xiàn)此接口
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
@SuppressWarnings("UnnecessaryLocalVariable")
CursorLoader cursorLoader = new CursorLoader(
this,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME},
"mime_type=? or mime_type=?" + (isShowGif ? "or mime_type=?" : ""),
isShowGif ? new String[]{"image/jpeg", "image/png", "image/gif"} : new String[]{"image/jpeg", "image/png"},
MediaStore.Images.Media.DATE_ADDED + " DESC"
);
return cursorLoader;
}
>getLoaderManager().initLoader(int,Bundle, LoaderManager.LoaderCallbacks);
通過此方法進行初始化,如果要兼容到11以下的系統(tǒng),調用
getSupportLoaderManager()..initLoader(int,Bundle, LoaderManager.LoaderCallbacks);
onCreateLoader()方法是接口中必須實現(xiàn)的方法;
new CursorLoader(Context context,
Uri uri, //查詢的Uri
String[] projection, //列名
String selection,//查詢條件
String[] selectionArgs, //查詢條件中的參數
String sortOrder)//排序規(guī)則
onLoadFinished(Loader<Cursor> loader, Cursor data)方法會在查詢完成后回調,其中data就是我們想要的結果就在此對象中
if (data.moveToFirst()) {
do {
String photoDir = data.getString(data.getColumnIndex(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME));
String photoUri = data.getString(data.getColumnIndex(MediaStore.Images.Media.DATA));
} while (data.moveToNext());
}
//photoDir:當前圖片所在的目錄名
//photoUri:當前圖片的路徑
2.實現(xiàn)列表的單選或多選
列表的顯示是使用控件RecyclerView實現(xiàn)展示,圖片選中控件是使用CheckBox來進行圖片的選擇標識,具體請查看源碼PhotoPickerActivity.PhotoListAdapter適配器類
拍照并顯示至列表
實現(xiàn)方式:同樣調用系統(tǒng)相機
//用戶要拍照
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePhotoFile = createImageFile();
// Continue only if the File was successfully created
if (takePhotoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(takePhotoFile));
startActivityForResult(takePictureIntent, TAKE_PHOTO);
} else {
showSnackBar(getString(R.string.open_camera_fail));
}
//其中createImageFile()返回一個文件File,即拍照后保存的路徑
拍照成功需要更新列表,這個時候我們做一個操作即可,那就是提醒系統(tǒng)更新媒體庫
public void notifyMediaUpdate(File file) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
//這樣操作后,我們前面實現(xiàn)的加載器會自動去加載新的數據,參數file就是我們之前拍照前保存的保存路徑
下面上一張演示圖