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 ); } ?>
四、删除缓存文件
直接以文件删除方式删除
相关文章推荐
- (4.1.28.4)HTTP协议的报文浅析
- Jmeter使用SSL(HTTPS协议)
- Linux网络编程(2)——采用TCP的基本server的实现
- CloseableHttpClient加载证书来访问https网站
- 打造安全的App!iOS安全系列之 HTTPS
- 网络编程系列之十三 wireshark安装文件冲突
- Android Http传输数据
- 网络流24题 01 飞行员配对方案问题 (多源多汇点+最大流)
- 网站区别手机端和pc端用HttpContext.Current.Request.Url
- TCP/IP的网际层协议——ARP
- LESSON: HTTP 403 Error Caused By Spring Security Role Missing
- http://android.blog.51cto.com/268543/306424
- 读《http 权威指南后》,写的一个只有18K 大小的httpClient
- TCP/IP的网际层协议——ICMP
- python实现的json数据以HTTP GET,POST,PUT,DELETE方式页面请求
- TCP三次握手、四次断开和香农定理
- 为ElasticSearch添加HTTP基本认证(head,bigdesk等插件增加登陆机制)
- 网络编程系列之十二 codeblocks导入makefile工程
- 网络编程系列之十一 radius客户端(802.1x客户端)
- iOS开发 - 检测网络状态(WIFI、2G/3G/4G)