Android AsyncHttpClient图片上传

本文,主要是解决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 temp = new ArrayList();
            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后台参考代码

  
$base_path = "./upload/";
$target_path = $base_path . basename ( $_FILES ['uploadfile'] ['name'] );  
if (move_uploaded_file ( $_FILES ['uploadfile'] ['tmp_name'], $target_path )) {  
    $array = array (  
            "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 );  
}  
?>  

四、删除缓存文件
直接以文件删除方式删除

你可能感兴趣的:(android开发)