I\'m developing an android app in which I have to ask for permissions at runtime. I\'m wondering about the best way to implement that using Model-View-Presenter architecture.
If you still want to be able to mock permission access/requests, you still create something like a PermissionHandler
, but only reference it inside your view class. For example -
Interface:
public interface PermissionsHandler {
boolean checkHasPermission(AppCompatActivity activity, String permission);
void requestPermission(AppCompatActivity activity, String[] permissions, int requestCode);
}
Production implementation:
public class PermissionsHandlerAndroid implements PermissionsHandler {
@Override
public boolean checkHasPermission(AppCompatActivity activity, String permission) {
return ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED;
}
@Override
public void requestPermission(AppCompatActivity activity, String[] permissions, int requestCode){
ActivityCompat.requestPermissions(activity, permissions, requestCode);
}
}
Mocked class (for example, to test and make sure your activity correctly handles onRequestPermissionsResult
)
public class PermissionsHandlerMocked implements PermissionsHandler {
@Override
public boolean checkHasPermission(AppCompatActivity activity, String permission) {
return false;
}
@Override
public void requestPermission(AppCompatActivity activity, String[] permissions, int requestCode){
int[] grantResults = new int[permissions.length];
for (int i = 0; i < permissions.length; i++) {
grantResults[i] = PackageManager.PERMISSION_GRANTED
}
activity.onRequestPermissionResult(requestCode, permissions, grantResults);
}
}
Then in your activity:
PermissionsHandler permissionsHandler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
permissionsHandler = Injection.providePermissionsHandler();
//or however you choose to inject your production vs mocked handler.
}
//method from your view interface, to be called by your presenter
@Override
void requestLocationPermission() {
permissionsHandler.requestPermision((AppCompatActivity) this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE_LOCATION};
}
fobo66, you can always make the view implement much more generic methods like
checkLocationPermissionGranted()
and requestLocationPermission()
. Then your view implementation can reference the activity as needed, and your presenter never has to touch the activity reference.