本文同步發表于我的微信公眾號,掃一掃文章底部的二維碼或在微信搜索 郭霖 即可關注,每個作業日都有文章更新,
Hello大家早上好,說起PermissionX,其實我已經有段時間沒有更新這個框架了,一是因為現在作業確實比較忙,沒有過去那么多的閑暇時間來寫開源專案,二是因為,PermissionX的主體功能已經相當穩定,并不需要頻繁對其進行變更,
不過之前一直有朋友在反映,對于Android中的一些特殊權限申請,PermissionX并不支持,是的,PermissionX本質上只是對Android運行時權限API進行了一層封裝,用于簡化運行時權限申請的,而這些特殊權限并不屬于Android運行時權限的一部分,所以PermissionX自然也是不支持的,
但是特殊權限卻是我們這些開發者們可能經常要與之打交道的一部分,它們并不難寫,但是每次去寫都感覺很繁瑣,因此經慎重考慮之后,我決定將幾個比較常用的特殊權限納入PermissionX的支持范圍,那么本篇文章我們就來看一看,對于這幾個常見的特殊權限,使用PermissionX和不使用PermissionX的寫法有什么不同之處,
對于還從來沒有了解過PermissionX的朋友們,可以通過我撰寫的《PermissionX權限系列專欄》逐步進行學習,將幫助你很好地理解和使用這個框架,
什么是特殊權限?
事實上,Android的權限機制也是經歷過長久的迭代的,在6.0系統之前,Google將權限機制設計的比較簡單,你的應用程式需要用到什么權限,只需要在AndroidManifest.xml檔案中宣告一下就可以了,
但是從6.0系統開始,Android引入了運行時權限機制,Android將常用的權限大致歸成了幾類,一類是普通權限,一類是危險權限,一類是特殊權限,
普通權限指的是那些不會直接威脅到用戶的安全和隱私的權限,這種權限和過去一樣,只需要在AndroidManifest.xml檔案中宣告一下就可以了,不需要做任何特殊處理,
危險權限則表示那些可能會觸及用戶隱私或者對設備安全性造成影響的權限,如獲取設備聯系人資訊、定位設備的地理位置等,這部分權限需要通過代碼進行申請,并要用戶手動同意才可獲得授權,PermissionX庫主要就是處理的這種權限的申請,
而特殊權限則更加少見,Google認為這種權限比危險權限還要敏感,因此不能僅僅讓用戶手動同意就可以獲得授權,而是需要讓用戶到專門的設定頁面去手動對某一個應用程式授權,該程式才能使用這個權限,
不過相比于危險權限,特殊權限沒有非常固定的申請方式,每個特殊權限可能都要使用不同的寫法才行,這也導致申請特殊權限比申請危險權限還要繁瑣,
從1.5.0版本開始,PermissionX對最常用的幾個特殊權限進行了支持,正如剛才所說,特殊權限沒有固定的申請方式,因此PermissionX也是針對于這幾個特殊權限一個一個去適配并支持的,如果你發現你需要申請的某個特殊權限還沒有被PermissionX支持,也可以向我提出需求,我會考慮在接下來的版本中加入,
jcenter的現狀
在過去,我們發布開源庫通常都是發布到jcenter上的,但是相信大家現在都已經知道了,jcenter即將停止服務,具體可以參考我的這篇文章 淺談JCenter即將被停止服務的事件 ,
目前的jcenter處在一個半廢棄的邊緣,雖然還可以正常從jcenter下載開源庫,但是已經不能再向jcenter發布新的開源庫了,而在明年2月1號之后,下載服務也會被關停,
所以,以后要想再發布開源庫我們只能選擇發布到其他倉庫,比如現在Google推薦我們使用Maven Central,
于是,從1.5.0版本開始,PermissionX也會將庫發布到Maven Center上,之前的老版本由于遷移價值并不大,所以我也不想再耗費經歷做遷移了,1.5.0之前的版本仍然保留在jcenter上,提供下載服務直到明年的2月1號,
而關于如何將庫發布到Maven Central,我在準備接下來的幾周里寫一篇比較詳細的文章,講述完整的發布程序,
那么我們還是先回到PermissionX,
請求特殊權限
Android里具體有哪些特殊權限呢?
說實話,這個我也不太清楚,我所了解的特殊權限基本都是因為需要用到了,然后發現這個權限即不屬于普通權限,也不屬于危險權限,要用一種更加特殊的方式去申請,才知道原來這是一個特殊權限,
因此,PermissionX 1.5.0版本中對特殊權限的支持,也就僅限于我知道的,以及從網友反饋得來的幾個最為常用的特殊權限,
一共是以下3個:
- 懸浮窗
- 修改設定
- 管理外部存盤
接下來我就分別針對這3個特殊權限做一下更加詳細的介紹,
懸浮窗
懸浮窗功能在不少應用程式中使用得非常頻繁,因為你可能總有一些內容是要置頂于其他內容之上顯示的,這個時候用懸浮窗來實作就會非常方便,
當然,如果你只是在自己的應用內部實作懸浮窗功能是不需要申請權限的,但如果你的懸浮窗希望也能置頂于其他應用程式的上方,這就必須得要申請權限了,
懸浮窗的權限名叫做SYSTEM_ALERT_WINDOW,如果你去查一下這個權限的檔案,會發現這個權限的申請方式比較特殊:
按照檔案上的說法,從Android 6.0系統開始,我們在使用SYSTEM_ALERT_WINDOW權限前需要發出一個action為Settings.ACTION_MANAGE_OVERLAY_PERMISSION的Intent,引導用戶手動授權,另外我們還可以通過Settings.canDrawOverlays()這個API來判斷用戶是否已經授權,
因此,想要申請懸浮窗權限,自然而然就可以寫出以下代碼:
if (Build.VERSION.SDK_INT >= 23) {
if (Settings.canDrawOverlays(context)) {
showFloatView()
} else {
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
startActivity(intent)
}
} else {
showFloatView()
}
看上去也不復雜嘛,
確實,但是它麻煩的點主要在于,它的請求方式是脫離于一般運行時權限的請求方式的,因此得要為它額外撰寫獨立的權限請求邏輯才行,
而PermissionX的目標就是要榷訓這種獨立的權限請求邏輯,減少差異化代碼撰寫,爭取使用同一套API來實作對特殊權限的請求,
如果你已經比較熟悉PermissionX的用法了,那么以下代碼你一定不會陌生:
PermissionX.init(activity)
.permissions(Manifest.permission.SYSTEM_ALERT_WINDOW)
.onExplainRequestReason { scope, deniedList ->
val message = "PermissionX需要您同意以下權限才能正常使用"
scope.showRequestReasonDialog(deniedList, message, "Allow", "Deny")
}
.request { allGranted, grantedList, deniedList ->
if (allGranted) {
Toast.makeText(activity, "所有申請的權限都已通過", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(activity, "您拒絕了如下權限:$deniedList", Toast.LENGTH_SHORT).show()
}
}
可以看到,這就是最標準的PermissionX的正常用法,但是我們在這里卻用來請求了懸浮窗權限,也就是說,即使是特殊權限,在PermissionX中也可以用普通的方式去處理,
另外不要忘記,所有申請的權限都必須在AndroidManifest.xml進行注冊才行:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.permissionx.app">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
</manifest>
那么運行效果是什么樣的呢?我們來看看吧:
可以看到,PermissionX還自帶了一個權限提示框,友好地告知用戶我們需要懸浮窗權限,引導用戶去手動開啟,
修改設定
了解了懸浮窗權限的請求方式之后,接下來我們就可以快速過一下修改設定權限的請求方式了,因為它們的用法是完全一樣的,
修改設定的權限名叫WRITE_SETTINGS,如果我們去查看一下它的檔案,你會發現它和剛才懸浮窗權限的檔案簡直如出一轍:
同樣是從Android 6.0系統開始,在使用WRITE_SETTINGS權限前需要先發出一個action為Settings.ACTION_MANAGE_WRITE_SETTINGS的Intent,引導用戶手動授權,然后我們還可以通過Settings.System.canWrite()這個API來判斷用戶是否已經授權,
所以,如果是自己手動申請這個權限,相信你已經知道要怎么寫了,
那么用PermissionX申請的話應該要怎么寫呢?這個當然就更簡單了,只需要把要申請的權限替換一下即可,其他部分都不用作修改:
PermissionX.init(activity)
.permissions(Manifest.permission.WRITE_SETTINGS)
...
當然,不要忘記在AndroidManifest.xml中注冊權限:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.permissionx.app">
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
</manifest>
運行一下,效果如下圖所示:
管理外部存盤
管理外部存盤權限也是一種特殊權限,它可以允許你的App擁有對整個SD卡進行讀寫的權限,
有些朋友可能會問,SD卡本來不就是可以全域讀寫的嗎?為什么還要再申請這個權限?
那你一定是沒有了解Android 11上的Scoped Storage功能,從Android 11開始,Android系統強制啟用了Scoped Storage,所有App都不再擁有對SD卡進行全域讀寫的權限了,
關于Scoped Storage的更多內容,可以參考我的這篇文章 Android 11新特性,Scoped Storage又有了新花樣 ,
但是如果有的應用就是要對SD卡進行全域讀寫該怎么辦呢(比如說檔案瀏覽器)?
不用擔心,Google仍然還是給了我們一種解決方案,那就是請求管理外部存盤權限,
這個權限是Android 11中新增的,為的就是應對這種特殊場景,
那么這個權限要怎么申請呢?我們還是先來看一看檔案:
大致可以分為幾步吧:
第一,在AndroidManifest.xml中宣告MANAGE_EXTERNAL_STORAGE權限,
第二,發出一個action為Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION的Intent,引導用戶手動授權,
第三,呼叫Environment.isExternalStorageManager()來判斷用戶是否已授權,
傳統請求權限的寫法我就不再演示了,使用PermissionX來請求的寫法仍然也還是差不多的,只不過要注意,因為MANAGE_EXTERNAL_STORAGE權限是Android 11系統新加入的,所以我們也只應該在Android 11以上系統去請求這個權限,代碼如下所示:
if (Build.VERSION.SDK_INT >= 30) {
PermissionX.init(this)
.permissions(Manifest.permission.MANAGE_EXTERNAL_STORAGE)
...
}
AndroidManifest.xml中的權限如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.permissionx.app">
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
</manifest>
運行一下程式,效果如下圖所示:
這樣我們就擁有全域讀寫SD卡的權限了,
另外PermissionX還有一個特別方便的地方,就是它可以一次性申請多個權限,假如我們想要同時申請懸浮窗權限和修改設定權限,只需要這樣寫就可以了:
PermissionX.init(activity)
.permissions(Manifest.permission.SYSTEM_ALERT_WINDOW, Manifest.permission.WRITE_SETTINGS)
...
運行效果如下圖所示:
當然你也可以將特殊權限與普通運行時權限放在一起申請,PermissionX對此也是支持的,只有當所有權限都請求結束時,PermissionX才會將所有權限的請求結果一次性回呼給開發者,
其實除了以上3種特殊權限之外,PermissionX還額外支持一種特殊權限,就是后臺定位權限,只不過這個權限并不是在1.5.0版本中才支持的,而是1.2版本就開始支持了,感興趣的朋友可以參考這篇文章 PermissionX現在支持Java了!還有Android 11權限變更講解 ,
如何升級
關于PermissionX新版本的內容變化就介紹到這里,升級的方式非常簡單,修改一下dependencies當中的版本號即可:
repositories {
google()
mavenCentral()
}
dependencies {
implementation 'com.guolindev.permissionx:permissionx:1.5.0'
}
注意現在一定要使用mavenCentral倉庫,而不能再使用jcenter了,
如果你對PermissionX的原始碼感興趣,可以訪問PermissionX的專案主頁:
https://github.com/guolindev/PermissionX
另外,本篇文章主要介紹的是PermissionX 1.5.0版本的新特性,如果你之前并沒有接觸過PermissionX,可以通過我撰寫的《PermissionX權限系列專欄》逐步進行學習,里面有非常詳盡的用法講解,
如果想要學習Kotlin和最新的Android知識,可以參考我的新書 《第一行代碼 第3版》,點擊此處查看詳情,
關注我的技術公眾號,每天都有優質技術文章推送,
微信掃一掃下方二維碼即可關注:
![]()
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/290693.html
標籤:其他
