0

I have an app with a register activity. When the user registers he is asked for these two permissions:

  • READ_PHONE_STATE
  • READ_CONTACTS

User should be able to accept or decline both, or accept one and decline the other. Depending on that I would want to have 4 different results:

  1. If the user allows READ_PHONE_STATE and declines READ_CONTACTS the result should be:register(name, email, password, getMyPhoneNumber(), false);
  2. If the user declines READ_PHONE_STATE and allows READ_CONTACTS the result should be: register(name, email, password, "", true);
  3. If the user declines both the result should be: register(name, email, password, "", false);
  4. If the user allows both the result should be: register(name, email, password, getMyPhoneNumber(), true);

I have been trying to find a solution that would allow for these combinations for a while now, trying this, this, this, this, this and much more, but I couldn't find a working solution.

This is my original RegisterActivity:

public class RegisterActivity extends AppCompatActivity {
private static final String TAG = "RegisterActivity";
EditText nameText, emailText, passwordText;
Button registerButton;
TextView loginLink;
CheckBox checkBoxShowPassword;
private SessionManager session;
private SQLiteHandler db;
private static final int MY_PERMISSIONS_REQUEST_READ_CONTACTS = 0;
RegisterActivity registerActivity = RegisterActivity.this;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_register);

    nameText = findViewById(R.id.input_name);
    emailText = findViewById(R.id.input_email);
    passwordText = findViewById(R.id.input_password);
    registerButton = findViewById(R.id.btn_register);
    loginLink = findViewById(R.id.link_login);

    session = new SessionManager(getApplicationContext());
    db = new SQLiteHandler(getApplicationContext());
    if (session.isLoggedIn()) {
        Intent intent = new Intent(RegisterActivity.this, MainActivity.class);
        startActivity(intent);
        finish();
    }

    registerButton.setOnClickListener(v -> {
        String name = nameText.getText().toString().trim();
        String email = emailText.getText().toString().trim();
        String password = passwordText.getText().toString().trim();
        String phone = "";

        if (ContextCompat.checkSelfPermission(registerActivity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(registerActivity, Manifest.permission.READ_CONTACTS)) {
                if (!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
                    register(name, email, password, phone, false);
                } else {
                    Toast.makeText(getApplicationContext(), R.string.please_enter_credentials, Toast.LENGTH_LONG).show();
                }
            } else {
                ActivityCompat.requestPermissions(registerActivity, new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
            }
        } else {
            if (!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
                register(name, email, password, phone, true);
            } else {
                Toast.makeText(getApplicationContext(), R.string.please_enter_credentials, Toast.LENGTH_LONG).show();
            }
        }
    });
    loginLink.setOnClickListener(v -> {
        finish();
    });

    checkBoxShowPassword = findViewById(R.id.checkBoxShowPassword);
    checkBoxShowPassword.setOnCheckedChangeListener((buttonView, isChecked) -> {
        if (!isChecked) {               passwordText.setTransformationMethod(PasswordTransformationMethod.getInstance());
        } else {                passwordText.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
        }
    });
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    String email = emailText.getText().toString().trim();
    String password = passwordText.getText().toString().trim();
    String name = nameText.getText().toString().trim();
    String phone = "";

    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                if (!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
                    register(name, email, password, phone, true);
                } else {
                    Toast.makeText(getApplicationContext(), R.string.please_enter_credentials, Toast.LENGTH_LONG).show();
                }
            } else {
                if (!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
                    register(name, email, password, phone, false);
                } else {
                    Toast.makeText(getApplicationContext(), R.string.please_enter_credentials, Toast.LENGTH_LONG).show();
                }
            }
        }
    }
}

