拍照PhotoIntentActivity總結html
項目地址:http://developer.android.com/training/camera/photobasics.htmlandroid
好比在gradle配置文件裏:api
再看getExternalStoragePublicDirectory()方法緩存
也就是說,這個方法在api level 8中才添加進來的,而個人app須要在最小版本4中使用,若是直接使用這個方法,那個android studio會報錯,編譯不過去。app
糾正:這裏用api level 4也不行,最後改爲7,好像是ide
這個v7包,最小是7gradle
以上問題可使用TargetApi註解來解決,以下ui
這裏還須要注意一個問題,這裏的compileSdkVersion也是不能小於8的,若是小於8spa
這裏的FROYO的值是取不到的,假如我取4,那麼在Build.VERSION_CODES裏,只能取到1、2、3、4這四個值rest
這裏還須要進一步的處理
這裏先判斷當前的版本號的大小,來進行不一樣的操做
這個app中爲了得到相冊的目錄,使用的抽象類,在使用的類中定義一個成員變量,根據版本號不一樣,使用這個抽象類的子類進行實例化。【這裏用接口(Interface)是否也能夠呢】
抽象類:
兩個實現類:
成員變量:
使用類是根據不一樣的版本在onCreate中進行實例化:
調用手機的攝像頭進行拍照,發送的是隱式的intent,不指定具體的activity。那麼就存在這樣的狀況:手機上的全部app都不能處理這個intent,那麼個人app就會crash。因此在發隱式intent前,必須檢查是否存在可以處理這個隱式intent的app,如存在,那麼能夠發這個intent,若是不存在,那麼就不容許發這個intent
直接經過resolveActivity方法來判斷是否存處理在給定action的intent的activity。
下面更是指出驗證的重要性:若是在使用隱式intent調用 startActivityForResult(),並且這個intent沒有app可以處理,app會crash。
這個方法是sample裏給出的,核心代碼:
經過PackageManager查找是否存處理在給定action的intent的activity。
這裏直接發送action是MediaStore.ACTION_IMAGE_CAPTURE的intent,就會調用系統的相機app來進行拍照。
Ps.發以前要檢查隱式intent,如第2部分描述。
按3.1的方法直接發送intent,這裏直接從返回的Intent對象得到Bundle對象,再從Bundle對象中取「data」屬性,其內容就是拍照的圖片
(The Android Camera application encodes the photo in the return Intent delivered to onActivityResult() as a small Bitmap in the extras, under the key "data".)
這種方法只適合用於獲取小圖片
拍大圖片與拍小圖片的區別是,須要把拍的照片緩存到sd卡上,而後再從sd卡讀取這張照片進行處理。而不是直接從」data」中取出照片。
緩存到sd卡上以後,還須要找到它,因此在Activity裏聲名了一個保存這個路徑的成員變量
與拍小圖片不一樣,拍大圖片須要額外工做
結合圖中的註釋,這裏能夠看到整個發intent請求的過程
1) 與拍小圖片同樣,先聲名一個拍照的intent
2) 得到一個空的臨時文件
3) 把這個臨時文件的絕對路徑保存的activity對象的成員變量中
4) 指定把拍照的圖片保存到那個臨時文件中
5) 發送intent
這裏面涉及到不少知識點:文件操做、Uri(contentprovider),這裏不是主要的內容,不作介紹
因爲這裏已經把拍照獲得的圖片放到sd卡中緩存,因此直接從圖片路徑就能夠得到該圖片了,可是能夠添加一些額外工做
爲了防止省內存,通常不直接解碼獲得整個圖片,而是把圖片按必定的比例進行縮放再解碼。
Step 1 得到ImageView的大小
Step 2 得到Bitmap的大小
這裏 bmOptions.inJustDecodeBounds = true;就是爲了獲得大小,而不真正獲得Bitmap對象
Step 3 縮放並解碼獲得Bitmap圖片對象
這兩個方法,能夠保證在橫豎屏切換的時候,顯示的圖片仍然顯示,若是不加這兩個方法,那麼橫豎屏切換的時候,imageview上會再也不顯示圖片。
能夠看到,在save的時候,把圖片保存到bundle中,restore的時候,再從bundle中取出來,設置到imageview中。
onSaveInstanceState方法的默認實現解釋以下
簡而言之,這個方法會默認把界面上的view保存起來,若是在override這個方法時,不調用super方法,就須要手動保存這些view。
因此5.1中看到的方法中,須要先手動把成員變量mImageBitmap保存起來,再調用super的方法
onRestoreInstanceState方法的默認實現解釋以下
默認就是把onSaveInstanceState方法保存的view的狀態還原回來
因此,這裏在重寫onSaveInstanceState和onRestoreInstanceState時,在onSaveInstanceState中是最後執行super方法,在onRestoreInstanceState是最早執行super方法。