Android仿微信选择照片,拍照

效果图:
效果图:

使用的方法简单粗暴,直接利用ContentResolver查询系统媒体数据库,拿到每张图片的实际路径,然后得到他们所在的目录,将其按目录分类(原来测试的是拿到缩略图,但是在模拟器上测试可以,我的手机上一直报找不到缩略图的异常,可能是垃圾手机的原因,不过微信也是没用那缩略图)
我把代码都封装到一个Activity中了(SelectPictureActivity.java),下次再使用直接复制就可以用,布局样式需要在layout中修改

使用
startActivityForResult(new Intent(this, SelectPictureActivity.class), REQUEST_PICK);

然后选择完成返回选择的图片路径的list

1
2
3
4
5
6
7
8
9
10
@SuppressWarnings("unchecked")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
selectedPicture = (ArrayList<String>) data
.getSerializableExtra(SelectPictureActivity.INTENT_SELECTED_PICTURE);
adapter.notifyDataSetChanged();
}
}

完整的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
package com.zyh.selectpicture;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;

public class SelectPictureActivity extends Activity {

/**
* 最多选择图片的个数
*/
private static int MAX_NUM = 6;
private static final int TAKE_PICTURE = 520;

public static final String INTENT_MAX_NUM = "intent_max_num";
public static final String INTENT_SELECTED_PICTURE = "intent_selected_picture";

private Context context;
private GridView gridview;
private PictureAdapter adapter;
/**
* 临时的辅助类,用于防止同一个文件夹的多次扫描
*/
private HashMap<String, Integer> tmpDir = new HashMap<String, Integer>();
private ArrayList<ImageFloder> mDirPaths = new ArrayList<ImageFloder>();

private ImageLoader loader;
private DisplayImageOptions options;
private ContentResolver mContentResolver;
private Button btn_select, btn_ok;
private ListView listview;
private FolderAdapter folderAdapter;
private ImageFloder imageAll, currentImageFolder;

/**
* 已选择的图片
*/
private ArrayList<String> selectedPicture = new ArrayList<String>();
private String cameraPath = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_select_picture);
MAX_NUM = getIntent().getIntExtra(INTENT_MAX_NUM, 6);
context = this;
mContentResolver = getContentResolver();
loader = ImageLoader.getInstance();
options = new DisplayImageOptions.Builder().showImageOnLoading(R.drawable.ic_launcher)
.showImageForEmptyUri(R.drawable.ic_launcher).showImageOnFail(R.drawable.ic_launcher)
.cacheInMemory(true).cacheOnDisk(true).considerExifParams(true)
.imageScaleType(ImageScaleType.EXACTLY).bitmapConfig(Bitmap.Config.RGB_565).build();
initView();
}

public void select(View v) {
if (listview.getVisibility() == 0) {
hideListAnimation();
} else {
listview.setVisibility(0);
showListAnimation();
folderAdapter.notifyDataSetChanged();
}
}

public void showListAnimation() {
TranslateAnimation ta = new TranslateAnimation(1, 0f, 1, 0f, 1, 1f, 1, 0f);
ta.setDuration(200);
listview.startAnimation(ta);
}

public void hideListAnimation() {
TranslateAnimation ta = new TranslateAnimation(1, 0f, 1, 0f, 1, 0f, 1, 1f);
ta.setDuration(200);
listview.startAnimation(ta);
ta.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}

@Override
public void onAnimationRepeat(Animation animation) {
}

@Override
public void onAnimationEnd(Animation animation) {
listview.setVisibility(8);
}
});
}

/**
* 点击完成按钮
*
* @version 1.0
* @author zyh
* @param v
*/
public void ok(View v) {
Intent data = new Intent();
data.putExtra(INTENT_SELECTED_PICTURE, selectedPicture);
setResult(RESULT_OK, data);
this.finish();
}

private void initView() {
imageAll = new ImageFloder();
imageAll.setDir("/所有图片");
currentImageFolder = imageAll;
mDirPaths.add(imageAll);
btn_ok = (Button) findViewById(R.id.btn_ok);
btn_select = (Button) findViewById(R.id.btn_select);
btn_ok.setText("完成0/" + MAX_NUM);

gridview = (GridView) findViewById(R.id.gridview);
adapter = new PictureAdapter();
gridview.setAdapter(adapter);

gridview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 0) {
goCamare();
}
}
});

listview = (ListView) findViewById(R.id.listview);
folderAdapter = new FolderAdapter();
listview.setAdapter(folderAdapter);
listview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
currentImageFolder = mDirPaths.get(position);
Log.d("zyh", position + "-------" + currentImageFolder.getName() + "----"
+ currentImageFolder.images.size());
hideListAnimation();
adapter.notifyDataSetChanged();
btn_select.setText(currentImageFolder.getName());
}
});
getThumbnail();
}

/**
* 使用相机拍照
*
* @version 1.0
* @author zyh
*/
protected void goCamare() {
if (selectedPicture.size() + 1 > MAX_NUM) {
Toast.makeText(context, "最多选择" + MAX_NUM + "张", Toast.LENGTH_SHORT).show();
return;
}

Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri imageUri = getOutputMediaFileUri();
openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(openCameraIntent, TAKE_PICTURE);
}

/**
* 用于拍照时获取输出的Uri
*
* @version 1.0
* @author zyh
* @return
*/
protected Uri getOutputMediaFileUri() {
File mediaStorageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Night");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
cameraPath = mediaFile.getAbsolutePath();
return Uri.fromFile(mediaFile);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && cameraPath != null) {
selectedPicture.add(cameraPath);
Intent data2 = new Intent();
data2.putExtra(INTENT_SELECTED_PICTURE, selectedPicture);
setResult(RESULT_OK, data2);
this.finish();
}
}

