1. 程式人生 > >解釋 Android 呼叫系統相機,在onActivityResult中接收的data為null的原因

解釋 Android 呼叫系統相機,在onActivityResult中接收的data為null的原因

   很多時候,我們在使用程式呼叫系統相機的時候,會發現在onActivityResult中接收的data為null,開始我也一直不明白,這是為什麼,後來查看了原始碼才知道,今天在這記錄一下,方便以後忘了。哈哈。
下面這個方法是我呼叫系統相機的方法,其中紅色標記的方法是設定拍照後相片儲存的地址。
	/**
	 * 設定一些引數
	 * 
	 */
	private void takePhoto () {
		Intent intent = new Intent(); 
		intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
		intent.putExtra(MediaStore.EXTRA_OUTPUT, <span style="color:#ff0000;">setFilePath()</span>);
		openCameraOrAlbum(intent, TAKE_PICTURE);
	}
       /**
        * 呼叫系統相機
        * @param intent
        * @param requestCode
        */
       private void openCameraOrAlbum (Intent intent , int requestCode) {
          try {
               startActivityForResult(intent, requestCode);
           } catch (ActivityNotFoundException e) {
               ToastUtil.showShort(this, "無法開啟相機");
           }
       }

拍完照片,返回時在onActivityResult(int requestCode, int resultCode , Intent data)  中接收,通常很多人都會以為data就是儲存圖片資訊的,但我發現data是null的,這讓我著實費解,花了很長時間,查看了原始碼才明白。先貼原始碼看下。

 在 com.android.camera.Camera類中找到 doAttach() 方法 ,下面是doAttach()方法中部分程式碼的截圖

注:我是在grepCode上檢視的原始碼,這是個原始碼檢視網站,很強大哦)


請看1382行,mSaveUri這個變數儲存的就是我上面setFilePath()方法建立的圖片的地址,如上,我傳入了這個值,但是在1389行,系統儲存完圖片後,直接setResult(RESULT_OK)了。

並沒有建立intent返回,所有這就能理解為什麼在onActivityResult中的data為null的原因。解決方法,就是在你呼叫系統相機的Activity宣告一個變數,儲存你圖片的路徑,如下,我在setFilePath()方法中

儲存了圖片的地址

	/**
	 * 指定圖片儲存路徑 
	 * @return
	 */
	private Uri setFilePath() {
		String outPath = Environment.getExternalStorageDirectory()
				.getAbsoluteFile() + "/takePic/" + System.currentTimeMillis()+".jpg";
		File outFile = FileUtil.createDirFile(outPath);
		<span style="color:#cc0000;">this.mCameraFilePath = outFile.getAbsolutePath();   // 儲存圖片的地址</span>
		Log.d("TAG", "圖片地址:"+mCameraFilePath);
		return Uri.fromFile(outFile) != null ? Uri.fromFile(outFile) : null;
	}

這樣在onActivityResult()中使用mCameraFilePath 去訪問你拍的圖片即可。   

以上說的是給圖片設定自己儲存路徑的情況,那如果不設定會怎麼樣呢?請看上面原始碼截圖,如果不設定路徑,那麼mSaveUri這個變數就為null , 在1398行系統會將圖片轉化成Bitmap並建立Intent 存放在data裡面

所以在onActivityResult中通過 data.getExtras().get("data");就能拿到圖片的Bitmap 當然系統並沒有將圖片儲存到SD卡上,所以在手機中時找不到該圖片的,它只會當即返回這個圖片的bitmap物件。

但是,有個問題,如果不設定儲存的路徑,通過intent傳遞過去,則返回的圖片物件是被壓縮過的,圖片會變得很小

沒有原始圖片清晰,所以這是比較坑爹的。因此建議大家還是在呼叫相機的時候設定下面這個引數。

intent.putExtra(MediaStore.EXTRA_OUTPUT, setFilePath());

那麼拍照後儲存的圖片就是原始圖片了。

好了,以上就是我檢視原始碼得之的結果,希望能幫到大家。謝謝

這是我第一次寫部落格,覺得行就點個讚唄大笑。(改了好多次,哎不會用這個編輯器啊)