What's the best way to check for permissions at runtime using MVP architecture?

后端 未结 3 1405
孤独总比滥情好
孤独总比滥情好 2021-02-01 18:41

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.

3条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-02-01 19:33

    Permissions requests and status are View(Fragment or Activity) responsibility due to depend of the user actions to make a request or grant permissions. I manage permissions with MVP as follows(Read external storage example):

    My Contract

    interface View {
        ...
        void requestReadPermission();
        boolean areReadPermissionGranted();
        void showPermissionError();
        void hidePermissionError();
        ...
    }
    
    interface Presenter {
        ...
        void setReadPermissions(boolean grantedPermissions);
        ...
    }
    
    interface Model {
        ...
    }
    

    My view implementation. (Fragment in this case but it can be Activity or whatever, the Presenter will only expect the response).

    public class MyView extends Fragment implements Contract.View {
    
    ...
    Contract.Presenter presenter;
    
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        boolean grantedPermissions =  (grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED);
        presenter.setReadPermissions(grantedPermissions);
    }
    
    
    
    @Override
    public void showPermissionError() {
        // Show not permission message
    }
    
    @Override
    public void hidePermissionError() {
        // Hide not permission message
    }
    
    @Override
    public void requestReadPermission() {
        this.requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
    }
    @Override
    public boolean areReadPermissionGranted() {
        return ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
    }
    ...
    

    And the Presenter implementation

    public class MyPresenter implements Contract.Presenter {
    
    ...
    Contract.View view;
    
    public void doSomethingThatRequiresPermissions() {
    
        ...
            if ( !view.areReadPermissionGranted() ) {
                view.requestReadPermission();
                view.showPermissionError();
            } else {
                view.hidePermissionError();
                doSomethingWithPermissionsGranted();
            }
        ...
    }
    
    @Override
    public void setReadPermissions(boolean grantedPermissions) {
        if( grantedPermissions ){
            view.hidePermissionError();
            doSomethingThatRequiresPermissions();
    
        } else {
            view.showPermissionError();
        }
    }
    
    public void doSomethingWithPermissionsGranted(){
        ...
    }
    

    Then you can make unit test like

    Contract.View mockedView;
    @Test
    public void requestAlbumListWithoutPermissions() {
        when(mockedView.areReadPermissionGranted()).thenReturn(false);
        presenter.doSomethingWithPermissionsGranted();
        verify(mockedView).showPermissionError();
        verify(mockedView).requestReadPermission();
    }
    

提交回复
热议问题