Last active
April 10, 2016 13:42
-
-
Save PhilippLgh/f624e551b09b1536c26e64b627207dcb to your computer and use it in GitHub Desktop.
Android Bootstrap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by Philipp on 3/3/2016. | |
* handles new permission system on marshmallow | |
* see http://developer.android.com/intl/zh-cn/training/permissions/requesting.html | |
*/ | |
public class PermissionsHelper { | |
private Activity getActivityContext(){ | |
return BaseApp.getCurrentActivity() | |
} | |
public static final int PERMISSIONS_REQUEST_READ_SD_CARD = 17; | |
public static final int PERMISSIONS_REQUEST_MODIFY_AUDIO = 18; | |
public static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 19; | |
private Map<String, Integer> permissionRequestCodeMapping = new HashMap<String, Integer>() | |
{{ | |
put(Manifest.permission.MODIFY_AUDIO_SETTINGS, PERMISSIONS_REQUEST_MODIFY_AUDIO); | |
put(Manifest.permission.READ_EXTERNAL_STORAGE, PERMISSIONS_REQUEST_READ_SD_CARD); | |
put(Manifest.permission.RECORD_AUDIO, PERMISSIONS_REQUEST_RECORD_AUDIO); | |
}}; | |
private int getRequestCode(@NonNull String permission) { | |
if(!permissionRequestCodeMapping.containsKey(permission)){ | |
throw new IllegalArgumentException(String.format("permission %s has no permission code",permission)); | |
} | |
return permissionRequestCodeMapping.get(permission); | |
} | |
//map request code to an event bus event type so that they can be broadcasted if no callback is found | |
private Map<Integer, String> eventBusMapping = new HashMap<Integer, String>() | |
{{ | |
put(PERMISSIONS_REQUEST_MODIFY_AUDIO, SystemEvents.PERMISSION_MODIFY_AUDIO_GRANTED_EVENT); | |
put(PERMISSIONS_REQUEST_READ_SD_CARD, SystemEvents.PERMISSION_ACCESS_STORAGE_GRANTED_EVENT); | |
put(PERMISSIONS_REQUEST_RECORD_AUDIO, SystemEvents.PERMISSION_RECORD_AUDIO_GRANTED_EVENT); | |
}}; | |
private String getEventBusName(int requestCode){ | |
return eventBusMapping.containsKey(requestCode) ? eventBusMapping.get(requestCode) : SystemEvents.UNKNOWN_PERMISSION_EVENT; | |
} | |
private Map<Integer, PermissionCallback> permissionRequestCallbacks = new HashMap<>(); | |
private PermissionsHelper(){} | |
private static PermissionsHelper instance; | |
public static PermissionsHelper getInstance(){ | |
if(instance==null){ | |
instance = new PermissionsHelper(); | |
} | |
return instance; | |
} | |
//############################ C H E C K P E R M I S S I O N ######################## | |
public boolean checkPermission(@NonNull String permission){ | |
Context context = getActivityContext(); | |
int permissionCheck = ContextCompat.checkSelfPermission(context /*= this activity*/, permission); | |
return permissionCheck == PackageManager.PERMISSION_GRANTED; | |
} | |
//region CONVENIENCE METHODS | |
public boolean hasStorageAccessRights() { | |
return checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE); | |
} | |
public boolean hasAudioModificationRights() { | |
return checkPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS); | |
} | |
public boolean hasRecordAudioRights() { | |
return checkPermission(Manifest.permission.RECORD_AUDIO); | |
} | |
//endregion | |
//############################ R E Q U E S T P E R M I S S I O N ######################## | |
public void requestPermission(@NonNull String permission){ | |
requestPermission(permission, null); | |
} | |
public void requestPermission(@NonNull String permission,@Nullable PermissionCallback callback) { | |
//map permission to request code | |
int requestCode = getRequestCode(permission); | |
//if no callback is passed -> default to event bus broadcast | |
if(callback==null){ | |
callback = getEventBusCallback(requestCode); | |
} | |
//if we already have the permission notify callback. done. | |
if(checkPermission(permission)){ | |
callback.permissionGranted(); | |
return; | |
} | |
//store callback for later when we have the user decision | |
//the repsonse will be passed to on onRequestPermissionsResult by ActivityBase | |
permissionRequestCallbacks.put(requestCode, callback); | |
Activity requestingActivity = getActivityContext(); | |
if (ContextCompat.checkSelfPermission(requestingActivity, permission) != PackageManager.PERMISSION_GRANTED) { | |
// Should we show an explanation? | |
if (ActivityCompat.shouldShowRequestPermissionRationale(requestingActivity, permission)) { | |
// 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. | |
// TODO show request explanation | |
} else { | |
// No explanation needed, we can request the permission. | |
ActivityCompat.requestPermissions(requestingActivity, new String[]{permission}, requestCode); | |
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an | |
// app-defined int constant. The callback method gets the | |
// result of the request. | |
} | |
} | |
} | |
//region CONVENIENCE METHODS | |
public void requestReadStoragePermission(@Nullable PermissionCallback callback){ | |
requestPermission(Manifest.permission.READ_EXTERNAL_STORAGE, callback); | |
} | |
public void requestAudioModificationPermission(@Nullable PermissionCallback callback) { | |
requestPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS, callback); | |
} | |
private void requestRecordAudioPermission(@Nullable PermissionCallback callback) { | |
requestPermission(Manifest.permission.RECORD_AUDIO, callback); | |
} | |
//endregion | |
private PermissionCallback getEventBusCallback(int requestCode){ | |
//if no callback is passed default to event bus broadcast | |
final String eventName = getEventBusName(requestCode); | |
return new PermissionCallback() { | |
@Override | |
public void permissionGranted() { | |
MainEventBus.getInstance().post(eventName, true); | |
} | |
@Override | |
public void permissionDenied() { | |
MainEventBus.getInstance().post(eventName, false); | |
} | |
}; | |
} | |
//############################ O N R E Q U E S T R E S U L T ######################## | |
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { | |
//we should at least have a default callback which uses an event bus broadcast | |
if(!permissionRequestCallbacks.containsKey(requestCode)){ | |
throw new RuntimeException("no permission callback found for request code "+requestCode); | |
} | |
PermissionCallback callback = permissionRequestCallbacks.remove(requestCode); | |
onRequestPermissionsResult(requestCode, permissions, grantResults, callback); | |
} | |
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults, PermissionCallback callback) { | |
// 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. | |
callback.permissionGranted(); | |
} else { | |
// permission denied. Disable the functionality that depends on this permission. | |
callback.permissionDenied(); | |
} | |
} | |
public static abstract class PermissionCallback{ | |
public abstract void permissionGranted(); | |
public void permissionDenied(){} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment