2015/8/30

[Android][Programming] 關於 Android 6.0 Marshmallow 的權限控制

在七月 Google 發表了下一個版本的 Android 。在經過多個月份的測試之後,最後正式的向大眾宣布版本 Marshmallow (棉花糖) ,API 版本也更新到了 23。

這次新增了眾多的功能,關於 API 的改變可以參考 Android Developer 的網站。新的功能像是新增了指紋辨識的 API ,這次在 App 權限的控制之上也有了新的調整。在過去,我們安裝程式時需要一次授權所有的權限給該程式,造成一些安全上的疑慮,例如漫畫的程式卻要求電話號碼。新的版本改變了這個狀況,只有在 App 需要這些權限的時候會跳出來詢問使用者:要不要授權給該程式使用。

並且也提供了上次在 4.4 更新時被鬼隱的 AppOps ,可以讓使用者決定是否要收回已經授權的權限。舊有的程式未經過修改,初次安裝在 Marshmallow 上的話,會變成完全沒有授權任何權限給該程式的狀況,故勢必要經過一些調整,所以為此我研究了一些心得。:D



Android Developer 上面也有詳細的介紹

首先,在 AndroidManifest 新增該程式使用的權限依然是一定要的。

<!-- GPS授權 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- 允許應用程式透過Wifi或3G網路來定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
view raw gistfile1.txt hosted with ❤ by GitHub



以下的程式碼以獲取位置的權限為例子
private static final int LOCATION_REQUEST = 1; // requestPermissions 與 onResultPermissionsResult 使用
public void getNetworkFix() {
locateManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); // 獲取系統位置服務
// 檢查是否有授權
if ( checkLocationPermission() ) {
if (locateManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locateManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); // 定位
}
} else {
// 請求使用者授權
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_REQUEST);
}
}
private boolean checkLocationPermission() {
// 如果使用者的 Android 版本低於 6.0 ,直接回傳 True (在安裝時已授權)
int api_version = Build.VERSION.SDK_INT; //API版本
String android_version = Build.VERSION.RELEASE; //Android版本
if(api_version < Build.VERSION_CODES.M && !android_version.matches("(6)\\..+")) return true;
return (checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
// 授權對話框結果,一個請求授權對應一個 requestCode
if (requestCode == LOCATION_REQUEST) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
getNetworkFix();
else
Toast.makeText(this, "需要您的授權使用定位功能", Toast.LENGTH_SHORT).show(); // 不授權顯示
} else
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
view raw gistfile1.txt hosted with ❤ by GitHub


請求使用者授權處
new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}
view raw gistfile1.txt hosted with ❤ by GitHub

陣列裡可以包含多個授權。
另外 Manifest.Permissions.[權限] 引入的 Manifest 是 android.Manifest 這個不是自己程式的 Package,不然的話會找不到想要引入的權限 XDrz...

結果的話會長成這樣

使用者之後反悔的話可以到 [設定] -> [應用程式] -> [App] -> [權限],裡查看該程式的權限列表。


另外,要放在舊版本的 Android 執行時,一定要加入判斷版本號,不然會發 NoSuchMethodError !(廢話 XD


沒有留言:

張貼留言