Skip to content

Instantly share code, notes, and snippets.

@PhilippLgh
Last active April 10, 2016 13:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PhilippLgh/f624e551b09b1536c26e64b627207dcb to your computer and use it in GitHub Desktop.
Save PhilippLgh/f624e551b09b1536c26e64b627207dcb to your computer and use it in GitHub Desktop.
Android Bootstrap
/**
* 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