1、系统权限
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
第一种方法:
startActivityForResult(new Intent("android.media.action.IMAGE_CAPTURE"), TAKE_PICTURE);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PICTURE) {
if (resultCode == RESULT_OK) {
Bitmap bm = (Bitmap) data.getExtras().get("data");
img.setImageBitmap(bm);//想图像显示在ImageView视图上,
}
}
}
但是这种得到的图片是缩略图,清晰度不够,本人没有找到获得原始大图方法。
本人使用的是第二种方法:基本思想是在点击拍照时就建立起文件,当拍照完成后将bitmp填充进入
try {
Intent takePictureIntent = new Intent(
MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent
.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
picPath = photoFile.getAbsolutePath();
} catch (IOException ex) {
ex.printStackTrace();
}
if (photoFile != null) {
takePictureIntent.putExtra(
MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent,
RESULT_take_pic);
}
}
} catch (Exception e) {
}
public File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = new File(DirectoryUtil.getPicDirectory());
if (!storageDir.isDirectory())
storageDir.mkdirs();
File image = File.createTempFile(imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return image;
}
拍照成功后返回执行函数:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQ_VIEW_IMAGE) {
Log.e("zhy", requestCode + "");
mGrideAdapter.notifyDataSetChanged();
} else if (requestCode == RESULT_take_pic) {
if(picPath ==null){
showLongToast("拍照失败请选择图片上传");
}else{
File file = new File(picPath);
Long size = file.length();
if (size <= 0) { //拍照失败删除文件
if (file.exists()) {
file.delete();
}
} else { //拍照成功显示图片
NativeImageLoader.mSelectList.add(picPath);
mGrideAdapter.notifyDataSetChanged();
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}
上述方法可以获得清晰的图片。
问题研究及解决:
用上述第二种方法的时候本人发现在三星部分手机(如note3)上拍照后activity会重启,如果不做任何处理重启后所有当前状态没有返回picPath=null则会导致死机。
在想到是activity重启导致状态丢失,本人首先想到在销毁前保存当前的现场状态,重启时回复现场。即做如下处理:
/**
* activity进入后台变得可能被销毁是调用
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("picPath", picPath); //保存当前拍照图片的地址
List<String> lt = NativeImageLoader.mSelectList;
outState.putString("mlistPath", ListToString(lt)); //保存已选择的所有图片地址可能多张
super.onSaveInstanceState(outState);
}
private String ListToString(List<String> list){
StringBuffer sb = new StringBuffer();
for(int i = 0; i<list.size(); i++){
String s = list.get(i);
sb.append(s);
sb.append(",");
}
return sb.toString();
}
/**
* 当actvity从非正常销毁进入时调用
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
addingPic(); //恢复界面控件的状态
String listStr = savedInstanceState.getString("mlistPath");
if(listStr != null && !"".equals(listStr)){
String[] strs = listStr.split(",");
NativeImageLoader.mSelectList.addAll(Arrays.asList(strs));
}
picPath = savedInstanceState.getString("picPath"); //获得当前拍照图片的地址
}
上述方法可以解决此问题,但是本人还有一个地方不明白
outState.putStringArrayList(); //api中给出此方法可以保存数组但是实际上得不到保存的数据
于是本人将数组转换为string中间用,分割,如下:
outState.putString("mlistPath", ListToString(lt)); //保存已选择的所有图片地址可能多张
问题虽然解决了但是为什么会出现这样的问题呢?后来我仔细查看了那个手机的拍照过程,中间好像是activity发生旋转。后来我在mainfest中配置了android:configChanges="keyboardHidden|orientation|screenSize"此属性。发现此问题解决了activity并没有销毁,如此证明我的猜想是正确的。注意keyboardHidden|orientation|screenSize一定要配置这三个属性,一开始本人只配置两个,导致后来才想到了保持状态的方法。此上两种方法均可以解决此问题,明显第二种要简单很多!