Android8.3調用攝像頭和相冊

? ? ? ? ?我們平時在使用QQ或微信的時候經常要和別人分享圖片,這些圖片可以是用手機攝像頭拍的铅鲤,也可以是從相冊中選取的。類似這樣的功能實在是太常見了枫弟,幾乎在每個應用程序中都會有邢享,那么本節(jié)我們就學習一下調用攝像頭和相冊方面的知識。

8.3.1 ? ?調用攝像頭拍照

? ? ? ? ? 先來看看攝像頭方面的知識淡诗,現(xiàn)在很多的應用都會要求用戶上傳一張圖片來作為頭像骇塘,這時攝像頭拍張照是最簡單快捷的伊履。下面就讓我們通過一個例子來學習一下如何才能在應用程序里調用手機的攝像頭進行拍照。

新建一個CameraAlbumTest項目款违,然后修改activity_main.xml中的代碼唐瀑,如下所示:

? ? ? ? ?可以看到,布局文件中只有兩個控件一個Button和一個ImageView插爹。BUtton適用于打開攝像頭進行拍照的哄辣,而ImageView則是用于將拍到的圖片顯示出來。

? ? ? ? ? 然后開始編寫調用攝像頭的具體邏輯赠尾,修改mainActivity中的代碼力穗,如下所示:


? ? ? ? ? ? 上述代碼稍微有點復雜,我們來仔細分析一下气嫁。在MainActivity中要做的第一件事自然是分別獲取到Button和ImageView的實例当窗,并給Button注冊上點擊事件,然后在Button的點擊事件里開始處理調用攝像頭的邏輯寸宵,我們重點看一下這部代碼崖面。

? ? ? ? ?首先這里創(chuàng)建了一個File,對象梯影,用于存放攝像頭拍下的圖片巫员,這里我們把圖片命名為output_image.jpg,并將它存放在手機SD卡的應用關聯(lián)緩存目錄下光酣。什么叫做應用關聯(lián)緩存目錄啦疏遏?就是指SD卡中專門存放當前應用緩存數(shù)據(jù)的位置,調用getExternalCacheDir()方法可以得到這個目錄救军,具體的路徑是/sdcard/Android/data/<package name>/cache财异。name為什么要使用應用關聯(lián)目錄存放圖片啦?因為從Android6.0系統(tǒng)開始唱遭,讀寫SD卡被列為了危險權限戳寸,如果將圖片存放在SD卡的任何其他目錄,都要進行運行時權限處理才行拷泽,而使用應關聯(lián)目錄則可以跳過這一步疫鹊。

? ? ? ? ? ?接著會進行一個判斷,如果運行設備的系統(tǒng)版本低于Android7.0就調用formFile()方法將File對象轉換成Uri對象司致,這個Uri對象標識這output_image.jpg這張圖片的本地真實路徑拆吆。否則就調用FileProvider的getUriForFile()方法將File對象轉換成一個封裝過得Uri對象。getUriForFile()方法接收3各參數(shù)脂矫,第一個參數(shù)要求傳入Context對象枣耀,第二個參數(shù)可以是任意唯一的字符串,第三個參數(shù)真是我們剛剛創(chuàng)建的File對象庭再。之所以要進行這樣一層轉換捞奕,是因為從Android7.0系統(tǒng)開始牺堰,直接使用本地真實路勁Uri被認為是不安全的,會拋出一個FileUriExposedException異常颅围。而FileProvider則是一種特殊的內容提供者伟葫,他是用了和內存提供器類似的機制來對數(shù)據(jù)進行保護,可以選擇性地保護院促,可以選擇性地將封裝過得Uri共享給外部筏养,從而提高了應用的安全性。

? ? ? ? ? ? 接下來構建出一個Intent對象一疯,并將這個Intent的action指定為android.media.action.IMAGE_CAPTURE,再調用Inten的putExtra()方法來指定圖片的輸出地址撼玄,這里填入剛剛得到的Uri對象,最后調用startActivityForResult()來啟動活動墩邀。由于我們使用的是一個隱士Intent掌猛,系統(tǒng)會找出能夠響應這個Intent的活動啟動,這樣照相機程序就會被打開眉睹,拍下的照片將會輸出到output_image.jpg中荔茬。

