android处理拍照与选择相册并可动态设置是否可裁剪下传解决方案
在网上看见很多人苦于android系统的兼容性问题,我话了点时间封装了一个可以调用的类
先贴工具类代码吧
package com.xia.ui.component;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
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.ContextThemeWrapper;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.Toast;
import com.xia.ui.R;
import com.xia.util.AlertUtil;
import com.xia.util.config;
/**
* 所有拍照基类 调用基类回调函数取值 注意调用该类必须从在activity 重新onActivityResult
*
* @auther:summer 时间: 2012-7-2 上午10:54:56
*/
public class PictureActivityUtil {
private static final String TAG = "PictureActivityUtil";
/** 用来标识请求照相功能的activity */
public static final int CAMERA_WITH_DATA = 168;
/** 用来标识请求gallery的activity */
public static final int PHOTO_PICKED_WITH_DATA = CAMERA_WITH_DATA+1;
/**图片裁剪*/
public static final int PHOTO_CROP = PHOTO_PICKED_WITH_DATA+1;
/**拍照的照片存储位置 */
private static final File PHOTO_DIR = new File(
Environment.getExternalStorageDirectory() + "/DCIM/Camera/");
private static File mCurrentPhotoFile;// 照相机拍照得到的图片
private static int cut_w,cut_h;//裁剪图片宽度,高度
/**
* 得到本地图片路径
* @return
*/
public static File getmCurrentPhotoFile() {
if(mCurrentPhotoFile==null){
if (!PHOTO_DIR.exists())
PHOTO_DIR.mkdirs();// 创建照片的存储目录
mCurrentPhotoFile = new File(PHOTO_DIR, "temp.jpg");
if(!mCurrentPhotoFile.exists())
try {
mCurrentPhotoFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
return mCurrentPhotoFile;
}
/**
* 设置裁剪图片尺寸
* @param w
* @param h
*/
public static void InitCutSize(int w,int h)
{
cut_w=w;
cut_h=h;
}
/**
* 开始启动照片选择框
*
* @param context
* @param iscrop
* 是否裁剪
*/
public static void doPickPhotoAction(final Activity context) {
final Context dialogContext = new ContextThemeWrapper(context,
android.R.style.Theme_Light);
String[] choices;
choices = new String[2];
choices[0] = context.getString(R.string.take_photo); // 拍照
choices[1] = context.getString(R.string.pick_photo); // 从相册中选择
final ListAdapter adapter = new ArrayAdapter<String>(dialogContext,
android.R.layout.simple_list_item_1, choices);
final AlertDialog.Builder builder = new AlertDialog.Builder(
dialogContext);
builder.setTitle(R.string.selePicTitle);
builder.setSingleChoiceItems(adapter, -1,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
switch (which) {
case 0: {
String status = Environment
.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED)) {// 判断是否有SD卡
doTakePhoto(context);// 用户点击了从照相机获取
} else {
AlertUtil.showToast(dialogContext, "没有找到SD卡");
}
break;
}
case 1:
doPickPhotoFromGallery(context);// 从相册中去获取
break;
}
}
});
builder.setNegativeButton(
context.getResources().getString(R.string.cancle),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
/**
* 拍照获取图片
*
*/
private static void doTakePhoto(Activity context) {
try {
if (!PHOTO_DIR.exists())
PHOTO_DIR.mkdirs();// 创建照片的存储目录
mCurrentPhotoFile = new File(PHOTO_DIR, "temp.jpg");// 给新照的照片文件命名
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mCurrentPhotoFile));
context.startActivityForResult(intent,
CAMERA_WITH_DATA);
} catch (ActivityNotFoundException e) {
Toast.makeText(context, R.string.photoPickerNotFoundText,
Toast.LENGTH_LONG).show();
if (config.DEBUG)
Log.e(TAG, e.toString());
}
}
/**
* 请求Gallery相册程序
* @param context
* @param iscrop
*/
private static void doPickPhotoFromGallery(Context context) {
try {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
((Activity) context).startActivityForResult(intent,
PHOTO_PICKED_WITH_DATA);
} catch (ActivityNotFoundException e) {
Toast.makeText(context, R.string.photoPickerNotFoundText1,
Toast.LENGTH_LONG).show();
if(config.DEBUG)
e.printStackTrace();
}
}
/**
* 所有图片裁剪回调
* @param context
* @param uri 图片资源地址
*/
public static void doCropPhoto(Activity context, Uri uri) {
try {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", true);
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", cut_w!=0? cut_w : config.w);
intent.putExtra("outputY", cut_h!=0? cut_h : config.h);
intent.putExtra("return-data", true);
context.startActivityForResult(intent,PHOTO_CROP);
} catch (Exception e) {
Toast.makeText(context, R.string.photoPickerNotFoundText,
Toast.LENGTH_LONG).show();
if (config.DEBUG)
Log.e(TAG, "裁剪:" + e.toString());
}
}
/**
* 获取不裁剪时图片返回的路径
* @param activity
* @param data
* @return path
*/
public static String getNoCropPath(Activity activity,Intent data)
{
String path="";
if(data==null)
return getmCurrentPhotoFile().toString();
Uri imageuri=data.getData();
if(imageuri==null){
String str=data.getAction();
imageuri = Uri.parse(str);
}
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = activity.managedQuery(imageuri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
if (cursor.moveToFirst()) {
path = cursor.getString(column_index);
}
return path;
}
/**
* 裁剪后的图片路径
* @return
*/
public static String getCropPath(Intent data)
{
Bundle extras = data.getExtras();
Bitmap myBitmap = (Bitmap) extras.get("data");
FileOutputStream fos=null;
try {
fos = new FileOutputStream(PictureActivityUtil.getmCurrentPhotoFile());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
return PictureActivityUtil.getmCurrentPhotoFile().toString();
}
}
在activity里使用方法如下:
1.首先在public void onClick(View v) {
PictureActivityUtil.doPickPhotoAction(MeActivity.this);
}
调用选择弹窗截图如下:
2.回调的时候在
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==RESULT_OK)
{
switch (requestCode) {
case PictureActivityUtil.PHOTO_PICKED_WITH_DATA: // 调用Gallery返回的
System.out.println("tmd=============="+data);
/*String path1=PictureActivityUtil.getNoCropPath(MeActivity.this, data);
Bitmap photobtm1=BitmapFactory.decodeFile(path1);
if(photobtm1!=null){
currentvestface.setImageBitmap(photobtm1);
}*/
PictureActivityUtil.doCropPhoto(MeActivity.this, data.getData());
break;
case PictureActivityUtil.CAMERA_WITH_DATA: // 照相机程序返回的
System.out.println("tmd2=============="+data);
//不需要裁剪及返回图片地址及图片位图对象
/*String paths=PictureActivityUtil.getNoCropPath(MeActivity.this, data);
Bitmap photobtm=BitmapFactory.decodeFile(paths);
if(photobtm!=null){
currentvestface.setImageBitmap(photobtm);
}*/
PictureActivityUtil.doCropPhoto(MeActivity.this,Uri.fromFile(PictureActivityUtil.getmCurrentPhotoFile())); //如果不裁剪及不需要调用该方法
break;
case PictureActivityUtil.PHOTO_CROP: //图片裁剪操作
String path2=PictureActivityUtil.getCropPath(data);
Bitmap photo2=BitmapFactory.decodeFile(path2);
if(photo2!=null)
currentvestface.setImageBitmap(photo2);
break;
}
}
3.上传服务器代码如下:
/**
* 上传文件至Server的方法并返回是否上传成功数据
*
* @param uri
* 服务器请求地址
* @param netClass
* 网络类型
* @param filePath
* 文件全路径
* @param fileName
* 文件名
* @return
*/
public static String uploadFileToWebServer(String uri, String netClass,
String filePath, String fileName) {
String end = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
String HTTPBody = "";
try {
URL url = new URL(uri);
HttpURLConnection conn = null;
if (netClass.indexOf("wap") >= 0) {
String proxyIP = getWAPGatewayIP(netClass);
Proxy proxy = new Proxy(java.net.Proxy.Type.HTTP,
new InetSocketAddress(proxyIP, 80));
conn = (HttpURLConnection) url.openConnection(proxy);
} else {
conn = (HttpURLConnection) url.openConnection();
}
/* 允许Input、Output,不使用Cache */
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
/* 设置传送的method=POST */
conn.setRequestMethod("POST");
/* setRequestProperty */
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
/* 设置DataOutputStream */
DataOutputStream ds = new DataOutputStream(conn.getOutputStream());
ds.writeBytes(twoHyphens + boundary + end);
ds.writeBytes("Content-Disposition: form-data; "
+ "name=\"uploadfile\";filename=\"" + fileName + "\"" + end);
ds.writeBytes(end);
/* 取得文件的FileInputStream */
FileInputStream fStream = new FileInputStream(filePath);
/* 设置每次写入1024bytes */
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int length = -1;
/* 从文件读取数据至缓冲区 */
while ((length = fStream.read(buffer)) != -1) {
/* 将资料写入DataOutputStream中 */
ds.write(buffer, 0, length);
}
ds.writeBytes(end);
ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
/* close streams */
fStream.close();
ds.flush();
// 读取返回信息
InputStream in = conn.getInputStream();
int ch = 0;
ByteArrayOutputStream out = new ByteArrayOutputStream();
while ((ch = in.read()) != -1) {
out.write(ch);
}
HTTPBody = out.toString();
conn.disconnect();
in.close();
out.close();
} catch (Exception e) {
HTTPBody = "[数据错误]" + e.getMessage();
}
return HTTPBody;
}