首先,由于要调用系统的dialog,所以我们定义一个字符串数组用以显示item:
public static final String[] items = {"相机拍摄","手机相册","取消"};
然后,调用下面这段代码来处理拍照及选择照片:
public static void SelectPhoto(String UserID)
{
AppActivity.fileName = UserID+".png";
if(cpGame!=null)
{
cpGame.runOnUiThread(new Runnable() {
@Override
public void run() {
AlertDialog.Builder builder = new AlertDialog.Builder(
cpGame);
builder.setTitle("选择头像");
builder.setItems(items, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
String select_item = items[which].toString();
if(which == 0)
{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 拍照上传
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(AppActivity.tempFile));
//在onActivityResult中接收
cpGame.startActivityForResult(intent, CAMERA_REQUEST_CODE);
}
else if(which == 1)
{
// 相册上传
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
cpGame.startActivityForResult(intent, PICTURE_REQUEST_CODE);
}
}
});
builder.show();
}
});
}
}
其中的AppActivity.fileName是要保存的文件名,cpGame是从AppActivity传过来的this指针:
Activity cpGame = AppActivity.this;
public static final int CAMERA_REQUEST_CODE = 222;//调用相机code
public static final int PICTURE_REQUEST_CODE = 444;//调用相册code
public static final int PHOTO_REQUEST_CUT = 666;//照片裁剪code
public static File tempFile = new File(Environment.getExternalStorageDirectory(),getPhotoFileName());//拍照保存的文件路径
// 使用系统当前日期加以调整作为照片的名称
private static String getPhotoFileName() {
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat dateFormat = new SimpleDateFormat(
"'IMG'_yyyyMMdd_HHmmss");
return dateFormat.format(date) + ".jpg";
}
然后,在AppActivity的onActivityResult()函数中接收并处理所取到的照片数据,这个函数会在acticity切换的时候回调:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//拍照回调
switch (requestCode) {
case MyPlatform.CAMERA_REQUEST_CODE:// 当选择拍照时调用
startPhotoZoom(Uri.fromFile(tempFile));
break;
case MyPlatform.PICTURE_REQUEST_CODE:// 当选择从本地获取图片时
// 做非空判断,当我们觉得不满意想重新剪裁的时候便不会报异常,下同
if (data != null)
startPhotoZoom(data.getData());
break;
case MyPlatform.PHOTO_REQUEST_CUT:// 返回的结果
if (data != null)
{
Bundle bundle = data.getExtras();
if (bundle != null)
{
Bitmap photo = bundle.getParcelable("data");
if (photo!=null)
{
MyPlatform.saveMyBitmap(photo);
}
}
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
这里如果是拍照返回,则直接从所保存的路径tempFile中取到数据,如果是相册返回,则直接用data.getData()取数据,取到数据之后我们开始对照片进行缩放剪裁:
private void startPhotoZoom(Uri uri) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
// crop为true是设置在开启的intent中设置显示的view可以剪裁
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX,outputY 是剪裁图片的宽高
intent.putExtra("outputX", mWH);
intent.putExtra("outputY", mWH);
intent.putExtra("return-data", true);
intent.putExtra("noFaceDetection", true);
startActivityForResult(intent, MyPlatform.PHOTO_REQUEST_CUT);
}
这里的mWH = 300,此时剪裁之后的图片不会过于失真,然后,这里剪裁之后,又会调用onActivityResult()函数来处理结果,也就是上面代码中的
case MyPlatform.PHOTO_REQUEST_CUT
在这里我们基本已经做完了对照片的所有处理,那么下一步我们就开始保存图片:
//保存照片到本地img_interim文件夹下,便于上传
@SuppressLint("SdCardPath")
public static void saveMyBitmap(Bitmap bit) {
bm = bit;
if(cpGame!=null)
{
cpGame.runOnUiThread(new Runnable() {
@Override
public void run() {
File dir = new File(AppActivity.path+"/img_interim/");
if (!dir.exists()) {
dir.mkdir();
}
saveFile = new File(AppActivity.path+"/img_interim/" + AppActivity.fileName);
try {
saveFile.createNewFile();
FileOutputStream fOut = null;
fOut = new FileOutputStream(saveFile);
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
//这里的saveFile就是最终取到的照片路径
} catch (IOException e1) {
// TODO Auto-generated catch block
saveFile = null;
e1.printStackTrace();
}
}
});
}
}
这里的一些参数的初始值:
public static String path = Environment.getExternalStorageDirectory().getPath();
public static Bitmap bm=null;
AppActivity.fileName就是最开始我们所说的要保存的文件名字