This is an old revision of the document!
The Android permission model changed in API 23. Permissions were divided into Dangerous and Normal. Normal are as before, but Dangerous permissions must be accepted/rejected by the user when the program is first run. Also any Dangerous permission can be revoked at anytime by the user going to the app settings and removing the permission.
As such, if we change our target build to Jelly Bean (API 23) or higher then we must implement the new permission model.
Our current Android app permissions are predominately Normal. However all of our apps need 2 Dangerous permissions: ACCESS_FINE and WRITE_EXTERNAL. Code will need to be added to handle checking for and requesting access for these permissions.
One app (SmartGrade) asks for a permission that is no longer available: READ_LOG. This permission was necessary for several GPS drivers. A solution to this problem is still outstanding.
From those pages to check and request permission:
// Here, thisActivity is the current activity if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, Manifest.permission.READ_CONTACTS)) { // Show an explanation to the user *asynchronously* -- don't block // this thread waiting for the user's response! After the user // sees the explanation, try again to request the permission. } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS); // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an // app-defined int constant. The callback method gets the // result of the request. } }
From those pages to receive the permission request results:
@Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // contacts-related task you need to do. } else { // permission denied, boo! Disable the // functionality that depends on this permission. } return; } // other 'case' lines to check for other // permissions this app might request } }