Uri Permission

從android N開始,如果應(yīng)用targetSdk大于等于24, 應(yīng)用data目錄默認(rèn)情況下,不能被其他應(yīng)用訪問,如果想分享本地文件給其他應(yīng)用(如相冊分享圖片) , 只能通過ContentProvider提供,接下來看看Content Uri相關(guān)幾個問題。

1. 為何需要Uri權(quán)限

通過Uri分享文件,需要通過ContentProvider實(shí)現(xiàn),如果不通過Uri權(quán)限授予讀取權(quán)限,就只能exported整個ContentProvider,訪問權(quán)限過大。通過Uri Permission授予權(quán)限,可以將訪問權(quán)限限制在單個文件的Uri上。

1. 如何授予權(quán)限?

有兩種方式:

1) 請求方通過startActivityForResult獲取文件Uri

這種情況下,通過setResult返回調(diào)用方一個intent,通過intent.setData將文件Uri 作為data返回,同時給intent.setFlag(Intent.FLAG_GRANT_READ_URI_PERMISSION)等權(quán)限,這樣,調(diào)用方就獲取了臨時權(quán)限。當(dāng)caller activity銷毀時,授予的權(quán)限會自動移除,不需要顯示的revokePermission

2) 通過Context.grantUriPermission()方法授予

該方法有三個參數(shù),分別為targetPackage, uri, permission, 通過這種方法授予權(quán)限,必須顯示調(diào)用Context.revokeUriPermission()方法移除掉

可以看到,兩種方法的區(qū)別在于:

  1. 通過intent.setData()只能用于startActivityForResult獲取uri的情況
  2. 通過intent.setData()授予的權(quán)限會自動移除,而content.grantUriPerimssion授予的權(quán)限必須顯示調(diào)用context.revokeUriPermission移除,需要自己管理權(quán)限聲明周期

Uri Permission生命周期

從上一節(jié)可以看到,通過intent.setData 授予的權(quán)限生命周期隨著caller activity銷毀而銷毀。
通過context.grantUriPermission需要調(diào)用context.revokeUriPermission移除。但grantUriPermission授予的權(quán)限也有其生命周期。默認(rèn)情況下,權(quán)限是不跨設(shè)備重啟的,一旦設(shè)備重啟了,權(quán)限就自動回收了,如果想重啟后依然具有權(quán)限,需要grantUriPermission時加上Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION屬性,并且被授權(quán)方需要調(diào)用方法ContentResolver.takePersistableUriPermission(Uri, int) 等方法(參考Intent.java), 才能使權(quán)限跨重啟。
另一種特例,如果授權(quán)方被清除數(shù)據(jù)了,同樣會移除掉權(quán)限,需要特別謹(jǐn)慎處理

Uri Permission or exported ContentProvider?

完全exported ContentProvider的風(fēng)險在于,可以不受任何限制調(diào)用ContentProvider, 如果對應(yīng)的文件獲取方法沒有處理好訪問權(quán)限控制則很容易造成隱私數(shù)據(jù)泄漏,因此需要非常嚴(yán)謹(jǐn)?shù)奶幚砦募x取接口,常見的方式是限制可訪問文件路徑,如要求file path必須是cache目錄等。
Uri Permission的問題在于,如果要持久化已授予的權(quán)限,被授權(quán)方需要處理takePersistableUriPermission等,同時,需要處理授權(quán)方清除數(shù)據(jù)問題。
綜合來看: 如果權(quán)限都是臨時的,則通過Uri Permission比較合適,如果是持久的,則Exported ContentProvider, 并且限制文件路徑的方式會更好。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容