先声明授人与鱼不如授人与渔,只能提供一个思路,当然需要源码的同学可以私下有偿问我要源码:QQ:508181017
工作了将近三年时间了,一直没正儿八经的研究系统自带的相册和拍照,这回来个高仿微信的拍照、多选、预览、删除(去除相片)相册功能,之前开发的所有应用都带有这需求,但是一直都不实用!废话就不多说了,先来捋一下思路:
1、拍照能实时保存到本地并实时查询(不必用广播或者服务)
2、拍照保存到到自定义路径并根据不同文件夹显示文件夹下的相片
3、多选规定张数图片
4、用到的集合有:
(1)、所有相片集合
(2)、不同文件下相片集合
(3)、系统保存相片的文件夹集合
(4)、已选中相片集合
5、每次选中返回上级界面时都要传递已选中的相片来跟当前所显示的相册集合进行对比使得checkbox是否勾选
6、自己碰到的问题有:
(1)、当选择相片量超过特定数量时CheckBox的setOnCheckedChangeListener事件会出现错误(不是bug,可能我的代码逻辑不够严谨),主要是在设定控件自带的setChecked(false|true)方法时出现的;所以我用了onClick方法来实现其选中状态。
(2)、预览相册返回上级(展示文件夹下的相片)时集合的对比,在考虑到性能的情况下,本人用了map集合来记录保存已选中的相片,回调界面时遍历当前文件夹下的相片判断map集合是否包含,包含则让checkbox为选中状态。
(3)、在删除图片时,自己的业务并不和微信的一样,此项目只让用户选中和不选中而已回调到界面一样是可以显示自己所要的效果。
7、主要代码:
(1)、获取最近照片列表
public List<PhotoModel> getCurrent() { Cursor cursor = resolver.query(Media.EXTERNAL_CONTENT_URI, new String[] { ImageColumns.DATA, ImageColumns.DATE_ADDED, ImageColumns.SIZE }, null, null, ImageColumns.DATE_ADDED); if (cursor == null || !cursor.moveToNext()) return new ArrayList<PhotoModel>(); List<PhotoModel> photos = new ArrayList<PhotoModel>(); cursor.moveToLast(); do { if (cursor.getLong(cursor.getColumnIndex(ImageColumns.SIZE)) > 1024 * 10) { PhotoModel photoModel = new PhotoModel(); photoModel.setOriginalPath(cursor.getString(cursor.getColumnIndex(ImageColumns.DATA))); photos.add(photoModel); } } while (cursor.moveToPrevious()); return photos; }
(2)、获取所有相册列表
public List<AlbumModel> getAlbums() { List<AlbumModel> albums = new ArrayList<AlbumModel>(); Map<String, AlbumModel> map = new HashMap<String, AlbumModel>(); Cursor cursor = resolver.query(Media.EXTERNAL_CONTENT_URI, new String[] { ImageColumns.DATA, ImageColumns.BUCKET_DISPLAY_NAME, ImageColumns.SIZE }, null, null, null); if (cursor == null || !cursor.moveToNext()) return new ArrayList<AlbumModel>(); cursor.moveToLast(); AlbumModel current = new AlbumModel("最近照片", 0, cursor.getString(cursor.getColumnIndex(ImageColumns.DATA)), true); // "最近照片"相册 albums.add(current); do { if (cursor.getInt(cursor.getColumnIndex(ImageColumns.SIZE)) < 1024 * 10) continue; current.increaseCount(); String name = cursor.getString(cursor.getColumnIndex(ImageColumns.BUCKET_DISPLAY_NAME)); if (map.keySet().contains(name)) map.get(name).increaseCount(); else { AlbumModel album = new AlbumModel(name, 1, cursor.getString(cursor.getColumnIndex(ImageColumns.DATA))); map.put(name, album); albums.add(album); } } while (cursor.moveToPrevious()); return albums; }
(3)、获取对应相册下的照片
public List<PhotoModel> getAlbum(String name) { Cursor cursor = resolver.query(Media.EXTERNAL_CONTENT_URI, new String[] { ImageColumns.BUCKET_DISPLAY_NAME, ImageColumns.DATA, ImageColumns.DATE_ADDED, ImageColumns.SIZE }, "bucket_display_name = ?", new String[] { name }, ImageColumns.DATE_ADDED); if (cursor == null || !cursor.moveToNext()) return new ArrayList<PhotoModel>(); List<PhotoModel> photos = new ArrayList<PhotoModel>(); cursor.moveToLast(); do { if (cursor.getLong(cursor.getColumnIndex(ImageColumns.SIZE)) > 1024 * 10) { PhotoModel photoModel = new PhotoModel(); photoModel.setOriginalPath(cursor.getString(cursor.getColumnIndex(ImageColumns.DATA))); photos.add(photoModel); } } while (cursor.moveToPrevious()); return photos; }
(4)、拍照并及时更新本地相册
public void photo() { // Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // startActivityForResult(openCameraIntent, TAKE_PICTURE); try { File dir = new File(Environment.getExternalStorageDirectory()+ "/" + localTempImgDir); System.out.println("图片名称:"+dir.getPath()); if (!dir.exists()){ dir.mkdirs(); } localTempImgFileName=System.currentTimeMillis()+".jpg"; Intent intent = new Intent( android.provider.MediaStore.ACTION_IMAGE_CAPTURE); File f = new File(dir, localTempImgFileName);// localTempImgDir和localTempImageFileName是自己定义的名字 Uri u = Uri.fromFile(f); intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0); intent.putExtra(MediaStore.EXTRA_OUTPUT, u); startActivityForResult(intent, ResultTag.CODE_TOPHOTO); } catch (ActivityNotFoundException e) { Toast.makeText(PublishActivity.this, "没有找到储存目录",Toast.LENGTH_LONG).show(); } }
(5)、拍照并及时更新本地相册
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //相机照相返回 if (requestCode == ResultTag.CODE_TOPHOTO) { File f = new File(Environment.getExternalStorageDirectory() + "/" + localTempImgDir + "/" + localTempImgFileName); String sdStatus = Environment.getExternalStorageState(); if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用 Log.v("TestFile","SD card is not avaiable/writeable right now."); return; } try { Uri u = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), f.getAbsolutePath(), null, null)); System.out.println("地址为:"+f.getAbsolutePath()); MediaScannerConnection.scanFile(this, new String[] { f.getAbsolutePath()}, null, new MediaScannerConnection.OnScanCompletedListener() { public void onScanCompleted(String path, Uri uri) { Log.i("ExternalStorage", "Scanned " + path + ":"); Log.i("ExternalStorage", "-> uri=" + uri); } }); } catch (FileNotFoundException e) { e.printStackTrace(); } PhotoModel takePhoto = new PhotoModel(); takePhoto.setChecked(true); takePhoto.setOriginalPath(f.getAbsolutePath()); selectedShow.add(takePhoto); adapter.notifyDataSetChanged(); } }
时间: 2024-11-03 01:24:47