在Android应用中,用户模块一般会有头像上传的功能,即用户可以调用摄像头拍照或者从本地图库中选择图片上传,用户打开应用登陆后即可显示上传的头像。
要想实现Android拍照+选择本地图片上传的功能,主要需要掌握以下几点:
- 调用系统照相机拍照
- 打开本地图库选择本地图片
- 将图片上传到服务器
(1)调用系统照相机拍照
//调用系统照相机拍照
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
context.startActivityForResult(intent,TAKEPAHOT_REQUEST_CODE);
//在Activity的onActivityResult方法中获取到拍照后的照片
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKEPAHOT_REQUEST_CODE) {
if (data != null) {
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
}
}
(2)打开本地图库选择图片
//打开本地图库选择图片
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent2.setType("image/*");
context.startActivityForResult(intent, GALLERY_REQUEST_CODE);
//在Activity的onActivityResult方法中获取选择的图片的Uri
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == GALLERY_REQUEST_CODE) {
if (data != null) {
Uri uri = data.getData();// 返回的是一个content类型的Uri
}
但是这里要注意一下从本地图库中选择图片返回的是一个Uri,这个Uri是一个Content类型的Uri;Android中有两种Uri,一种是File类型的Uri,一种是Content类型的Uri,一般我们可以直接使用的是File类型的Uri,但是从本地图库中选择图片后,获取到的是一个Content类型的Uri,所以我们需要把Content类型的Uri转成File类型的Uri。
Content类型的Uri转成File类型的Uri主要是把Content类型的Uri保存到SD卡中,然后获取保存的路径的Uri,也即转成的File类型的Uri。提供如下两个方法:
saveImg(Bitmap bitmap)将图片保存到SD卡中,convertUri(Uri contentUri)将content类型的Uri转成File类型的Uri:
//将Content类型的Uri转成File类型的Uri
public Uri convertUri(Uri contentUri) {
Uri uri = null;
InputStream in = null;
try {
in = getContentResolver().openInputStream(contentUri);
Bitmap bitmap = BitmapFactory.decodeStream(in);
in.close();
uri = saveBitmap(bitmap);//保存选择的图片到SD卡中
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
return uri;
}
//保存图片到SD中
public Uri saveBitmap(Bitmap bitmap) {
File file = new
File(Environment.getExternalStorageDirectory(), "/saveImg");// 保存的目录
if (!file.exists()) {// 目录是否存在
file.mkdir(); // 如果不存在则创建该目录
}
File imageFile = new File(file.getAbsolutePath(), System.currentTimeMillis() + "img.png");
FileOutputStream os = null;
try {
os = new FileOutputStream(imageFile);
bitmap.compress(CompressFormat.PNG, 85, os);
os.flush();
os.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
return Uri.fromFile(imageFile);
}
这样我们就可以使用从本地图库中选择的图片了。
(3)上传图片到服务器
上传图片到服务器原理就是使用Http连接将图片转成Base64编码的字符串,作为请求参数传到服务器中。在服务器端使用Base64解码字符串,然后写到文件中。
上传图片到服务器的Android客户端代码
public void uploadImg(Bitmap bitmap) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
byte bytes[] = os.toByteArray();
String img = new String(Base64.encodeToString(bytes, Base64.DEFAULT));
String url = "http://192.168.0.102:8080/UploadImgTestServer/MainServlet";
RequestParams params = new RequestParams();
params.add("img", img);
AsyncHttpClient client = new AsyncHttpClient();
client.post(url, params, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "上传成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(int arg0, Header[] arg1, byte[] arg2, Throwable arg3) {
// TODO Auto-generated method stub
}
});
}
服务器端接收上传的图片,这里的服务器端是一个Java Web项目,在
Servlet中的处理就是创建一个文件,将客户端传过来的图片字符串数据使用Base64解码后,写到创建的文件中即可。
服务器端接收图片的代码:
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String img = request.getParameter("img");//获取到客户端传过来的图片字符串数据
System.out.println("img--->" + img);
String rootPath = getServletContext().getRealPath("/");//获取项目的根目录
String dirPath = rootPath +"img";//拼接保存图片的目录
System.out.println("dirPath" + dirPath);
File dirFile = new File(dirPath);
if (!dirFile.exists()){
dirFile.mkdir();
}
File imgFile = new File(dirPath, System.currentTimeMillis() + "img.png");//创建一个PNG图片文件,用于保存接收到的图片
if (!imgFile.exists()) {
imgFile.createNewFile();
}
FileOutputStream os = new FileOutputStream(imgFile);
os.write(Base64.decode(img));//将接收到的图片字符串数据解码后写到创建的PNG图片文件中
os.flush();
os.close();
}
这样就将客户端传过来的图片保存到了服务器项目根目录下的img目录中。