Android本地圖片上傳(拍照+相簿)

LG_227發表於2018-04-04
本文demo下載:wisdomdd.cn
本例項主要功能包含: android 選擇照片/拍照 上傳圖片到伺服器 原始碼, 圖片上傳過程中顯示上傳進度條, 包含伺服器端接收檔案處理的程式碼, 後臺語言為C#, 例項下載可以直接執行

執行效果圖:

blob.png   blob.png  blob.png


Android端程式碼

MainActivity:

public class MainActivity extends Activity implements OnClickListener,
      OnUploadProcessListener {
   private static final String TAG = "uploadImage";
   private File file = null;
   /**
    * 去上傳檔案
    */
   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;
   /**
    * 上傳完畢
    */
   private static final int UPLOAD_END_PROCESS = 6;
 
   /***
    * 這裡的這個URL是我伺服器的javaEE環境URL
    */
   private static String requestURL = WelcomeActivity.ServerUrl
         + "ajax/admin/ProPicUpload.ashx";
    
 
   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. */
   @Override
   public 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);
   }
 
   @Override
   public 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) {
            uploadImageResult.setText("正在上傳中...");
            //progressDialog.setMessage("正在上傳檔案...");
            //progressDialog.show();
            handler.sendEmptyMessage(TO_UPLOAD_FILE);
          
         } else {
            Toast.makeText(this, "上傳的檔案路徑出錯", Toast.LENGTH_LONG).show();
         }
         break;
      default:
         break;
      }
   }
 
   @Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 
      if (resultCode == Activity.RESULT_OK) // TO_SELECT_PHOTO)
      {
         picPath = data.getStringExtra(SelectPicActivity.KEY_PHOTO_PATH);
         Log.i(TAG, "最終選擇的圖片1=" + picPath);
         Bitmap bm = BitmapFactory.decodeFile(picPath);
         imageView.setImageBitmap(bm);
         // ContentResolver resolver = getContentResolver();
         // Bitmap bm = MediaStore.Images.Media.getBitmap(resolver,
         // data.getData());
      }
      super.onActivityResult(requestCode, resultCode, data);
   }
 
   /**
    * 上傳伺服器響應回撥
    */
   @Override
   public 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 class UpdateImageThread extends Thread {
      @Override
      public void run() {
         toUploadFile();
      }
   };
 
   private void toUploadFile() {
      if (picPath != null) {
         String fileKey = "Filedata";
         UploadUtil uploadUtil = UploadUtil.getInstance();
         uploadUtil.setOnUploadProcessListener(this); // 設定監聽器監聽上傳狀態
         Map<String, String> params = new HashMap<String, String>();
         params.put("type", "android");
         //uploadUtil.uploadFile(picPath, fileKey, requestURL, params);
         //uploadUtil.uploadFile(file, fileKey, requestURL, params);
         try {
            @SuppressWarnings("static-access")
            String s = uploadUtil.uploadSubmit(requestURL, params,
                  new File(picPath), fileKey);
            Log.e("s=", s);
            //progressDialog.hide();
             
            Message msg = Message.obtain();
            msg.what = UPLOAD_END_PROCESS;
            msg.obj=s;
            handler.sendMessage(msg);
            //UPLOAD_END_PROCESS
         } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            //uploadImageResult.setText("上傳失敗");
         }
      }
   }
 
   @SuppressLint("HandlerLeak")
   private Handler handler = new Handler() {
      @Override
      public void handleMessage(Message msg) {
         switch (msg.what) {
         case TO_UPLOAD_FILE:
            // toUploadFile();
            new UpdateImageThread().start();
            break;
         case UPLOAD_INIT_PROCESS:
            progressBar.setMax(msg.arg1);
            break;
         case UPLOAD_IN_PROCESS:
            Log.e("setProgress", msg.arg1 + "%");
 
            progressBar.setProgress(msg.arg1);
            uploadImageResult.setText(msg.arg1 + "%");
            break;
         case UPLOAD_FILE_DONE:
            String result = "響應碼:" + msg.arg1 + "\n響應資訊:" + msg.obj
                  + "\n耗時:" + UploadUtil.getRequestTime() + "秒";
            uploadImageResult.setText(result);
            break;
         case UPLOAD_END_PROCESS:
            uploadImageResult.setText("上傳成功");
            String imageUrl = msg.obj.toString();
            Intent lastIntent = getIntent();
            lastIntent.putExtra("url", imageUrl);
            setResult(Activity.RESULT_OK, lastIntent);
            finish();
            break;
         default:
            break;
         }
         super.handleMessage(msg);
      }
 
   };
 
   @Override
   public void onUploadProcess(int uploadSize) {
      Message msg = Message.obtain();
      msg.what = UPLOAD_IN_PROCESS;
      msg.arg1 = uploadSize;
      handler.sendMessage(msg);
   }
 
   @Override
   public void initUpload(int fileSize) {
      Message msg = Message.obtain();
      msg.what = UPLOAD_INIT_PROCESS;
      msg.arg1 = fileSize;
      handler.sendMessage(msg);
   }
 
}

