如何为不同的多重权限Accept/Decline组合得到不同的结果

How to Get Different Results For Different Multiple Permissions Accept/Decline Combinations

我有一个带有寄存器 activity 的应用程序。当用户注册时,他被要求提供这两个权限:

用户应该能够接受或拒绝两者,或者接受一个而拒绝另一个。取决于我想要有 4 个不同的结果:

  1. 如果用户允许 READ_PHONE_STATE 并拒绝 READ_CONTACTS 结果应该是:register(name, email, password, getMyPhoneNumber(), false);
  2. 如果用户拒绝 READ_PHONE_STATE 并允许 READ_CONTACTS,结果应该是:register(name, email, password, "", true);
  3. 如果用户同时拒绝,结果应该是:register(name, email, password, "", false);
  4. 如果用户同时允许,结果应该是:register(name, email, password, getMyPhoneNumber(), true);

一段时间以来,我一直在尝试寻找一种允许这些组合的解决方案,尝试 , , , this, this 等等,但我找不到可行的解决方案。

这是我原来的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 示例尝试过的解决方案之一(从上面编辑了寄存器 activity),但它不起作用,除非我接受了两者,并且如果我拒绝了任何一个或两者其中我无法注册。我编辑的 RegisterActivity 现在看起来像这样:

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();
...

return 合并允许和拒绝权限的结果的最佳方法是什么。

我找到了解决方案:

// 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();
}

希望对其他人有所帮助。