public void register(final String name, final String email, final String password, final String phone, Boolean isGranted) {
    Log.d(TAG, "Login");
    if (!validate()) {
        onRegisterFailed();
        return;
    }

    registerButton.setEnabled(true);
    String tag_string_req = "req_login";
    final ProgressDialog progressDialog = new ProgressDialog(RegisterActivity.this,
            R.style.AppTheme_Dark_Dialog);
    progressDialog.setIndeterminate(true);
    progressDialog.setMessage(getString(R.string.authenticating));
    progressDialog.show();

    ApiInterface apiService =
            ApiClient.getClient().create(ApiInterface.class);
    progressDialog.dismiss();

    Call<ContactResponse> call = apiService.register(name, email, password, phone);
    call.enqueue(new Callback<ContactResponse>() {
        @Override
        public void onResponse(Call<ContactResponse> call, retrofit2.Response<ContactResponse> response) {
            if (response.body().getError()) {
                String message = response.body().getErrorMessage();
                onRegisterFailed(message);
                return;
            }

            final Contact contact = response.body().getResults();
            if (contact != null) {
                session.setLogin(true);

                db.addUser(contact.getUserName(), contact.getEmail(), contact.getUserId(), contact.getCreatedAt(), contact.getAbout(),
                        contact.getThumbnailUrl(), contact.getPhone());

                Intent intent = new Intent(RegisterActivity.this,
                        MainActivity.class);
                startActivity(intent);
                finish();
                onRegisterSuccess();

                if (isGranted) {
                    updateContacts();
                }
            } else {
                onRegisterFailed();
            }
        }
        @Override
        public void onFailure(Call<ContactResponse> call, Throwable t) {
            // Log error here since request failed
            Log.e(TAG, t.toString());
            onRegisterFailed();
        }
    });
}
public void userExists(final String phone) {
}
public void onRegisterSuccess() {
    registerButton.setEnabled(true);
    setResult(RESULT_OK, null);
    finish();
}
public void onRegisterFailed() {
    Toast.makeText(getBaseContext(), R.string.registration_failed, Toast.LENGTH_LONG).show();
    registerButton.setEnabled(true);
}
public void onRegisterFailed(String message) {
    Toast.makeText(getBaseContext(), message, Toast.LENGTH_LONG).show();
    registerButton.setEnabled(true);
}
public boolean validate() {
    boolean valid = true;

    String name = nameText.getText().toString();
    String email = emailText.getText().toString();
    String password = passwordText.getText().toString();

    if (name.isEmpty() || name.length() < 3) {
        nameText.setError(getString(R.string.enter_3_chars));
        valid = false;
    } else {
        nameText.setError(null);
    }
    if (email.isEmpty() || !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
        emailText.setError(getString(R.string.enter_valid_email));
        valid = false;
    } else {
        emailText.setError(null);
    }
    if (password.isEmpty() || password.length() < 4 || password.length() > 20) {
        passwordText.setError(getString(R.string.enter_4_20_char));
        valid = false;
    } else {
        passwordText.setError(null);
    }

    return valid;
}
private String getMyPhoneNumber() {
    TelephonyManager tMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

    String simCountry = null;
    if (tMgr != null) {
        simCountry = tMgr.getSimCountryIso().toUpperCase();
    }
    if (tMgr != null) {
        String simOperatorCode = tMgr.getSimOperator();
    }
    if (tMgr != null) {
        String simOperatorName = tMgr.getSimOperatorName();
    }
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
    }
    String simSerial = tMgr.getSimSerialNumber();
    String MyPhoneNumber = "0000000000";
    try {
        MyPhoneNumber = tMgr.getLine1Number();
    } catch (NullPointerException ex) {
    }
    if (MyPhoneNumber == null || MyPhoneNumber.equals("")) {
        return "";
    }
    PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
    Phonenumber.PhoneNumber countryNumberProto = null;
    try {
        countryNumberProto = phoneUtil.parse(MyPhoneNumber, simCountry);
    } catch (NumberParseException e) {
        System.err.println(getString(R.string.numberparseexception_thrown) + e.toString());
    }
    return phoneUtil.format(countryNumberProto, PhoneNumberUtil.PhoneNumberFormat.E164);
}
public void updateContacts() {

    String[] PROJECTION = new String[]{
            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
            ContactsContract.CommonDataKinds.Phone.NUMBER
    };

    Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, null);

    HashMap<String, String> user = db.getUserDetails();
    String userId = user.get("uid");

    if (phones != null) {
        while (phones.moveToNext()) {
            if (phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER) != -1) {
                final String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                ApiInterface apiService =
                        ApiClient.getClient().create(ApiInterface.class);
                Call<ContactsResponse> call = apiService.contactExists(phoneNumber, userId);
                call.enqueue(new Callback<ContactsResponse>() {
                    @Override
                    public void onResponse(Call<ContactsResponse> call, retrofit2.Response<ContactsResponse> response) {
                        Log.e(TAG, "abc");
                    }
                    @Override
                    public void onFailure(Call<ContactsResponse> call, Throwable t) {
                        Log.e(TAG, t.toString());
                    }
                });
            }
        }
    }
     if (phones != null) {
         phones.close();
     }
   }
}

This is one of the solutions I tried (edited register activity from above) based on this example, but it did not work unless I accepted both, and if I declined any or both of them I wasn't able to register. My edited RegisterActivity now looks like this:

registerButton.setOnClickListener(v -> {

        RequestMultiplePermission();
    });

    loginLink.setOnClickListener(v -> {
        finish();
    });

    checkBoxShowPassword = findViewById(R.id.checkBoxShowPassword);
    checkBoxShowPassword.setOnCheckedChangeListener((buttonView, isChecked) -> {
        if (!isChecked) {
            passwordText.setTransformationMethod(PasswordTransformationMethod.getInstance());
        } else {
            passwordText.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
        }
    });
}
private void RequestMultiplePermission() {

    ActivityCompat.requestPermissions(registerActivity, new String[]
            {
                    Manifest.permission.READ_PHONE_STATE,
                    Manifest.permission.READ_CONTACTS
            }, RequestPermissionCode);

}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case RequestPermissionCode:
            String name = nameText.getText().toString().trim();
            String email = emailText.getText().toString().trim();
            String password = passwordText.getText().toString().trim();
            String phone = getMyPhoneNumber();

            if (grantResults.length > 0) {
                boolean PhoneStatePermission = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                boolean ContactsPermission = grantResults[1] == PackageManager.PERMISSION_GRANTED;

                if (PhoneStatePermission && ContactsPermission) {
                    register(name, email, password, phone, true);
                } else if (!PhoneStatePermission && ContactsPermission) {
                    register(name, email, password, "", true);
                } else if (!ContactsPermission && PhoneStatePermission) {
                    register(name, email, password, phone, false);
                } else {
                    register(name, email, password, "", false);
                }
            }
            break;
    }
}