? ? ? ? ? 注意,剛才我們是使用startActivityForResult()來啟動活動的竹海,因此拍完照后會有結果返回到onActivityResult()方法中慕蔚。如果發(fā)現(xiàn)拍照成功,就可以調用BitmapFactory的decodeStream()方法將output_image.jpg這張照片解析成Bitmap對象斋配,然后把它設置到ImageView中顯示出來孔飒。

? ? ? ? ?不過現(xiàn)在還沒結束,剛才提到了內容提供器艰争,那么我們自然要在AndroidManifest.xml中內容提供器進行注冊了坏瞄,如下所示:(不多說,直接上代碼

? ? ? ? ? ? ?其實,android:name屬性的值是固定的甩卓,android:authorities屬性的之必須要和剛才FileProvider.getUriForFile()方法中第二個參數(shù)一致鸠匀。另外,這里還有<provider>標簽的內部使用<meta-data>來指定Uri的共享路徑逾柿,并引入了一個@xml/file_paths資源缀棍。當然,這個資源現(xiàn)在還是不存在的机错,下面我們就來創(chuàng)建它爬范。

右擊res目錄---->NEW----->File,創(chuàng)建一個file_paths.xml文件弱匪。然后修改file_paths.xml文件中的內容青瀑,如下所示:


? ? ? ? ? ?其中,external-path就是用來指定Uri共享的,name屬性的值可以隨便填狱窘,path屬性的值表示共享的的具體路徑。這里設置空值就表示將整個SD卡進行共享财搁,當然你也可以僅共享我們存放output_image.jpg這張圖片的路徑蘸炸。

? ? ? ? ? 另外還有一點要注意,在Android4.4系統(tǒng)之前尖奔,訪問SD卡的應用關聯(lián)目錄也是要聲明權限的搭儒,從4.4系統(tǒng)開始不再需要權限聲明。那么我們?yōu)榱四軌蚣嫒堇习姹鞠到y(tǒng)的手機提茁,還需要在AndroidManifest.xml中聲明一下訪問SD卡的權限

? ? ? ? 這樣代碼就編寫完了淹禾,現(xiàn)在將程序運行運行到手機上。

8.3.2 從相冊中選擇照片

? ? ? ? ? ?雖然調用攝像頭拍照既方便又快捷茴扁,但我們并不是每次都需要去當場拍以后在那個照片的铃岔,因為每個人的手機相冊里應該存在許許多多張照片,直接從相冊里選取一張現(xiàn)在照片回避打開相機拍照更加常用峭火。一個優(yōu)秀的應用程序應該講這兩種選擇方式都提供給用戶毁习,由用戶決定使用哪一種。下面我們就來看一下卖丸,如何才能實現(xiàn)從相冊中選擇照片的功能纺且。

? ? ? ? ? ?還是在CameraAlbumTest項目的基礎上進行修改,編輯activity_main.xml文件稍浆,在布局中添加一個按鈕用于從相冊選擇照片载碌,代碼如圖所示:

? ? ? ? ? 可以看到,在Choose_From_Album按鈕的點擊事件里我們現(xiàn)實進行了一個運行權限處理衅枫,動態(tài)申請WRITE_EXTERNAL_STORAGE這個危險權限嫁艇。為什么需要申請證券西安啦?因為相冊中的照片都是存在SD卡上为鳄,我們要從SD卡中讀取照片就需要申請這個權限裳仆。WRITE_EXTERNAL_STORAGE表示同時授予程序對SD卡讀寫能力。

? ? ? ? ?當用戶授予了權限申請之后孤钦,會調用openAlbum()方法歧斟,這里我們先是構建出了一個Intent對象,并將它的action指定為android.intent.action.GET_CONTENT.接著給這個Intent對象設置一些必要參數(shù)偏形,然后調用startActivityForResult()方法就可以打開相冊程序選擇照片了静袖。注意在調用startActivityForResult()方法的時候,我們個誒第二個參數(shù)傳入的值變成了CHOOSE_PHoto的case圖片俊扭,接下來的邏輯就比較復雜了队橙,首先為了兼容新老版本的手機,我們做了一個判斷,如果是4.4及以上系統(tǒng)的手機就調用handleImageOnKiKat()方法來處理圖片捐康,否則就調用handleImageBeforeKitke()方法來處理圖片仇矾。之所以要這樣做,是因為Android系統(tǒng)從4.4版本開始解总,選取相冊中的圖片不再返回圖片真實的Uri了贮匕,而是一個封裝過的Uri,因此如果是4.4版本以上的手機就需要對這個Uri進行解析才行花枫。

