1. 程式人生 > >android 圖片上傳,使用 httpclient 的MultipartEntity 上傳

android 圖片上傳,使用 httpclient 的MultipartEntity 上傳

該上傳案例使用springmvc 為後臺使用httpclient 方法傳遞檔案比檔案流和base64方法上傳檔案更方便簡介。

該案例首先獲取圖片並將圖片寫入應用的SD卡資料夾。然後再上傳給伺服器

關於在SD卡中建立應用資料夾請參照

http://blog.csdn.net/u012373815/article/details/47614715

準備工作匯入JAR包

Android 端需要匯入

apache-mime4j-0.6.jar

httpmime-4.2.jar

Springmvc 需要匯入

commons-fileupload-1.2.2.jar

commons-io-2.4.jar

所需jar包我以上傳到我的資源頁

http://download.csdn.net/detail/u012373815/9001465

Android 端需要新增訪問網路許可權和SD卡讀寫許可權。

<!-- 網路許可權 -->

<uses-permission android:name="android.permission.INTERNET"/>

   <!--sd卡許可權 -->

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

 <uses-permission android:name

="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>        

1.  上傳圖片首先需要獲取圖片

OnClickListenerzhuceimg 為某一個控制元件的點選方法,點選選取圖片

  // 提取圖片

public classOnClickListenerzhuceimg implements OnClickListener {

     @Override

     public void onClick(View v) {

       ShowPickDialog();

     }

  }

  /*

   * 提示對話方塊

   */

  private void ShowPickDialog() {

     new AlertDialog.Builder(this)

         .setTitle("設定頭像")

         .setNegativeButton("相簿",

 new DialogInterface.OnClickListener() {

  public void onClick(DialogInterfacedialog, intwhich) {

dialog.dismiss();// 對話方塊消失

if (SdCardUtil.checkSdCard() == true) {

Intent intent = new Intent(Intent.ACTION_PICK);

       intent.setType("image/*");// 相片型別

       startActivityForResult(intent,1); // 跳到onActivityResult case1

} else {

  Toast.makeText(Userzhuce.this, "SD卡不存在",  Toast.LENGTH_LONG).show();}

            }

         })

         .setPositiveButton("拍照", newDialogInterface.OnClickListener() {

  public void onClick(DialogInterfacedialog, intwhichButton) {

              dialog.dismiss();

              // 呼叫拍照

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

// 下面這句指定呼叫相機拍照後的照片儲存的路徑檔名用電話代替          intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri

     .fromFile(new File(Environment

.getExternalStorageDirectory(),userphone + ".jpg")));

  startActivityForResult(intent,2); // 跳到onActivityResult case2

            }

         }).show();

  }

  @Override

protected voidonActivityResult(intrequestCode, intresultCode, Intent data) {

     switch (requestCode) {

     // 如果是直接從相簿獲取

     case 1:

       startPhotoZoom(data.getData());

       break;

     // 如果是呼叫相機拍照時

     case 2:

       Filetemp = newFile(Environment.getExternalStorageDirectory()

            +"/"+ userphone+ ".jpg");

       startPhotoZoom(Uri.fromFile(temp));

       break;

     // 取得裁剪後的圖片

     case 3:

       /*

        * 非空判斷大家一定要驗證,如果不驗證的話, * 在剪裁之後如果發現不滿意,要重新裁剪,丟棄

        * 當前功能時,會報NullException

        */

       if (data != null) {

         setPicToView(data); //儲存圖片到SD        } else{

Toast.makeText(this, "沒拿到資料", 1).show();

       }break;

     default:break;

     }

super.onActivityResult(requestCode, resultCode, data);

  }

  // 裁剪圖片方法實現

  public void startPhotoZoom(Uri uri){

     Intentintent = newIntent("com.android.camera.action.CROP");

     intent.setDataAndType(uri,"image/*");

// 下面這個crop=true是設定在開啟的Intent中設定顯示的VIEW可裁剪

     intent.putExtra("crop", "true");

     // aspectX aspectY 是寬高的比例

     intent.putExtra("aspectX",1);

     intent.putExtra("aspectY",1);

     // outputX outputY 是裁剪圖片寬高

     intent.putExtra("outputX",500);

     intent.putExtra("outputY",500);

     intent.putExtra("return-data",true);

     startActivityForResult(intent,3); // 跳到onActivityResult case3

  }

  /*

   * 儲存裁剪之後的圖片資料 *

   */

  private void setPicToView(Intentpicdata) {

     Bundleextras = picdata.getExtras();

     Bitmapphoto = null;

     if (extras != null) {

     photo= (Bitmap) extras.get("data");

Drawable drawable = new BitmapDrawable(photo);

// 轉換為drawable 用於顯示

       zhuceimg.setImageDrawable(drawable);

     }

     if (photo != null) {

       saveImgTosdFile(photo);

     }

  }

  // 將圖片寫到sd

  public void saveImgTosdFile(Bitmapbitmap) {

     FileOutputStreamfos = null;

     Stringfilename = SdCardUtil.getSdPath() + SdCardUtil.FILEDIR + "/"

         +SdCardUtil.FILEPHOTO+ "/"+ System.currentTimeMillis();

     if (!filename.isEmpty()) {

       imageurl = filename;

     }

     try {

       fos= newFileOutputStream(filename);

       //將圖片寫道SD卡中以filename為名字bitmap.compress(Bitmap.CompressFormat.PNG,

60, fos);

     }catch(FileNotFoundException e) {

       // TODO Auto-generated catch block

       e.printStackTrace();

     }finally{

       try {

            fos.flush();        

       }catch(IOException e) {

         // TODO Auto-generated catch block

         e.printStackTrace();

       }

     }

  }

  // end 圖片

  // 上傳和返回結果處理

