您的位置:首页 > 理论基础 > 计算机网络

Android AsyncHttpClient图片上传

2015-08-10 12:50 501 查看

本文,主要是解决app在与后台通信时,如何保证字段信息与图片同步上传。

网上许多图片上传的实现,但笔者在开发中发现,这些并不是一个具体的流程。因此,写此文章总结下图片的上传流程。

图片上传流程,对于大部分app来说,是最长见的操作,拥有一个具体的流程,在开发中会带来许多方便。

流程具体如下:

1、选择图片(拍摄、从图片库选择)

2、压缩与本地缓存,图片需要压缩,很容易理解,为防止OOM。而缓存是保存压缩后的图片,以便上传到后台。

2、界面呈现选择的图片。

3、调用后台接口,上传图片。

4、取消上传后或者上传成功后,删除缓存。

解释:

图片呈现时,最好是先压缩再呈现。压缩方法网上很多,但笔者对于压缩方法,暂未找到一个可控制压缩后图片大小的方法,网上大部分方法为压缩后图片大小不可控。

图片压缩了,为什么还需要做缓存,原因:

图片上传有许多种方法,如字节流,Base64等。

在Android中,app与后台通信时,都有封装好的通信方法。相信许多开发者也会选择如AsyncHttpClient这样的类库,实现起来简单易用。另外,一般图片上传时,不会简单的只上传图片,图片可能是附加的信息。这时,采用字节流,Base64等方法时,会出现两个问题,一个是怎么把字段信息和图片一起上传,二是若分开上传,怎么保证字段信息和图片同步。

其实,AsyncHttpClient已经有关于这些问题的解决方法,AsyncHttpClient里,已经可以实现了上传file,利用这个就很好的解决了上述问题。

AsyncHttpClient上传图片,是以file的形式上传的,而在android中,压缩后的图片是Bitmap形式,所以需要反压缩后的图片保存起来,以File的形式再上传。

如以下代码:

String title = "title";
File file = new File(path);
RequestParams requestParams = new RequestParams();
requestParams.put("title", title);
requestParams.put("file" , file);


言归正传,以下是各个流程的具体实现。

一、选择图片

1、界面跳转选择图片

//跳转拍摄照片
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);                        startActivityForResult(intent,101);


//跳转从照片库选择
Intent intent2 = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent2,102);


2、返回结果处理

saveImageCahce(bitmap); 该方法为缓存方法,下面会写到。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 101) {
switch (resultCode) {
case Activity.RESULT_OK:
Bundle bundle = data.getExtras();
Bitmap bitmap = (Bitmap) bundle.get("data");
//缓存
saveImageCahce(bitmap);
break;
case Activity.RESULT_CANCELED:
break;
}
} else if (requestCode == 102) {
switch (resultCode) {
case Activity.RESULT_OK:
Uri uri = data.getData();
Cursor cursor = getContentResolver().query(uri, null, null,null, null);
cursor.moveToNext();
String imgPath = cursor.getString(1);
cursor.close();
Bitmap bitmap = BitmapFactory.decodeFile(imgPath);
//缓存
saveImageCahce(bitmap);
break;
case Activity.RESULT_CANCELED:
break;
}
}
}


关于多图上传

在多图上传时,与单图上传类似,只是把单图上加上个循环步骤。

不同点是,选择图片时。不能调用Android自带的图片选择器,而需要另做图片选择。关于多图选择,网上很多,请自行搜索。

这里只需要把,多图选择后的结果的图片地址,以list形式,返回就行。

注意,返回的图片地址一定要是该图片的绝对路径。

代码如下:

@Override
protected void onActivityResult(int arg0, int arg1, Intent arg2) {
// TODO Auto-generated method stub
super.onActivityResult(arg0, arg1, arg2);
if (arg1 == 1001) {
// 获取返回结果中图片地址数据
Bundle bundle = arg2.getExtras();
List<String> temp = new ArrayList<String>();
temp = bundle.getStringArrayList("files");
//循环
for (int i = 0; i < temp.size(); i++) {
String file_path = temp.get(i);
//生成图片缓存地址
file_path =
//获取缓存文件夹地址
//获取文件名信息
FileManager.getSaveImagePath()
+ file_path.substring(file_path.lastIndexOf("/") + 1,
file_path.length());
//生成文件夹
FileHelper.createDirectory(FileManager.getSaveImagePath());
//压缩与保存图片
File file = new File(file_path);
try {
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream out = new FileOutputStream(file);
Util util = new Util(ReleaseRentalActivity.this);
Bitmap bitmap = util.getBitmapCompression(temp.get(i));
if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)) {
out.flush();
out.close();
}
mImgFiles.add(file_path);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
refreshImages();
}
}


二、压缩与本地缓存

private void saveImageCahce(Bitmap avatar) {
CacheUtils cu = new CacheUtils();
String image_path = cu.getAvatarCache(UserInfoActivity.this, avatar);
//呈现
Bitmap bitmap = BitmapFactory.decodeFile(image_path);
mUserAvatar.setImageBitmap(bitmap);
}


生成头像缓存

/**
* 生成头像缓存
*
* @param con
* @param avatar
* @return
*/
public String getAvatarCache(Context con, Bitmap avatar) {
//图片保存绝对路径
String file_path = FileManager.getSaveImagePath() + AVATAR_PATH;
//图片保存的文件夹
FileHelper.createDirectory(FileManager.getSaveImagePath());
File file = new File(file_path);
try {
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream out = new FileOutputStream(file);
ImageFactory imageFactory = new ImageFactory(con);
//压缩图片并保存
Bitmap bitmap = imageFactory.comp(avatar);
if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)) {
out.flush();
out.close();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//返回该图片缓存路径
return file_path;
}


三、上传图片

以RequestParams参数,进行AsyncHttpClient访问

String title = "title";
File file = new File(path);
RequestParams requestParams = new RequestParams();
requestParams.put("title", title);
requestParams.put("file" , file);


php后台参考代码

<?php
$base_path = "./upload/";
$target_path = $base_path . basename ( $_FILES ['uploadfile'] ['name'] );
if (move_uploaded_file ( $_FILES ['uploadfile'] ['tmp_name'], $target_path )) {
$array = arra
96ab
y (
"code" => "1",
"message" => $_FILES ['uploadfile'] ['name']
);
echo json_encode ( $array );
} else {
$array = array (
"code" => "0",
"message" => "There was an error uploading the file, please try again!" . $_FILES ['uploadfile'] ['error']
);
echo json_encode ( $array );
}
?>


四、删除缓存文件

直接以文件删除方式删除
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  安卓图片上传