Android呼叫系統相機的那些坑
Android實現拍照獲取圖片,有兩種方案,第一就是呼叫系統相機拍照,然後獲取拍照後的圖片,實現比較簡單,同時功能也比較簡單;第二就是自定義相機,實現複雜,但是功能強大。這裡討論的是第一種實現方案。
雖然第一種方案比較簡單,但是如果第一次用也會有一些磕磕絆絆,這裡把我遇到的問題記錄總結一些:
1、呼叫系統相機拍照後,系統報錯DeadObjectException;
解決辦法:在AndroidManifest的application裡新增
android:hardwareAccelerated=”false”
後來加上這句以後發現還是不好使,有的時候還是會報這個錯誤,後來在stack-overflow上看到這樣說的,
This means that your service had already stopped - either killed from the OS, or stopped from your application.
通過列印日誌發現service裡確實呼叫了onUnBind方法,What??為什麼unbind?我沒有進行這個操作啊?
stackoverflow地址:
後來想是不是我的Activity被系統收回了?在Activity的onDestory和onStop裡列印日誌,發現沒有走destroy,但是走了stop,而我的BasicActivity的onstop裡進行了unbind操作。這下豁然開朗了。把onStop的unbind操作轉移到onDestroy裡即可。(話說本來service的解綁也應該在onDestroy裡進行吧)
這裡因為自己的一個疏忽,除錯了好久才解決。 大家引以為戒,對於Activity生命週期不熟的同學可以移步到這個
2、拍照完畢後返回的intent裡資料格式不一致
一部分手機在返回的intent裡可以直接通過getData()
的方式來獲取圖片路徑;
但是,有時候我們會發現用相機拍攝獲取照片的時候,得到的 uri 是 null 的,這是因為android把拍攝的圖片封裝到bundle中傳遞回來,但是根據不同的機器獲得相片的方式不太一樣,可能有的相機能夠通過
inten.getData()獲取到uri,然後再根據uri獲取資料的路徑,在封裝成bitmap,但有時候有的相機獲取到的是null的,這時候我們該怎麼辦呢?
其實這時候我們就應該從bundle中獲取資料,通過 (Bitmap) bundle.get("data")
為了能夠同時適應上述兩種情況,我們這時候就應該在獲取圖片時做判斷了。我們可以在響應的時候做一個判斷:
if (uri == null){
Bitmap bmp = (Bitmap)data.getExtras().get("data");
//儲存bitmap到檔案
}
後面的過程就需要通過bitmap轉化成相應的圖片檔案了。不過得到最終的圖片是被壓縮了的。
如果想得到不被壓縮的圖片,可以在啟動相機的時候指定輸出檔案的路徑,程式碼如下:
Intent photoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
photoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(
newPhoto
));
photoIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
startActivityForResult(photoIntent,TAKE_PHOTO_REQUEST_CODE);
但是這樣也有一個問題,接著看下面。
3、指定拍照的路徑,返回的intent為null
如上面所說,指定拍照的路徑後,在onActivityResult(int requestCode, int resultCode, Intent data)程式碼中得到的data總為null?
於是我查看了Android系統框架Camera應用程式,找到了關於系統照相機如何處理返回值data問題!
預設情況下,即不需要指定intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);照相機有自己預設的儲存路徑,拍攝的照片將返回一個縮圖。如果想訪問原始圖片,可以通過dat extra能夠得到原始圖片位置。即,如果指定了目標uri,data就沒有資料,如果沒有指定uri,則data就返回有資料!現在想想,這種設計還是很合理的!
因為你既然指定了圖片路徑,那麼你就已經知道這個圖片的具體存在了!不需要系統在給你返回路徑了!
4、指定拍照的路徑,圖片沒有儲存甚至應用莫名重啟
遇到這種情況是因為你設定的圖片所在資料夾不存在,通常這種情況下系統會自動建立資料夾,但是有的手機不會自動建立,所以你在指定檔案路徑之前,一定要自己把資料夾建好!
5、照片存在了,但是名字不對
這種情況主要是你的照片名字存在空格等其它特殊字元,去除就可以了。