public void back(View v) {
onBackPressed();
}

class PictureAdapter extends BaseAdapter {
@Override
public int getCount() {
return currentImageFolder.images.size() + 1;
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder = null;
if (convertView == null) {
convertView = View.inflate(context, R.layout.grid_item_picture, null);
holder = new ViewHolder();
holder.iv = (ImageView) convertView.findViewById(R.id.iv);
holder.checkBox = (Button) convertView.findViewById(R.id.check);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (position == 0) {
holder.iv.setImageResource(R.drawable.pickphotos_to_camera_normal);
holder.checkBox.setVisibility(View.INVISIBLE);
} else {
position = position - 1;
holder.checkBox.setVisibility(View.VISIBLE);
final ImageItem item = currentImageFolder.images.get(position);
loader.displayImage("file://" + item.path, holder.iv, options);
boolean isSelected = selectedPicture.contains(item.path);
holder.checkBox.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (!v.isSelected() && selectedPicture.size() + 1 > MAX_NUM) {
Toast.makeText(context, "最多选择" + MAX_NUM + "张", Toast.LENGTH_SHORT).show();
return;
}
if (selectedPicture.contains(item.path)) {
selectedPicture.remove(item.path);
} else {
selectedPicture.add(item.path);
}
btn_ok.setText("完成" + selectedPicture.size() + "/" + MAX_NUM);
v.setSelected(selectedPicture.contains(item.path));
}
});
holder.checkBox.setSelected(isSelected);
}
return convertView;
}
}

class ViewHolder {
ImageView iv;
Button checkBox;
}

class FolderAdapter extends BaseAdapter {

@Override
public int getCount() {
return mDirPaths.size();
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
FolderViewHolder holder = null;
if (convertView == null) {
convertView = View.inflate(context, R.layout.list_dir_item, null);
holder = new FolderViewHolder();
holder.id_dir_item_image = (ImageView) convertView.findViewById(R.id.id_dir_item_image);
holder.id_dir_item_name = (TextView) convertView.findViewById(R.id.id_dir_item_name);
holder.id_dir_item_count = (TextView) convertView.findViewById(R.id.id_dir_item_count);
holder.choose = (ImageView) convertView.findViewById(R.id.choose);
convertView.setTag(holder);
} else {
holder = (FolderViewHolder) convertView.getTag();
}
ImageFloder item = mDirPaths.get(position);
loader.displayImage("file://" + item.getFirstImagePath(), holder.id_dir_item_image, options);
holder.id_dir_item_count.setText(item.images.size() + "张");
holder.id_dir_item_name.setText(item.getName());
holder.choose.setVisibility(currentImageFolder == item ? 0 : 8);
return convertView;
}
}

class FolderViewHolder {
ImageView id_dir_item_image;
ImageView choose;
TextView id_dir_item_name;
TextView id_dir_item_count;
}

/**
* 得到缩略图
*/
private void getThumbnail() {
Cursor mCursor = mContentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Images.ImageColumns.DATA }, "", null,
MediaStore.MediaColumns.DATE_ADDED + " DESC");
Log.e("TAG", mCursor.getCount() + "");
if (mCursor.moveToFirst()) {
int _date = mCursor.getColumnIndex(MediaStore.Images.Media.DATA);
do {
// 获取图片的路径
String path = mCursor.getString(_date);
Log.e("TAG", path);
imageAll.images.add(new ImageItem(path));
// 获取该图片的父路径名
File parentFile = new File(path).getParentFile();
if (parentFile == null) {
continue;
}
ImageFloder imageFloder = null;
String dirPath = parentFile.getAbsolutePath();
if (!tmpDir.containsKey(dirPath)) {
// 初始化imageFloder
imageFloder = new ImageFloder();
imageFloder.setDir(dirPath);
imageFloder.setFirstImagePath(path);
mDirPaths.add(imageFloder);
Log.d("zyh", dirPath + "," + path);
tmpDir.put(dirPath, mDirPaths.indexOf(imageFloder));
} else {
imageFloder = mDirPaths.get(tmpDir.get(dirPath));
}
imageFloder.images.add(new ImageItem(path));
} while (mCursor.moveToNext());
}
mCursor.close();
for (int i = 0; i < mDirPaths.size(); i++) {
ImageFloder f = mDirPaths.get(i);
Log.d("zyh", i + "-----" + f.getName() + "---" + f.images.size());
}
tmpDir = null;
}

class ImageFloder {
/**
* 图片的文件夹路径
*/
private String dir;

/**
* 第一张图片的路径
*/
private String firstImagePath;
/**
* 文件夹的名称
*/
private String name;

public List<ImageItem> images = new ArrayList<ImageItem>();

public String getDir() {
return dir;
}

public void setDir(String dir) {
this.dir = dir;
int lastIndexOf = this.dir.lastIndexOf("/");
this.name = this.dir.substring(lastIndexOf);
}

public String getFirstImagePath() {
return firstImagePath;
}

public void setFirstImagePath(String firstImagePath) {
this.firstImagePath = firstImagePath;
}

public String getName() {
return name;
}

}

class ImageItem {
String path;

public ImageItem(String p) {
this.path = p;
}
}

}

源码下载:https://github.com/18236887539/SelectPicture