1. 程式人生 > >Android圖片上傳(頭像裁切+原圖原樣)

Android圖片上傳(頭像裁切+原圖原樣)

還是那句話,最近專案比較忙哭拖了很久這篇文章終於完成了!

先看一下效果圖:

(一)頭像裁切、上傳伺服器(效果圖)

一般都是有圓形顯示頭像的,這裡我自定義了一個ImageView,頁面很乾淨但是看著很上檔次吧!

點選頭像從底部彈出一個對話方塊,提示使用者頭像來自相機或者相簿,這都是常規流程。

上傳完成後預設的“程式設計師頭像”換成了萌妹子

(二)普通圖片上傳伺服器(效果圖)

模仿QQ空間發動態的佈局隨意捏造一個介面出來

點選新增圖片從底部彈出一個對話方塊,提示使用者圖片來自相機或者相簿,這也都是常規流程。

上傳過程中,有可能圖片很大,顯示一個進度圈(其實頭像上傳也有,只是檔案小,還沒顯示就上傳完成了大笑


上傳完成後把剛才的照片亮出來顯示到按鈕的地方,當然大家根據需要還可以自己擴充套件(比如長按抖動出現刪除、繼續新增N張等等)


下面簡單鋪一下程式碼:

(一)頭像裁切、上傳伺服器(程式碼)


這裡上邊的按鈕是頭像的點選事件,彈出底部的頭像選擇框,下邊的按鈕跳到下個頁面,進行原圖上傳。

[java] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. @Override
  2. publicvoid onClick(View v) {  
  3.     switch (v.getId()) {  
  4.     case R.id.avatarImg:// 更換頭像點選事件
  5.         menuWindow = new
     SelectPicPopupWindow(mContext, itemsOnClick);    
  6.         menuWindow.showAtLocation(findViewById(R.id.mainLayout),   
  7.                 Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 00);   
  8.         break;  
  9.     case R.id.loginBtn://登入按鈕跳轉事件
  10.         startActivity(new Intent(mContext, UploadActivity.class));  
  11.         break
    ;  
  12.     default:  
  13.         break;  
  14.     }  
  15. }  
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.avatarImg:// 更換頭像點選事件
			menuWindow = new SelectPicPopupWindow(mContext, itemsOnClick);  
			menuWindow.showAtLocation(findViewById(R.id.mainLayout), 
					Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 0, 0); 
			break;
		case R.id.loginBtn://登入按鈕跳轉事件
			startActivity(new Intent(mContext, UploadActivity.class));
			break;

		default:
			break;
		}
	}
彈出窗繫結一個按鈕事件
[java] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. //為彈出視窗實現監聽類  
  2. private OnClickListener itemsOnClick = new OnClickListener() {  
  3.     @Override
  4.     publicvoid onClick(View v) {  
  5.         menuWindow.dismiss();  
  6.         switch (v.getId()) {  
  7.         // 拍照
  8.         case R.id.takePhotoBtn:  
  9.             Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  
  10.             //下面這句指定呼叫相機拍照後的照片儲存的路徑
  11.             takeIntent.putExtra(MediaStore.EXTRA_OUTPUT,   
  12.                     Uri.fromFile(new File(Environment.getExternalStorageDirectory(), IMAGE_FILE_NAME)));  
  13.             startActivityForResult(takeIntent, REQUESTCODE_TAKE);  
  14.             break;  
  15.         // 相簿選擇圖片
  16.         case R.id.pickPhotoBtn:  
  17.             Intent pickIntent = new Intent(Intent.ACTION_PICK, null);  
  18.             // 如果朋友們要限制上傳到伺服器的圖片型別時可以直接寫如:"image/jpeg 、 image/png等的型別"
  19.             pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");  
  20.             startActivityForResult(pickIntent, REQUESTCODE_PICK);  
  21.             break;  
  22.         default:  
  23.             break;  
  24.         }  
  25.     }  
  26. };   
	//為彈出視窗實現監聽類  
	private OnClickListener itemsOnClick = new OnClickListener() {
		@Override
		public void onClick(View v) {
			menuWindow.dismiss();
			switch (v.getId()) {
			// 拍照
			case R.id.takePhotoBtn:
				Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
				//下面這句指定呼叫相機拍照後的照片儲存的路徑
				takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, 
						Uri.fromFile(new File(Environment.getExternalStorageDirectory(), IMAGE_FILE_NAME)));
				startActivityForResult(takeIntent, REQUESTCODE_TAKE);
				break;
			// 相簿選擇圖片
			case R.id.pickPhotoBtn:
				Intent pickIntent = new Intent(Intent.ACTION_PICK, null);
				// 如果朋友們要限制上傳到伺服器的圖片型別時可以直接寫如:"image/jpeg 、 image/png等的型別"
				pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
				startActivityForResult(pickIntent, REQUESTCODE_PICK);
				break;
			default:
				break;
			}
		}
	}; 