final Handler handlerzhuce= newHandler() {

     public void handleMessage(Messagemsg) { 

       Stringstr = (String) msg.obj;

       if (!str.equals("no")) {

Toast.makeText(Userzhuce.this, "完善資訊成功!", Toast.LENGTH_SHORT).show();

startActivity(new Intent(Userzhuce.this, Wo.class));

       }else{

Toast.makeText(Userzhuce.this, "資訊完善失敗!!", Toast.LENGTH_SHORT)

              .show();

       }

     }

  };

  // 點選更新

public classOnClickListenerzhuce implements OnClickListener {

       @Override

     public void onClick(View v) {

       // TODO Auto-generated method stub

       if (zhucenc.getText().toString().equals("")) {

         Toast.makeText(Userzhuce.this, "暱稱不能為空!!!", Toast.LENGTH_SHORT)

              .show();

       }else{

     //imageurl為圖片在手機上儲存的位置

     Filefile = newFile(imageurl);

newThread(updateUser.updateuser(

HttpPath.USERUPDATE_PATH,userphone,

zhucenc.getText().toString(),

zhuceaddress.getText().toString(),

handlerzhuce, file)).start();

       }

     }

  }

2.  上傳圖片的httpclient 工具類

 import java.io.File;

import java.io.IOException;

import java.io.UnsupportedEncodingException;

import java.nio.charset.Charset;

import org.apache.http.HttpResponse;

import org.apache.http.client.ClientProtocolException;

import org.apache.http.client.HttpClient;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.impl.client.DefaultHttpClient;

import org.apache.http.util.EntityUtils;

import org.apache.http.entity.mime.MultipartEntity;

import org.apache.http.entity.mime.content.FileBody;

import org.apache.http.entity.mime.content.StringBody;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

public classupdateUser {

public staticRunnable  updateuser (final String path, final String userphone,  final String username,

final String address,  final Handler handler,

final File imgfile  ){

      Runnablerun=newRunnable() {

        Stringresult=null;

        @Override

        public void run() {

           // TODO Auto-generated method stub

   HttpClienthttpClient=newDefaultHttpClient();

           HttpPosthttpPost=newHttpPost(path);

           FileBodyfile=newFileBody(imgfile);

           MultipartEntity emEntity=new MultipartEntity();

        try {//封裝所需資料,包括檔案和所需的Strig 資料

              emEntity.addPart("file",file);

              emEntity.addPart("userphone",newStringBody(userphone,Charset.forName("utf-8")));

              emEntity.addPart("username",newStringBody(username,Charset.forName("utf-8")));

              emEntity.addPart("address",newStringBody(address,Charset.forName("utf-8")));

              httpPost.setEntity(emEntity);

              Log.i("TAG", "post總位元組數:"+emEntity.getContentLength());

              HttpResponsehttpResponse=httpClient.execute(httpPost);

              intcode=httpResponse.getStatusLine().getStatusCode();

              if(code==200)

              {

                 System.out.println("連結成功");   result=EntityUtils.toString(httpResponse.getEntity());                                              

              }

              Messagemessage=handler.obtainMessage();

              message.obj=result;

              handler.sendMessage(message);

           }catch(UnsupportedEncodingException e) {

              // TODO Auto-generated catch block

              e.printStackTrace();

           }catch(ClientProtocolException e) {

              // TODO Auto-generated catch block

              e.printStackTrace();

           }catch(IOException e) {

              // TODO Auto-generated catch block

              e.printStackTrace();

           }                    

        }

      };

      return run;

   }

3.  伺服器端controller 程式碼書寫

關於service 的程式碼書寫就不在這裡寫了

//@RequestParam("file")為檔案上傳的標識 “file“

 @RequestMapping("/upUser")

   @ResponseBody

   public StringupUser(HttpServletRequest httpRequest, @RequestParam("file") MultipartFile file) throws Exception {

      System.out.println("sdfsdfsdf");

      Stringuserphone = httpRequest.getParameter("userphone");

      Stringusername = httpRequest.getParameter("username");

      Stringaddress = httpRequest.getParameter("address");

      System.out.println(userphone+username+"______");

      // 接收圖片

      //圖片儲存路徑

      Stringimagepath = httpRequest.getSession().getServletContext()

           .getRealPath("/")

           +"images"+ "/"+ userphone + ".jpg";

        Filef = newFile(imagepath);

        file.transferTo(f);

      //圖片名稱

String  userimg="/backtow/images"

+"/"+userphone+".jpg";

      Usersuser=newUsers();

      user.setUserphone(userphone);

      user.setUsername(username);

      user.setAddress(address);

      user.setUserimg(userimg);

      Stringresult=userservice.upUser(user);

      return result;

   }