作者簡介 原創微信公眾號郭霖 WeChat ID: guolin_blog
本篇來自Chay_Chan的投稿,分享了他在適配Android7.0時的一些心得,希望能夠幫助到大家。
Chay_Chan的博客地址:
http://blog.csdn.net/chay_chan
關于
最近在軟件的維護和更新過程中,了解到一些關于Android7.0的適配,在這里和大家分享一下,據我所知,需要對Notification、拍照、圖片的裁剪進行適配
Notification
關于 Android7.0 Notication 增加的特性,在此我就不詳細說明了,因為關于這類介紹的文章,早有一些大牛已經發布過了。我主要講的是我在應用更新功能中使用 Notification 踩到的坑。可以這么說,應用更新功能對于每個上線App都必不少,因為App的需求或者功能,都是會在不斷的變化和完善的。
我遇到的情況是:在 Android7.0 以下,以下代碼是顯示下載App新版本成功后的通知欄,點擊可以跳轉到安裝App的頁面:
以上代碼,在 Android7.0 以下,可以實現點擊通知欄攔跳轉到安裝App界面的功能,但是在安卓7.0或以上,點擊事件就出現問題了,點擊通知欄沒有任何反應,通知欄也不會顯示,但是會有error等級的log輸出,出現 FileUriExposedException 這樣的異常,原因是 Andorid7.0 的“私有目錄被限制訪問”,“StrictMode API 政策”。
由于從 Android7.0 開始,直接使用真實的路徑的Uri會被認為是不安全的,會拋出一個 FileUriExposedException 這樣的異常。需要使用 FileProvider,選擇性地將封裝過的Uri共享到外部。于是,需要對上面的代碼進行修改:
以上代碼增加了對系統版本的判斷,如果是 Andorid7.0 或以上,則不再使用 Uri.fromFile()方法 獲取文件的Uri,而是通過使用 FileProvider(support.v4提供的類) 的getUriForFile()。同時要添加多這么一行代碼 installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
由于 FileProvider 是繼承 ContentProvider,屬于四大組件之一,需要在AndroidManifest.xml中配置,配置如下:
配置中的 authorities 按照江湖規矩一般加上包名,${applicationId}是獲取當前項目的包名,前提是 defaultConfig{} 閉包中要有applicationId屬性。
標簽中的 resource 填寫配置 fileprovider 的配置文件,在res資源目錄下新建xml文件下,在該文件夾下創建 file_provider_paths.xml文件,這個xml文件名并不是一定要這么起,只要和清單文件中配置的文件名一致就行。
file_provider_paths.xml 的內容如下:
上述代碼中path="",是有特殊意義的,它代碼根目錄,也就是說你可以向其它的應用共享根目錄及其子目錄下任何一個文件了,如果你將 path 設為 path=”pictures”, 那么它代表著根目錄下的 pictures目錄(eg:/storage/emulated/0/pictures),如果你向其它應用分享 pictures目錄 范圍之外的文件是不行的。
完成上述的代碼修改和 FileProvider 的配置后,就可以兼容 Android7.0 或以上系統了,點擊通知欄可以跳轉到安裝App的界面了。到此,關于 Notification 在 Android7.0 的兼容就完成了。
拍照
在 Andorid7.0 以下,以下代碼可以實現跳轉到拍照界面的功能,拍完照會在對應開啟拍照界面的 Activity 中的 onActivityResult()方法 中回調:
但是在 Android7.0 或者以上,以上代碼在調用拍照功能的時候,會導致應用Crash,會報 FileUriExposedException 異常,需要對以上代碼進行修改,對使用App的系統版本進行判斷,修改后代碼如下:
修改完成后,在 Android7.0 或以上的手機調用就可以調用拍照功能了,拍照完后,在 onActivityResult() 回調中,imgFile就是保存拍照后圖片的文件對象,就可以進行相應的處理,比如說對圖片進行裁剪。
圖片的剪裁
在 Android7.0 以下,以下代碼可以調用手機自帶的圖片裁剪功能:
但是在 Android7.0 或以上,以上代碼就需要進行修改,修改如下:
getImageContentUri()方法 具體如下:
由于自己將發起裁剪請求的方法進行封裝,所以在 onActivityResult() 中,拍照完成后,如果需要對圖片進行裁剪,則可以這么操作:
ImageTools 的 decodeUriAsBitmap() 方法,是將Uri轉換為Bitmap對象,具體的代碼如下:
FileUtils.saveBitmapByQuality()方法,是對圖片進行壓縮,第一個參數傳入的是圖片的Bitmap對象,第二個參數是壓縮的保留率,比如上面使用的是80,即壓縮后為原來的80%,則是對其壓縮了20%,具體的代碼如下:
上述代碼可以實現和兼容 Android7.0 或以上系統的拍照+裁剪圖片的功能了。在這里順便把調用相冊功能寫貼出來吧,畢竟實際開發中需要上傳圖片的時候,通常會讓用戶選擇是拍照或者從相冊中獲取。
如果需要在選擇完相冊圖片后對圖片進行裁剪,則可以像上面拍照代碼那樣,需要在 onActivityResult() 回調中,發起裁剪請求。這里一次性貼出 onActivityResult 的處理:
好了,寫到這里,我的第一篇博客終于完成了,花了接近四個小時,因為這是屬于技術性的博客,文字要求嚴謹,所以不像寫作文那樣信手拈來。不過我盡量將文章寫得通俗易懂,希望可以幫助到更多的人,之前雖然在做項目的時候,有寫過不少筆記,但是從來沒有寫過博客,要是有哪些地方寫得不夠好,還請各位大牛提出意見,彼此交流和學習。
我之所以萌發寫博客的念頭,也是因為在開發過程中查詢問題的時候,無意間看到郭霖(人稱郭神)的博客,于是一篇篇的看了他的博客,也逐漸了解他,對他非常敬佩,昨天問了他寫博客對提升能力有沒有幫助,他也推薦我寫博客,所以今天我寫了第一篇博客,希望可以一直堅持下去,畢竟我對于安卓開發,一直都很熱衷。
文章原創作者GuoLin 書籍推薦
郭林大神原創android 書籍:《第一行代碼 android》