為影象選取返回的接收處理 [java] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. @Override
  2. publicvoid onActivityResult(int requestCode, int resultCode, Intent data) {  
  3.     switch (requestCode) {  
  4.     case REQUESTCODE_PICK:// 直接從相簿獲取
  5.         try {  
  6.             startPhotoZoom(data.getData());  
  7.         } catch (NullPointerException e) {  
  8.             e.printStackTrace();// 使用者點選取消操作
  9.         }  
  10.         break;  
  11.     case REQUESTCODE_TAKE:// 呼叫相機拍照
  12.         File temp = new File(Environment.getExternalStorageDirectory() + "/" + IMAGE_FILE_NAME);  
  13.         startPhotoZoom(Uri.fromFile(temp));  
  14.         break;  
  15.     case REQUESTCODE_CUTTING:// 取得裁剪後的圖片
  16.         if (data != null) {  
  17.             setPicToView(data);  
  18.         }  
  19.         break;  
  20.     }  
  21.     super.onActivityResult(requestCode, resultCode, data);  
  22. }  
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		
		switch (requestCode) {
		case REQUESTCODE_PICK:// 直接從相簿獲取
			try {
				startPhotoZoom(data.getData());
			} catch (NullPointerException e) {
				e.printStackTrace();// 使用者點選取消操作
			}
			break;
		case REQUESTCODE_TAKE:// 呼叫相機拍照
			File temp = new File(Environment.getExternalStorageDirectory() + "/" + IMAGE_FILE_NAME);
			startPhotoZoom(Uri.fromFile(temp));
			break;
		case REQUESTCODE_CUTTING:// 取得裁剪後的圖片
			if (data != null) {
				setPicToView(data);
			}
			break;
		}
		super.onActivityResult(requestCode, resultCode, data);
	}