public boolean CheckingPermissionIsEnabledOrNot() {
    int FirstPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_PHONE_STATE);
    int SecondPermissionResult = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_CONTACTS);
    return FirstPermissionResult == PackageManager.PERMISSION_GRANTED &&
            SecondPermissionResult == PackageManager.PERMISSION_GRANTED;
}

private String getMyPhoneNumber() {
    TelephonyManager tMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

    String simCountry = null;
    if (tMgr != null) {
        simCountry = tMgr.getSimCountryIso().toUpperCase();
    }
    if (tMgr != null) {
        String simOperatorCode = tMgr.getSimOperator();
    }
    if (tMgr != null) {
        String simOperatorName = tMgr.getSimOperatorName();
    }
    RequestMultiplePermission();
...

What would be the best way to return the result of the combined allowed and declined permissions.

Banana
  • 2,435
  • 7
  • 34
  • 60
  • _"I wasn't able to register"_ Could you eloborate on what that means? Have you tried logging what happens in `onRequestPermissionsResult`? Btw, there's no need to make `ContactsPermission` part of the `if`-expression; you can simply pass it as the 4th argument to `register`. – Michael Jan 05 '18 at 09:20
  • @Michael I did not post the log, I will add it when I get home :) , and as far as the if statement is concerned, this is the first variation, I changed it to one line after this was posted :) – Banana Jan 05 '18 at 09:48

1 Answers1

0

I found a solution:

// define global variable for contacts permission
private static Boolean contactsGranted = false;
...
registerButton.setOnClickListener(v -> {
        String name = nameText.getText().toString().trim();
        String email = emailText.getText().toString().trim();
        String password = passwordText.getText().toString().trim();
});
...
 private void CheckContacts(String name, String email, String password) {
    if (ContextCompat.checkSelfPermission(registerActivity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(registerActivity, Manifest.permission.READ_CONTACTS)) {
            if (!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
                // contacts permission is not granted, check phone permission
                contactsGranted = false;
                CheckPhone(name, email, password);
            } else {
                Toast.makeText(getApplicationContext(), R.string.please_enter_credentials, Toast.LENGTH_LONG).show();
            }
        } else {
            ActivityCompat.requestPermissions(registerActivity, new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
        }
    } else {
        if (!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
            // contacts permission is granted, check phone permission
            contactsGranted = true;
            CheckPhone(name, email, password);
        } else {
            Toast.makeText(getApplicationContext(), R.string.please_enter_credentials, Toast.LENGTH_LONG).show();
        }
    }
}

private void CheckPhone(String name, String email, String password) {
    if (ContextCompat.checkSelfPermission(registerActivity, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(registerActivity, Manifest.permission.READ_PHONE_STATE)) {
            // phone permission is not granted, call register and pass empty phone string
            register(name, email, password, "");
        } else {
            ActivityCompat.requestPermissions(registerActivity, new String[]{Manifest.permission.READ_PHONE_STATE}, MY_PERMISSIONS_REQUEST_READ_PHONE);
        }
    } else {
        // phone permission is granted, call register and pass empty getMyPhoneNumber
        register(name, email, password, getMyPhoneNumber());
    }
}
...
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {

    String email = emailText.getText().toString().trim();
    String password = passwordText.getText().toString().trim();
    String name = nameText.getText().toString().trim();

    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS:
            // 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.
                if (!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
                    // contacts permission is granted, check phone permission
                    contactsGranted = true;
                    CheckPhone(name, email, password);
                } else {
                    // Prompt user to enter credentials
                    Toast.makeText(getApplicationContext(), R.string.please_enter_credentials, Toast.LENGTH_LONG).show();
                // permission denied, boo! Disable the
                // functionality that depends on this
                if (!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
                    // contacts permission is not granted, check phone permission
                    contactsGranted = false;
                    CheckPhone(name, email, password);
                } else {
                    // Prompt user to enter credentials
                    Toast.makeText(getApplicationContext(), R.string.please_enter_credentials, Toast.LENGTH_LONG).show();
                }
            }
            break;
        case MY_PERMISSIONS_REQUEST_READ_PHONE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // phone permission is granted, call register and pass empty getMyPhoneNumber
                register(name, email, password, getMyPhoneNumber());
            } else {
                // phone permission is not granted, call register and pass empty phone string
                register(name, email, password, "");
            }
            break;
    }
}
...
// Register
public void register(final String name, final String email, final String password, final String phone) {
...
if (contactsGranted) {
   updateContacts();
}

Hope it helps someone else.

Banana
  • 2,435
  • 7
  • 34
  • 60