android選擇圖片或拍照圖片上傳到伺服器(包括上傳參數)

來源:互聯網
上載者:User

標籤:伺服器   hashmap   stringbuffer   upload   

在9ria論壇看到的,還沒測試,先Mark與大家分享一下。

最近要搞一個項目,需要上傳相簿和拍照的圖片,不負所望,終於完成了! 不過需要說明一下,其實網上很多教程拍照的圖片,都是縮圖不是很清晰,所以需要在調用照相機的時候,事先產生一個地址,用於標識拍照的圖片URI


具體上傳代碼:1.選擇圖片和上傳介面,包括上傳完成和異常的回調監聽
package com.spring.sky.image.upload;import java.util.HashMap;import java.util.Map;import android.app.Activity;import android.app.ProgressDialog;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;import android.widget.ProgressBar;import android.widget.TextView;import android.widget.Toast;import com.spring.sky.image.upload.network.UploadUtil;import com.spring.sky.image.upload.network.UploadUtil.OnUploadProcessListener;/*** 說明:主要用於選擇檔案和上傳檔案操作*/public class MainActivity extends Activity implements OnClickListener,OnUploadProcessListener{private static final String TAG = "uploadImage";/*** 去上傳檔案*/protected static final int TO_UPLOAD_FILE = 1; /*** 上傳檔案響應*/protected static final int UPLOAD_FILE_DONE = 2; ///*** 選擇檔案*/public static final int TO_SELECT_PHOTO = 3;/*** 上傳初始化*/private static final int UPLOAD_INIT_PROCESS = 4;/*** 上傳中*/private static final int UPLOAD_IN_PROCESS = 5;/**** 這裡的這個URL是我伺服器的javaEE環境URL*/private static String requestURL = "http://192.168.10.160:8080/fileUpload/p/file!upload";private Button selectButton,uploadButton;private ImageView imageView;private TextView uploadImageResult;private ProgressBar progressBar;private String picPath = null;private ProgressDialog progressDialog;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);initView();}/*** 初始化資料*/private void initView() {selectButton = (Button) this.findViewById(R.id.selectImage);uploadButton = (Button) this.findViewById(R.id.uploadImage);selectButton.setOnClickListener(this);uploadButton.setOnClickListener(this);imageView = (ImageView) this.findViewById(R.id.imageView);uploadImageResult = (TextView) findViewById(R.id.uploadImageResult);progressDialog = new ProgressDialog(this);progressBar = (ProgressBar) findViewById(R.id.progressBar1);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.selectImage:Intent intent = new Intent(this,SelectPicActivity.class);startActivityForResult(intent, TO_SELECT_PHOTO);break;case R.id.uploadImage:if(picPath!=null){handler.sendEmptyMessage(TO_UPLOAD_FILE);}else{Toast.makeText(this, "上傳的檔案路徑出錯", Toast.LENGTH_LONG).show();}break;default:break;}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if(resultCode==Activity.RESULT_OK && requestCode == TO_SELECT_PHOTO){picPath = data.getStringExtra(SelectPicActivity.KEY_PHOTO_PATH);Log.i(TAG, "最終選擇的圖片="+picPath);Bitmap bm = BitmapFactory.decodeFile(picPath);imageView.setImageBitmap(bm);}super.onActivityResult(requestCode, resultCode, data);}/*** 上傳伺服器響應回調*/@Overridepublic void onUploadDone(int responseCode, String message) {progressDialog.dismiss();Message msg = Message.obtain();msg.what = UPLOAD_FILE_DONE;msg.arg1 = responseCode;msg.obj = message;handler.sendMessage(msg);}private void toUploadFile(){uploadImageResult.setText("正在上傳中...");progressDialog.setMessage("正在上傳檔案...");progressDialog.show();String fileKey = "pic";UploadUtil uploadUtil = UploadUtil.getInstance();;uploadUtil.setOnUploadProcessListener(this); //設定監聽器監聽上傳狀態Map<String, String> params = new HashMap<String, String>();params.put("orderId", "11111");uploadUtil.uploadFile( picPath,fileKey, requestURL,params);}private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case TO_UPLOAD_FILE:toUploadFile();break;case UPLOAD_INIT_PROCESS:progressBar.setMax(msg.arg1);break;case UPLOAD_IN_PROCESS:progressBar.setProgress(msg.arg1);break;case UPLOAD_FILE_DONE:String result = "響應碼:"+msg.arg1+"\n響應資訊:"+msg.obj+"\n耗時:"+UploadUtil.getRequestTime()+"秒";uploadImageResult.setText(result);break;default:break;}super.handleMessage(msg);}};@Overridepublic void onUploadProcess(int uploadSize) {Message msg = Message.obtain();msg.what = UPLOAD_IN_PROCESS;msg.arg1 = uploadSize;handler.sendMessage(msg );}@Overridepublic void initUpload(int fileSize) {Message msg = Message.obtain();msg.what = UPLOAD_INIT_PROCESS;msg.arg1 = fileSize;handler.sendMessage(msg );}}


2.選擇圖片介面,主要涉及兩種方式:選擇圖片和及時拍照圖片

package com.spring.sky.image.upload;import android.app.Activity;import android.content.ContentValues;import android.content.Intent;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.provider.MediaStore;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.LinearLayout;import android.widget.Toast;/*** @author spring sky<br>* 說明:主要用於選擇檔案操作*/public class SelectPicActivity extends Activity implements OnClickListener{/**** 使用照相機拍照擷取圖片*/public static final int SELECT_PIC_BY_TACK_PHOTO = 1;/**** 使用相簿中的圖片*/public static final int SELECT_PIC_BY_PICK_PHOTO = 2;/**** 從Intent擷取圖片路徑的KEY*/public static final String KEY_PHOTO_PATH = "photo_path";private static final String TAG = "SelectPicActivity";private LinearLayout dialogLayout;private Button takePhotoBtn,pickPhotoBtn,cancelBtn;/**擷取到的圖片路徑*/private String picPath;private Intent lastIntent ;private Uri photoUri;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.select_pic_layout);initView();}/*** 初始化載入View*/private void initView() {dialogLayout = (LinearLayout) findViewById(R.id.dialog_layout);dialogLayout.setOnClickListener(this);takePhotoBtn = (Button) findViewById(R.id.btn_take_photo);takePhotoBtn.setOnClickListener(this);pickPhotoBtn = (Button) findViewById(R.id.btn_pick_photo);pickPhotoBtn.setOnClickListener(this);cancelBtn = (Button) findViewById(R.id.btn_cancel);cancelBtn.setOnClickListener(this);lastIntent = getIntent();}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.dialog_layout:finish();break;case R.id.btn_take_photo:takePhoto();break;case R.id.btn_pick_photo:pickPhoto();break;default:finish();break;}}/*** 拍照擷取圖片*/private void takePhoto() {//執行拍照前,應該先判斷SD卡是否存在String SDState = Environment.getExternalStorageState();if(SDState.equals(Environment.MEDIA_MOUNTED)){Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//"android.media.action.IMAGE_CAPTURE"/**** 需要說明一下,以下操作使用照相機拍照,拍照後的圖片會存放在相簿中的* 這裡使用的這種方式有一個好處就是擷取的圖片是拍照後的原圖* 如果不實用ContentValues存放照片路徑的話,拍照後擷取的圖片為縮圖不清晰*/ContentValues values = new ContentValues(); photoUri = this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, photoUri);/**-----------------*/startActivityForResult(intent, SELECT_PIC_BY_TACK_PHOTO);}else{Toast.makeText(this,"記憶卡不存在", Toast.LENGTH_LONG).show();}}/**** 從相簿中取圖片*/private void pickPhoto() {Intent intent = new Intent();intent.setType("image/*");intent.setAction(Intent.ACTION_GET_CONTENT);startActivityForResult(intent, SELECT_PIC_BY_PICK_PHOTO);}@Overridepublic boolean onTouchEvent(MotionEvent event) {finish();return super.onTouchEvent(event);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if(resultCode == Activity.RESULT_OK){doPhoto(requestCode,data);}super.onActivityResult(requestCode, resultCode, data);}/*** 選擇圖片後,擷取圖片的路徑* @param requestCode* @param data*/private void doPhoto(int requestCode,Intent data){if(requestCode == SELECT_PIC_BY_PICK_PHOTO ) //從相簿取圖片,有些手機有異常情況,請注意{if(data == null){Toast.makeText(this, "選擇圖片檔案出錯", Toast.LENGTH_LONG).show();return;}photoUri = data.getData();if(photoUri == null ){Toast.makeText(this, "選擇圖片檔案出錯", Toast.LENGTH_LONG).show();return;}}String[] pojo = {MediaStore.Images.Media.DATA};Cursor cursor = managedQuery(photoUri, pojo, null, null,null); if(cursor != null ){int columnIndex = cursor.getColumnIndexOrThrow(pojo[0]);cursor.moveToFirst();picPath = cursor.getString(columnIndex);cursor.close();}Log.i(TAG, "imagePath = "+picPath);if(picPath != null && ( picPath.endsWith(".png") || picPath.endsWith(".PNG") ||picPath.endsWith(".jpg") ||picPath.endsWith(".JPG") )){lastIntent.putExtra(KEY_PHOTO_PATH, picPath);setResult(Activity.RESULT_OK, lastIntent);finish();}else{Toast.makeText(this, "選擇圖片檔案不正確", Toast.LENGTH_LONG).show();}}}

3. 上傳工具類,主要實現了圖片的上傳,上傳過程的初始化監聽和上傳完成的監聽,還有上傳耗時的計算

package com.spring.sky.image.upload.network;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.Iterator;import java.util.Map;import java.util.UUID;import android.util.Log;/*** * 上傳工具類* 支援上傳檔案和參數*/public class UploadUtil {private static UploadUtil uploadUtil;private static final String BOUNDARY = UUID.randomUUID().toString(); // 邊界標識 隨機產生private static final String PREFIX = "--";private static final String LINE_END = "\r\n";private static final String CONTENT_TYPE = "multipart/form-data"; // 內容類型private UploadUtil() {}/*** 單例模式擷取上傳工具類* @return*/public static UploadUtil getInstance() {if (null == uploadUtil) {uploadUtil = new UploadUtil();}return uploadUtil;}private static final String TAG = "UploadUtil";private int readTimeOut = 10 * 1000; // 讀取逾時private int connectTimeout = 10 * 1000; // 逾時時間/**** 請求使用多長時間*/private static int requestTime = 0;private static final String CHARSET = "utf-8"; // 設定編碼/**** 上傳成功*/public static final int UPLOAD_SUCCESS_CODE = 1;/*** 檔案不存在*/public static final int UPLOAD_FILE_NOT_EXISTS_CODE = 2;/*** 伺服器出錯*/public static final int UPLOAD_SERVER_ERROR_CODE = 3;protected static final int WHAT_TO_UPLOAD = 1;protected static final int WHAT_UPLOAD_DONE = 2;/*** android上傳檔案到伺服器* * @param filePath* 需要上傳的檔案的路徑* @param fileKey* 在網頁上<input type=file name=xxx/> xxx就是這裡的fileKey* @param RequestURL* 請求的URL*/public void uploadFile(String filePath, String fileKey, String RequestURL,Map<String, String> param) {if (filePath == null) {sendMessage(UPLOAD_FILE_NOT_EXISTS_CODE,"檔案不存在");return;}try {File file = new File(filePath);uploadFile(file, fileKey, RequestURL, param);} catch (Exception e) {sendMessage(UPLOAD_FILE_NOT_EXISTS_CODE,"檔案不存在");e.printStackTrace();return;}}/*** android上傳檔案到伺服器* * @param file* 需要上傳的檔案* @param fileKey* 在網頁上<input type=file name=xxx/> xxx就是這裡的fileKey* @param RequestURL* 請求的URL*/public void uploadFile(final File file, final String fileKey,final String RequestURL, final Map<String, String> param) {if (file == null || (!file.exists())) {sendMessage(UPLOAD_FILE_NOT_EXISTS_CODE,"檔案不存在");return;}Log.i(TAG, "請求的URL=" + RequestURL);Log.i(TAG, "請求的fileName=" + file.getName());Log.i(TAG, "請求的fileKey=" + fileKey);new Thread(new Runnable() { //開啟線程上傳檔案@Overridepublic void run() {toUploadFile(file, fileKey, RequestURL, param);}}).start();}private void toUploadFile(File file, String fileKey, String RequestURL,Map<String, String> param) {String result = null;requestTime= 0;long requestTime = System.currentTimeMillis();long responseTime = 0;try {URL url = new URL(RequestURL);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setReadTimeout(readTimeOut);conn.setConnectTimeout(connectTimeout);conn.setDoInput(true); // 允許輸入資料流conn.setDoOutput(true); // 允許輸出資料流conn.setUseCaches(false); // 不允許使用緩衝conn.setRequestMethod("POST"); // 請求方式conn.setRequestProperty("Charset", CHARSET); // 設定編碼conn.setRequestProperty("connection", "keep-alive");conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);// conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");/*** 當檔案不為空白,把檔案封裝並且上傳*/DataOutputStream dos = new DataOutputStream(conn.getOutputStream());StringBuffer sb = null;String params = "";/**** 以下是用於上傳參數*/if (param != null && param.size() > 0) {Iterator<String> it = param.keySet().iterator();while (it.hasNext()) {sb = null;sb = new StringBuffer();String key = it.next();String value = param.get(key);sb.append(PREFIX).append(BOUNDARY).append(LINE_END);sb.append("Content-Disposition: form-data; name=\"").append(key).append("\"").append(LINE_END).append(LINE_END);sb.append(value).append(LINE_END);params = sb.toString();Log.i(TAG, key+"="+params+"##");dos.write(params.getBytes());// dos.flush();}}sb = null;params = null;sb = new StringBuffer();/*** 這裡重點注意: name裡面的值為伺服器端需要key 只有這個key 才可以得到對應的檔案* filename是檔案的名字,包含尾碼名的 比如:abc.png*/sb.append(PREFIX).append(BOUNDARY).append(LINE_END);sb.append("Content-Disposition:form-data; name=\"" + fileKey+ "\"; filename=\"" + file.getName() + "\"" + LINE_END);sb.append("Content-Type:image/pjpeg" + LINE_END); // 這裡配置的Content-type很重要的 ,用於伺服器端辨別檔案的類型的sb.append(LINE_END);params = sb.toString();sb = null;Log.i(TAG, file.getName()+"=" + params+"##");dos.write(params.getBytes());/**上傳檔案*/InputStream is = new FileInputStream(file);onUploadProcessListener.initUpload((int)file.length());byte[] bytes = new byte[1024];int len = 0;int curLen = 0;while ((len = is.read(bytes)) != -1) {curLen += len;dos.write(bytes, 0, len);onUploadProcessListener.onUploadProcess(curLen);}is.close();dos.write(LINE_END.getBytes());byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();dos.write(end_data);dos.flush();// // dos.write(tempOutputStream.toByteArray());/*** 擷取響應碼 200=成功 當響應成功,擷取響應的流*/int res = conn.getResponseCode();responseTime = System.currentTimeMillis();this.requestTime = (int) ((responseTime-requestTime)/1000);Log.e(TAG, "response code:" + res);if (res == 200) {Log.e(TAG, "request success");InputStream input = conn.getInputStream();StringBuffer sb1 = new StringBuffer();int ss;while ((ss = input.read()) != -1) {sb1.append((char) ss);}result = sb1.toString();Log.e(TAG, "result : " + result);sendMessage(UPLOAD_SUCCESS_CODE, "上傳結果:"+ result);return;} else {Log.e(TAG, "request error");sendMessage(UPLOAD_SERVER_ERROR_CODE,"上傳失敗:code=" + res);return;}} catch (MalformedURLException e) {sendMessage(UPLOAD_SERVER_ERROR_CODE,"上傳失敗:error=" + e.getMessage());e.printStackTrace();return;} catch (IOException e) {sendMessage(UPLOAD_SERVER_ERROR_CODE,"上傳失敗:error=" + e.getMessage());e.printStackTrace();return;}}/*** 發送上傳結果* @param responseCode* @param responseMessage*/private void sendMessage(int responseCode,String responseMessage){onUploadProcessListener.onUploadDone(responseCode, responseMessage);}/*** 下面是一個自訂的回呼函數,用到回調上傳檔案是否完成* * @author shimingzheng* */public static interface OnUploadProcessListener {/*** 上傳響應* @param responseCode* @param message*/void onUploadDone(int responseCode, String message);/*** 上傳中* @param uploadSize*/void onUploadProcess(int uploadSize);/*** 準備上傳* @param fileSize*/void initUpload(int fileSize);}private OnUploadProcessListener onUploadProcessListener;public void setOnUploadProcessListener(OnUploadProcessListener onUploadProcessListener) {this.onUploadProcessListener = onUploadProcessListener;}public int getReadTimeOut() {return readTimeOut;}public void setReadTimeOut(int readTimeOut) {this.readTimeOut = readTimeOut;}public int getConnectTimeout() {return connectTimeout;}public void setConnectTimeout(int connectTimeout) {this.connectTimeout = connectTimeout;}/*** 擷取上傳使用的時間* @return*/public static int getRequestTime() {return requestTime;}public static interface uploadProcessListener{}}


android選擇圖片或拍照圖片上傳到伺服器(包括上傳參數)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.