把圖片顯示出來,然後上傳
[java] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. /** 
  2.  * 裁剪圖片方法實現 
  3.  * @param uri 
  4.  */
  5. publicvoid startPhotoZoom(Uri uri) {  
  6.     Intent intent = new Intent("com.android.camera.action.CROP");  
  7.     intent.setDataAndType(uri, "image/*");  
  8.     // crop=true是設定在開啟的Intent中設定顯示的VIEW可裁剪
  9.     intent.putExtra("crop""true");  
  10.     // aspectX aspectY 是寬高的比例
  11.     intent.putExtra("aspectX"1);  
  12.     intent.putExtra("aspectY"1);  
  13.     // outputX outputY 是裁剪圖片寬高
  14.     intent.putExtra("outputX"300);  
  15.     intent.putExtra("outputY"300);  
  16.     intent.putExtra("return-data"true);  
  17.     startActivityForResult(intent, REQUESTCODE_CUTTING);  
  18. }  
  19. /**  
  20.  * 儲存裁剪之後的圖片資料  
  21.  * @param picdata  
  22.  */  
  23. privatevoid setPicToView(Intent picdata) {  
  24.     Bundle extras = picdata.getExtras();  
  25.     if (extras != null) {  
  26.         // 取得SDCard圖片路徑做顯示
  27.         Bitmap photo = extras.getParcelable("data");  
  28.         Drawable drawable = new BitmapDrawable(null, photo);  
  29.         urlpath = FileUtil.saveFile(mContext, "temphead.jpg", photo);  
  30.         avatarImg.setImageDrawable(drawable);  
  31.         // 新執行緒後臺上傳服務端
  32.         pd = ProgressDialog.show(mContext, null"正在上傳圖片,請稍候...");  
  33.         new Thread(uploadImageRunnable).start();  
  34.     }  
  35. }  
  36. /** 
  37.  * 使用HttpUrlConnection模擬post表單進行檔案 
  38.  * 上傳平時很少使用,比較麻煩 
  39.  * 原理是: 分析檔案上傳的資料格式,然後根據格式構造相應的傳送給伺服器的字串。 
  40.  */
  41. Runnable uploadImageRunnable = new Runnable() {  
  42.     @Override
  43.     publicvoid run() {  
  44.         if(TextUtils.isEmpty(imgUrl)){  
  45.             Toast.makeText(mContext, "還沒有設定上傳伺服器的路徑!", Toast.LENGTH_SHORT).show();  
  46.             return;  
  47.         }  
  48.         Map<String, String> textParams = new HashMap<String, String>();  
  49.         Map<String, File> fileparams = new HashMap<String, File>();  
  50.         try {  
  51.             // 建立一個URL物件
  52.             URL url = new URL(imgUrl);  
  53.             textParams = new HashMap<String, String>();  
  54.             fileparams = new HashMap<String, File>();  
  55.             // 要上傳的圖片檔案
  56.             File file = new File(urlpath);  
  57.             fileparams.put("image", file);  
  58.             // 利用HttpURLConnection物件從網路中獲取網頁資料
  59.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  60.             // 設定連線超時(記得設定連線超時,如果網路不好,Android系統在超過預設時間會收回資源中斷操作)
  61.             conn.setConnectTimeout(5000);  
  62.             // 設定允許輸出(傳送POST請求必須設定允許輸出)
  63.             conn.setDoOutput(true);  
  64.             // 設定使用POST的方式傳送
  65.             conn.setRequestMethod("POST");  
  66.             // 設定不使用快取(容易出現問題)
  67.             conn.setUseCaches(false);  
  68.             conn.setRequestProperty("Charset""UTF-8");//設定編碼   
  69.             // 在開始用HttpURLConnection物件的setRequestProperty()設定,就是生成HTML檔案頭
  70.             conn.setRequestProperty("ser-Agent""Fiddler");  
  71.             // 設定contentType
  72.             conn.setRequestProperty("Content-Type""multipart/form-data; boundary=" + NetUtil.BOUNDARY);  
  73.             OutputStream os = conn.getOutputStream();  
  74.             DataOutputStream ds = new DataOutputStream(os);  
  75.             NetUtil.writeStringParams(textParams, ds);  
  76.             NetUtil.writeFileParams(fileparams, ds);  
  77.             NetUtil.paramsEnd(ds);  
  78.             // 對檔案流操作完,要記得及時關閉
  79.             os.close();  
  80.             // 伺服器返回的響應嗎
  81.             int code = conn.getResponseCode(); // 從Internet獲取網頁,傳送請求,將網頁以流的形式讀回來
  82.             // 對響應碼進行判斷
  83.             if (code == 200) {// 返回的響應碼200,是成功
  84.                 // 得到網路返回的輸入流
  85.                 InputStream is = conn.getInputStream();  
  86.                 resultStr = NetUtil.readString(is);  
  87.             } else {  
  88.                 Toast.makeText(mContext, "請求URL失敗!", Toast.LENGTH_SHORT).show();  
  89.             }  
  90.         } catch (Exception e) {  
  91.             e.printStackTrace();  
  92.         }  
  93.         handler.sendEmptyMessage(0);// 執行耗時的方法之後傳送消給handler
  94.     }  
  95. };  
  96. Handler handler = new Handler(new Handler.Callback() {  
  97.     @Override
  98.     publicboolean handleMessage(Message msg) {  
  99.         switch (msg.what) {  
  100.         case0:  
  101.             pd.dismiss();  
  102.             try {  
  103.                 // 返回資料示例,根據需求和後臺資料靈活處理
  104.                 // {"status":"1","statusMessage":"上傳成功","imageUrl":"http://120.24.219.49/726287_temphead.jpg"}
  105.                 JSONObject jsonObject = new JSONObject(resultStr);  
  106.                 // 服務端以字串“1”作為操作成功標記
  107.                 if (jsonObject.optString("status").equals("1")) {  
  108.                     BitmapFactory.Options option = new BitmapFactory.Options();  
  109.                     // 壓縮圖片:表示縮圖大小為原始圖片大小的幾分之一,1為原圖,3為三分之一
  110.                     option.inSampleSize = 1;  
  111.                     // 服務端返回的JsonObject物件中提取到圖片的網路URL路徑
  112.                     String imageUrl = jsonObject.optString("imageUrl");  
  113.                     Toast.makeText(mContext, imageUrl, Toast.LENGTH_SHORT).show();  
  114.                 }else{  
  115.                     Toast.makeText(mContext, jsonObject.optString("statusMessage"), Toast.LENGTH_SHORT).show();  
  116.                 }  
  117.             } catch (JSONException e) {  
  118.                 e.printStackTrace();  
  119.             }  
  120.             break;  
  121.         default:  
  122.             break;  
  123.         }  
  124.         returnfalse;  
  125.     }  
  126. });  
	/**
	 * 裁剪圖片方法實現
	 * @param uri
	 */
	public void startPhotoZoom(Uri uri) {
		Intent intent = new Intent("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", 300);
		intent.putExtra("outputY", 300);
		intent.putExtra("return-data", true);
		startActivityForResult(intent, REQUESTCODE_CUTTING);
	}
		
	/**
	 * 儲存裁剪之後的圖片資料
	 * @param picdata
	 */
	private void setPicToView(Intent picdata) {
		Bundle extras = picdata.getExtras();
		if (extras != null) {
			// 取得SDCard圖片路徑做顯示
			Bitmap photo = extras.getParcelable("data");
			Drawable drawable = new BitmapDrawable(null, photo);
			urlpath = FileUtil.saveFile(mContext, "temphead.jpg", photo);
			avatarImg.setImageDrawable(drawable);

			// 新執行緒後臺上傳服務端
			pd = ProgressDialog.show(mContext, null, "正在上傳圖片,請稍候...");
			new Thread(uploadImageRunnable).start();
		}
	}

	/**
	 * 使用HttpUrlConnection模擬post表單進行檔案
	 * 上傳平時很少使用,比較麻煩
	 * 原理是: 分析檔案上傳的資料格式,然後根據格式構造相應的傳送給伺服器的字串。
	 */
	Runnable uploadImageRunnable = new Runnable() {
		@Override
		public void run() {
			
			if(TextUtils.isEmpty(imgUrl)){
				Toast.makeText(mContext, "還沒有設定上傳伺服器的路徑!", Toast.LENGTH_SHORT).show();
				return;
			}
			
			Map<String, String> textParams = new HashMap<String, String>();
			Map<String, File> fileparams = new HashMap<String, File>();
			
			try {
				// 建立一個URL物件
				URL url = new URL(imgUrl);
				textParams = new HashMap<String, String>();
				fileparams = new HashMap<String, File>();
				// 要上傳的圖片檔案
				File file = new File(urlpath);
				fileparams.put("image", file);
				// 利用HttpURLConnection物件從網路中獲取網頁資料
				HttpURLConnection conn = (HttpURLConnection) url.openConnection();
				// 設定連線超時(記得設定連線超時,如果網路不好,Android系統在超過預設時間會收回資源中斷操作)
				conn.setConnectTimeout(5000);
				// 設定允許輸出(傳送POST請求必須設定允許輸出)
				conn.setDoOutput(true);
				// 設定使用POST的方式傳送
				conn.setRequestMethod("POST");
				// 設定不使用快取(容易出現問題)
				conn.setUseCaches(false);
				conn.setRequestProperty("Charset", "UTF-8");//設定編碼   
				// 在開始用HttpURLConnection物件的setRequestProperty()設定,就是生成HTML檔案頭
				conn.setRequestProperty("ser-Agent", "Fiddler");
				// 設定contentType
				conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + NetUtil.BOUNDARY);
				OutputStream os = conn.getOutputStream();
				DataOutputStream ds = new DataOutputStream(os);
				NetUtil.writeStringParams(textParams, ds);
				NetUtil.writeFileParams(fileparams, ds);
				NetUtil.paramsEnd(ds);
				// 對檔案流操作完,要記得及時關閉
				os.close();
				// 伺服器返回的響應嗎
				int code = conn.getResponseCode(); // 從Internet獲取網頁,傳送請求,將網頁以流的形式讀回來
				// 對響應碼進行判斷
				if (code == 200) {// 返回的響應碼200,是成功
					// 得到網路返回的輸入流
					InputStream is = conn.getInputStream();
					resultStr = NetUtil.readString(is);
				} else {
					Toast.makeText(mContext, "請求URL失敗!", Toast.LENGTH_SHORT).show();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			handler.sendEmptyMessage(0);// 執行耗時的方法之後傳送消給handler
		}
	};
	
	Handler handler = new Handler(new Handler.Callback() {
		
		@Override
		public boolean handleMessage(Message msg) {
			switch (msg.what) {
			case 0:
				pd.dismiss();
				
				try {
					// 返回資料示例,根據需求和後臺資料靈活處理
					// {"status":"1","statusMessage":"上傳成功","imageUrl":"http://120.24.219.49/726287_temphead.jpg"}
					JSONObject jsonObject = new JSONObject(resultStr);
					
					// 服務端以字串“1”作為操作成功標記
					if (jsonObject.optString("status").equals("1")) {
						BitmapFactory.Options option = new BitmapFactory.Options();
						// 壓縮圖片:表示縮圖大小為原始圖片大小的幾分之一,1為原圖,3為三分之一
						option.inSampleSize = 1;
						
						// 服務端返回的JsonObject物件中提取到圖片的網路URL路徑
						String imageUrl = jsonObject.optString("imageUrl");
						Toast.makeText(mContext, imageUrl, Toast.LENGTH_SHORT).show();
					}else{
						Toast.makeText(mContext, jsonObject.optString("statusMessage"), Toast.LENGTH_SHORT).show();
					}
					
				} catch (JSONException e) {
					e.printStackTrace();
				}
				
				break;
				
			default:
				break;
			}
			return false;
		}
	});

(二)普通圖片上傳伺服器(程式碼)

    直接從這裡開始,和頭像那裡基本沒什麼區別,我把拍照什麼的單獨抽出了方法,思路更清晰 [java] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. //為彈出視窗實現監聽類  
  2. private OnClickListener itemsOnClick = new OnClickListener() {  
  3.     @Override
  4.     publicvoid onClick(View v) {  
  5.         // 隱藏彈出視窗
  6.         menuWindow.dismiss();  
  7.         switch (v.getId()) {  
  8.         case R.id.takePhotoBtn:// 拍照
  9.             takePhoto();  
  10.             break;  
  11.         case R.id.pickPhotoBtn:// 相簿選擇圖片
  12.             pickPhoto();  
  13.             break;  
  14.         case R.id.cancelBtn:// 取消
  15.             break;  
  16.         default:  
  17.             break;  
  18.         }  
  19.     }  
  20. };   
	
	//為彈出視窗實現監聽類  
	private OnClickListener itemsOnClick = new OnClickListener() {
		@Override
		public void onClick(View v) {
			// 隱藏彈出視窗
			menuWindow.dismiss();
			
			switch (v.getId()) {
			case R.id.takePhotoBtn:// 拍照
				takePhoto();
				break;
			case R.id.pickPhotoBtn:// 相簿選擇圖片
				pickPhoto();
				break;
			case R.id.cancelBtn:// 取消
				break;
			default:
				break;
			}
		}
	}; 
[java] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. /** 
  2.  * 拍照獲取圖片 
  3.  */
  4. privatevoid takePhoto() {  
  5.     // 執行拍照前,應該先判斷SD卡是否存在
  6.     String SDState = Environment.getExternalStorageState();  
  7.     if (SDState.equals(Environment.MEDIA_MOUNTED)) {  
  8.         Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  
  9.         /*** 
  10.          * 需要說明一下,以下操作使用照相機拍照,拍照後的圖片會存放在相簿中的  
  11.          * 這裡使用的這種方式有一個好處就是獲取的圖片是拍照後的原圖 
  12.          * 如果不使用ContentValues存放照片路徑的話,拍照後獲取的圖片為縮圖不清晰 
  13.          */
  14.         ContentValues values = new ContentValues();  
  15.         photoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);  
  16.         intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, photoUri);  
  17.         startActivityForResult(intent, SELECT_PIC_BY_TACK_PHOTO);  
  18.     } else {  
  19.         Toast.makeText(this"記憶體卡不存在", Toast.LENGTH_LONG).show();  
  20.     }  
  21. }  
  22. /*** 
  23.  * 從相簿中取圖片 
  24.  */
  25. privatevoid pickPhoto() {  
  26.     Intent intent = new Intent();  
  27.     // 如果要限制上傳到伺服器的圖片型別時可以直接寫如:"image/jpeg 、 image/png等的型別"
  28.     intent.setType("image/*");  
  29.     intent.setAction(Intent.ACTION_GET_CONTENT);  
  30.     startActivityForResult(intent, SELECT_PIC_BY_PICK_PHOTO);  
  31. }  
	/**
	 * 拍照獲取圖片
	 */
	private void takePhoto() {
		// 執行拍照前,應該先判斷SD卡是否存在
		String SDState = Environment.getExternalStorageState();
		if (SDState.equals(Environment.MEDIA_MOUNTED)) {

			Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
			/***
			 * 需要說明一下,以下操作使用照相機拍照,拍照後的圖片會存放在相簿中的 
			 * 這裡使用的這種方式有一個好處就是獲取的圖片是拍照後的原圖
			 * 如果不使用ContentValues存放照片路徑的話,拍照後獲取的圖片為縮圖不清晰
			 */
			ContentValues values = new ContentValues();
			photoUri = 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();
		// 如果要限制上傳到伺服器的圖片型別時可以直接寫如:"image/jpeg 、 image/png等的型別"
		intent.setType("image/*");
		intent.setAction(Intent.ACTION_GET_CONTENT);
		startActivityForResult(intent, SELECT_PIC_BY_PICK_PHOTO);
	}
處理一下圖片選取的頁面回撥
[java] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. @Override
  2.     protectedvoid onActivityResult(int requestCode, int resultCode, Intent data) {  
  3.         // 點選取消按鈕
  4.         if(resultCode == RESULT_CANCELED){  
  5.             return;  
  6.         }  
  7.         // 可以使用同一個方法,這裡分開寫為了防止以後擴充套件不同的需求
  8.         switch (requestCode) {  
  9.         case SELECT_PIC_BY_PICK_PHOTO:// 如果是直接從相簿獲取
  10.             doPhoto(requestCode, data);  
  11.             break;  
  12.         case SELECT_PIC_BY_TACK_PHOTO:// 如果是呼叫相機拍照時
  13.             doPhoto(requestCode, data);  
  14.             break;  
  15.         }  
  16.         super.onActivityResult(requestCode, resultCode, data);  
  17.     }  
@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// 點選取消按鈕
		if(resultCode == RESULT_CANCELED){
			return;
		}
		
		// 可以使用同一個方法,這裡分開寫為了防止以後擴充套件不同的需求
		switch (requestCode) {
		case SELECT_PIC_BY_PICK_PHOTO:// 如果是直接從相簿獲取
			doPhoto(requestCode, data);
			break;
		case SELECT_PIC_BY_TACK_PHOTO:// 如果是呼叫相機拍照時
			doPhoto(requestCode, data);
			break;
		}
		super.onActivityResult(requestCode, resultCode, data);
	}
