Search code examples
javaandroidandroid-permissionsmvp

Android 3.1: Refactoring Button Code and Permissions to MVP Architecture


I have a simple one button app. The app show a button to make a phone call. I am having trouble clearly refactoring the code into an MVP architecture. There is a similar SO question (What's the best way to check for permissions at runtime using MVP architecture?). However, in this question, the answers are not clear enough to apply it to my problem.

The permissions request is not being recognized in the view from the presenter. The problem I'm having is in the view at startActivity(intent);. Android Studio underlines the intent in red and tells me the "Call requires permission which may be rejected by the user. The code should explicitly check for permissions".

Why is this refactoring wrong and how can I correct it to adhere to MVP architecture?

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

public void BtnSetEmergency_onclick(View view) {
    String number = "1112223333";
    final int REQUEST_PHONE_CALL = 1;
    Intent intent = new Intent(Intent.ACTION_CALL);
    intent.setData(Uri.parse("tel:" + number));

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {

        Toast.makeText(MainActivity.this, "One Button App", LENGTH_SHORT).show();

        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE},REQUEST_PHONE_CALL);
        }
        else{
            startActivity(intent);
        }

        return;
    }
    startActivity(intent);
  }
}

My Attempt at refactoring to an MVP architecture

View

public class MainActivity extends AppCompatActivity {

mainActivityPresenter mainActivityPresenterObject = new mainActivityPresenter();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

}


public void BtnSetEmergency_onclick(View view) {
    boolean phonePermissions = false;
    String number = "1112223333";
    final int REQUEST_PHONE_CALL = 1;
    Intent intent = new Intent(Intent.ACTION_CALL);
    intent.setData(Uri.parse("tel:" + number));


    phonePermissions = mainActivityPresenterObject.checkPhonePermissions(view);

    if(phonePermissions == true){
        startActivity(intent);
    }else if (phonePermissions == false){

    }
  }
}

Presenter

public class mainActivityPresenter {

public boolean checkPhonePermissions(View view){
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {

        Toast.makeText(MainActivity.this "One Button App", LENGTH_SHORT).show();

        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE},REQUEST_PHONE_CALL);
            return false;
        }
        else
        {
            return true;
        }
    }
    return false;
   }
}

===========================================================>

EDIT: Applying Final Answer Based on Nilesh Rathod Answer

===========================================================>

View

public class MainActivity extends AppCompatActivity {

    mainActivityPresenter mainActivityPresenterObject = new mainActivityPresenter();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    public void BtnSetEmergency_onclick(View view) {
        boolean phonePermissions = false;
        int number = 1112223333;
        Intent intent = new Intent(Intent.ACTION_CALL);
        intent.setData(Uri.parse("tel:" + Integer.toString(number)));

        if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE)
            == PackageManager.PERMISSION_GRANTED) {
            startActivity(intent);
        }else {
            mainActivityPresenterObject.checkPhonePermissions(view, MainActivity.this);
        }
    }
 }

Presenter

public class mainActivityPresenter {
    final int REQUEST_PHONE_CALL = 1;

    public void checkPhonePermissions(View view, MainActivity mainActivity){
        ActivityCompat.requestPermissions(mainActivity, new String[]{Manifest.permission.CALL_PHONE},REQUEST_PHONE_CALL);
    }

} 

Solution

  • "Call requires permission which may be rejected by the user. The code should explicitly check for permissions"

    Its behaving as intended.

    You need to check whether user granted permission for call or not before making call using startActivity(intent);

    FYI

    You can handle the result of permission dialog using ActivityCompat.OnRequestPermissionsResultCall

    This interface is the contract for receiving the results for permission requests

    Try this

    if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE)
                    == PackageManager.PERMISSION_GRANTED) {
           startActivity(intent);
    }else {
         // ask here for call permission
    }