解釋 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());
那麼拍照後儲存的圖片就是原始圖片了。
好了,以上就是我檢視原始碼得之的結果,希望能幫到大家。謝謝
這是我第一次寫部落格,覺得行就點個讚唄。(改了好多次,哎不會用這個編輯器啊)