接下來就是顯示圖片和上傳伺服器了,上傳和頭像是同一個流程,只是不進行裁切
[java] view plain copy print?在CODE上檢視程式碼片派生到我的程式碼片
  1. /** 
  2.  * 選擇圖片後,獲取圖片的路徑 
  3.  *  
  4.  * @param requestCode 
  5.  * @param data 
  6.  */
  7. privatevoid doPhoto(int requestCode, Intent data) {  
  8.     // 從相簿取圖片,有些手機有異常情況,請注意
  9.     if (requestCode == SELECT_PIC_BY_PICK_PHOTO) {  
  10.         if (data == null) {  
  11.             Toast.makeText(this"選擇圖片檔案出錯", Toast.LENGTH_LONG).show();  
  12.             return;  
  13.         }  
  14.         photoUri = data.getData();  
  15.         if (photoUri == null) {  
  16.             Toast.makeText(this"選擇圖片檔案出錯", Toast.LENGTH_LONG).show();  
  17.             return;  
  18.         }  
  19.     }  
  20.     String[] pojo = { MediaColumns.DATA };  
  21.     // The method managedQuery() from the type Activity is deprecated
  22.     //Cursor cursor = managedQuery(photoUri, pojo, null, null, null);
  23.     Cursor cursor = mContext.getContentResolver().query(photoUri, pojo, nullnullnull);  
  24.     if (cursor != null) {  
  25.         int columnIndex = cursor.getColumnIndexOrThrow(pojo[0]);  
  26.         cursor.moveToFirst();  
  27.         picPath = cursor.getString(columnIndex);  
  28.         // 4.0以上的版本會自動關閉 (4.0--14;; 4.0.3--15)
  29.         if (Integer.parseInt(Build.VERSION.SDK) < 14) {  
  30.             cursor.close();  
  31.         }  
  32.     }  
  33.     // 如果圖片符合要求將其上傳到伺服器
  34.     if (picPath != null && (    picPath.endsWith(".png") ||   
  35.                                 picPath.endsWith(".PNG") ||   
  36.                                 picPath.endsWith(".jpg") ||   
  37.                                 picPath.endsWith(".JPG"))) {  
  38.         BitmapFactory.Options option = new BitmapFactory.Options();  
  39.         // 壓縮圖片:表示縮圖大小為原始圖片大小的幾分之一,1為原圖
  40.         option.inSampleSize = 1;  
  41.         // 根據圖片的SDCard路徑讀出Bitmap
  42.         Bitmap bm = BitmapFactory.decodeFile(picPath, option);  
  43.         // 顯示在圖片控制元件上
  44.         picImg.setImageBitmap(bm);  
  45.         pd = ProgressDialog.show(mContext, null"正在上傳圖片,請稍候...");  
  46.         new Thread(uploadImageRunnable).start();  
  47.     } else {  
  48.         Toast.makeText(this"選擇圖片檔案不正確", Toast.LENGTH_LONG).show();  
  49.     }  
  50. }  
  51. /** 
  52.  * 使用HttpUrlConnection模擬post表單進行檔案 
  53.  * 上傳平時很少使用,比較麻煩 
  54.  * 原理是: 分析檔案上傳的資料格式,然後根據格式構造相應的傳送給伺服器的字串。 
  55.  */
  56. Runnable uploadImageRunnable = new Runnable() {  
  57.     @Override
  58.     publicvoid run() {  
  59.         if(TextUtils.isEmpty(imgUrl)){  
  60.             Toast.makeText(mContext, "還沒有設定上傳伺服器的路徑!", Toast.LENGTH_SHORT).show();  
  61.             return;  
  62.         }  
  63.         Map<String, String> textParams = new HashMap<String, String>();  
  64.         Map<String, File> fileparams = new HashMap<String, File>();  
  65.         try {  
  66.             // 建立一個URL物件
  67.             URL url = new URL(imgUrl);  
  68.             textParams = new HashMap<String, String>();  
  69.             fileparams = new HashMap<String, File>();  
  70.             // 要上傳的圖片檔案
  71.             File file = new File(picPath);  
  72.             fileparams.put("image", file);  
  73.             // 利用HttpURLConnection物件從網路中獲取網頁資料
  74.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  75.             // 設定連線超時(記得設定連線超時,如果網路不好,Android系統在超過預設時間會收回資源中斷操作)
  76.             conn.setConnectTimeout(5000);  
  77.             // 設定允許輸出(傳送POST請求必須設定允許輸出)
  78.             conn.setDoOutput(true);  
  79.             // 設定使用POST的方式傳送
  80.             conn.setRequestMethod("POST");  
  81.             // 設定不使用快取(容易出現問題)
  82.             conn.setUseCaches(false);  
  83.             // 在開始用HttpURLConnection物件的setRequestProperty()設定,就是生成HTML檔案頭
  84.             conn.setRequestProperty("ser-Agent""Fiddler");  
  85.             // 設定contentType
  86.             conn.setRequestProperty("Content-Type""multipart/form-data; boundary=" + NetUtil.BOUNDARY);  
  87.             OutputStream os = conn.getOutputStream();  
  88.             DataOutputStream ds = new DataOutputStream(os);  
  89.             NetUtil.writeStringParams(textParams, ds);  
  90.             NetUtil.writeFileParams(fileparams, ds);  
  91.             NetUtil.paramsEnd(ds);  
  92.             // 對檔案流操作完,要記得及時關閉
  93.             os.close();  
  94.