? ? ? ? ? 那么handleImageOnKiKat()方法中的邏輯基本是如何解析這個封裝過的Uri了刻盐。這里有好幾種判斷情況,如果返回的Uri是document類型的話劳翰,那就取出document id進行處理敦锌,如果不是的話,那么就是用普通的方式處理佳簸。另外乙墙,如果Uri的authority是media格式的話,document id還需要再進行一次解析溺蕉,要通過字符串分隔的方式取出后半部分才能得到真正的數(shù)字id伶丐。取出的id用于構建新的Uri和條件語句,然后把這些值作為參數(shù)傳入到getImagePath()方法當中疯特,就可以獲取到圖片的真實路徑了哗魂。拿到圖片的路徑之后,在調用disPlayImage()方法將圖片顯示在界面上漓雅。

? ? ? ? ? ? ? ?相比于handleImageOnKikAT()方法录别,handleImageBeforeKiKat()方法中的邏輯就要簡單很多了,因為它的Uri是沒有封裝過的邻吞,不需要任何解析组题,直接將Uri傳入到getImagePath()方法當中就能獲取到圖片的真實路徑了,最后同樣是調用displayImage()方法來讓圖片顯示到界面上抱冷。

? ? ? ? ? ? ? 現(xiàn)在將程序重新運行到手機上崔列,然后點擊一下choose From Album按鈕,首先會彈出權限申請對象畫框旺遮,如圖8.14所示赵讯。

? ? ? ? ? ? ?點擊允許之后就會打開手機相冊,如圖8.15所示:



? ? ? ? ? ? 然后隨意選擇一張照片耿眉,回到我們程序的界面边翼,選中的照片應該就會顯示出來了,如圖8.16所示鸣剪。


? ? ? ? ? ?調用攝像頭拍照以及從相冊中選取照片很多Android應用都會帶有的功能组底,現(xiàn)在你已經將這兩種技術學會了丈积,將來工作中需要開發(fā)類似的功能,相信你一定會輕松完成债鸡。不過目前我們現(xiàn)實還不算完美江滨,因為有些照片經過裁剪之后體積仍然很大,直接加載到內存中又可能會導致程序崩潰厌均。更好的做好是根據(jù)項目的需求先對照片進行適當?shù)膲嚎s牙寞,然后再加載到內存中。至于如何對照片進行壓縮莫秆,就要開眼你查閱資料的能力了,這里就不再展開進行講解了悔详。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末镊屎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子茄螃,更是在濱河造成了極大的恐慌缝驳,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件归苍,死亡現(xiàn)場離奇詭異用狱,居然都是意外死亡,警方通過查閱死者的電腦和手機拼弃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門夏伊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吻氧,你說我怎么就攤上這事溺忧。” “怎么了盯孙?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵鲁森,是天一觀的道長。 經常有香客問我振惰,道長歌溉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任骑晶,我火速辦了婚禮痛垛,結果婚禮上,老公的妹妹穿的比我還像新娘透罢。我一直安慰自己榜晦,他們只是感情好,可當我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布羽圃。 她就那樣靜靜地躺著乾胶,像睡著了一般抖剿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上识窿,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天斩郎,我揣著相機與錄音,去河邊找鬼喻频。 笑死缩宜,一個胖子當著我的面吹牛,可吹牛的內容都是我干的甥温。 我是一名探鬼主播锻煌,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼姻蚓!你這毒婦竟也來了宋梧?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤狰挡,失蹤者是張志新(化名)和其女友劉穎捂龄,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體加叁,經...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡倦沧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了它匕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片展融。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖豫柬,靈堂內的尸體忽然破棺而出愈污,到底是詐尸還是另有隱情,我是刑警寧澤轮傍,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布暂雹,位于F島的核電站,受9級特大地震影響创夜,放射性物質發(fā)生泄漏杭跪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一驰吓、第九天 我趴在偏房一處隱蔽的房頂上張望涧尿。 院中可真熱鬧,春花似錦檬贰、人聲如沸姑廉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽桥言。三九已至萌踱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間号阿,已是汗流浹背并鸵。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扔涧,地道東北人园担。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像枯夜,于是被迫代替她去往敵國和親弯汰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內容