使用ACTION_IMAGE_CAPTURE可能存在的風險

qingchengzhilei發表於2019-03-04

很多的 Android App 中都有使用相機拍攝使用者頭像的功能。大部分開發者都會使用MediaStore.ACTION_IMAGE_CAPTURE來滿足這一需求。這可以節省很多時間,不需要單獨開發相機UI,直接呼叫系統相機;不需要向系統請求 Camera 許可權。正如官方文件裡面說的那樣,Taking Photos Simply。然而在最近的一次的測試中,我發現並沒有那麼簡單。因為執行了幾年的程式碼竟然發生了 Crash。具體的 log 如下:

java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cat=[android.intent.category.DEFAULT] flg=0x3 cmp=com.google.android.GoogleCamera/com.android.camera.activity.CaptureActivity clip={text/uri-list U:content://com.imzhiqiang.example.fileprovider/imageCache/tmp_avatar.jpg} (has extras) } from ProcessRecord{bf70afd 18107:com.imzhiqiang.example/u0a108} (pid=18107, uid=10108) with revoked permission android.permission.CAMERA

看上去是因為沒有處理執行時許可權導致的 Crash。Interesting! 我並沒有在 manifest 檔案中宣告 Camera 的許可權,為什麼會出現沒有處理 Camera 執行時許可權的問題呢?隨後我想到了可能是引用的 library 中宣告瞭該許可權。在 Android Studio 中檢視了 Merged Manifest,果然是這樣。圖中深色背景的許可權是我自己宣告的,下面的許可權是第三方的 library 宣告的。

permission

然而這和 Intent 又有什麼關係?使用 ACTION_IMAGE_CAPTURE 不是可以避免請求 Camera 許可權嗎?經過幾番周折過後,最後終於在官方文件中找到了答案。

action_image_capture

雖然很難理解 Google 這樣的做法,不過總算找到了問題的根本所在。在對 Camera 許可權進行正確的處理後,終於正常執行了。

結論

  1. 如果沒有在 manifest 檔案中宣告 Camera 許可權,使用 ACTION_IMAGE_CAPTURE 不需要對 Camera 許可權做執行時許可權處理,程式碼正常執行。如果宣告瞭就必須要做許可權處理。
  2. 使用 Intent 的 action 時,一定要仔細閱讀官方文件,避免類似的風險。
  3. 引用第三方 library 時,除了熟悉其內部原理和原始碼外,還要注意它在 manifest 檔案中新增的東西。

擴充套件閱讀

  1. Taking Photos Not So Simply: How I Got Bitten By ACTION_IMAGE_CAPTURE
  2. Use intent ACTION_IMAGE_CAPTURE to launch camera app requires CAMERA permission
  3. The ACTION_IMAGE_CAPTURE Fallacy

相關文章