/**
 * 
 * 上傳工具類
 * 
 * @author spring sky<br>
 *         Email :vipa1888@163.com<br>
 *         QQ: 840950105<br>
 *         支援上傳檔案和引數
 */
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() { // 開啟執行緒上傳檔案
               @Override
               public 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 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 static 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 {
 
   }
 
   private static long totalSize = 0;
 
   /**
    * 提交引數裡有檔案的資料
    * 
    * @param url
    *            伺服器地址
    * @param param
    *            引數
    * @return 伺服器返回結果
    * @throws Exception
    */
   public String uploadSubmit(String url, Map<String, String> param,
         File file, String fileKey) throws Exception {
      HttpPost post = new HttpPost(url);
 
      // MultipartEntity entity = new MultipartEntity();
 
      CustomMultipartEntity entity = new CustomMultipartEntity(
            new ProgressListener() {
               @Override
               public void transferred(long num) {
                  onUploadProcessListener
                        .onUploadProcess((int) ((num / (float)totalSize) * 100));
               }
            });
 
      if (param != null && !param.isEmpty()) {
         for (Map.Entry<String, String> entry : param.entrySet()) {
            if (entry.getValue() != null
                  && entry.getValue().trim().length() > 0) {
               entity.addPart(entry.getKey(),
                     new StringBody(entry.getValue()));
            }
         }
      }
      // 新增檔案引數
      if (file != null && file.exists()) {
         entity.addPart(fileKey, new FileBody(file));
      }
      totalSize = entity.getContentLength();
 
      post.setEntity(entity);
      HttpClient httpClient = new DefaultHttpClient();
      HttpResponse response = httpClient.execute(post);
      int stateCode = response.getStatusLine().getStatusCode();
      StringBuffer sb = new StringBuffer();
      if (stateCode == HttpStatus.SC_OK) {
         HttpEntity result = response.getEntity();
         if (result != null) {
            InputStream is = result.getContent();
            BufferedReader br = new BufferedReader(
                  new InputStreamReader(is));
            String tempLine;
            while ((tempLine = br.readLine()) != null) {
               sb.append(tempLine);
            }
         }
      }
      post.abort();
      return sb.toString();
   }
 
}
C#程式碼:
public class ProPicUpload : IHttpHandler
 {
  
     public void ProcessRequest(HttpContext context)
     {
         context.Response.ContentType = "text/plain";
         context.Response.Charset = "utf-8";
         HttpPostedFile file = context.Request.Files["Filedata"];
         if (context.Request["type"] == "android")
         {
             if (file != null)
             {
                 //上傳圖片方法就不貼了
                 //通過file就可以儲存到伺服器
                 context.Response.Write("/upload/"   ","   "檔名.jpg");
             }
         }
          
     }
  
     public bool IsReusable
     {
         get
         {
             return false;
         }
     }
 }



相關文章