Supplementary MyRent lab to demonstrate how to request permissions at run time. We restrict ourselves to the single permission READ_CONTACTS.
All of these changes will take place in the ResidenceActivity class.
Introduce a new field for the intent data.
// This field is initialized in `onActivityResult`.
private Intent data;
This field is required to provide us with access to the data intent outside the method onActivityResult
.
The existing code in onActivityResult is:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch (requestCode)
{
case REQUEST_CONTACT:
String name = getContact(this, data);
emailAddress = getEmail(this, data);
tenantButton.setText(name + " : " + emailAddress);
residence.tenant = name;
break;
}
}
As we will be adding permission checks prior reading the contact details, we will farm the reading of the contact details into this new private method:
private void readContact() {
String name = getContact(this, data);
emailAddress = getEmail(this, data);
tenantButton.setText(name + " : " + emailAddress);
residence.tenant = name;
}
Next we will refactor the REQUEST_CONTACT case to this:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CONTACT:
this.data = data;
checkContactsReadPermission();
break;
}
}
We need to create a new method called checkContactsReadPermission(). This method will check if the app has permission to read the contact details:
//https://developer.android.com/training/permissions/requesting.html
private void checkContactsReadPermission() {
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
//We can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_CONTACT);
}
else {
//We already have permission, so go head and read the contact
readContact();
}
}
When the user responds to the dialog box (allow or deny), the system invokes the app's onRequestPermissionsResult() method, passing in the user response. Include this method in your class:
//https://developer.android.com/training/permissions/requesting.html
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CONTACT: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted
readContact();
}
}
}
}
Note that, if permission is granted, the readContact method is called, otherwise it is ignored.
Use ALT+Enter to include the necessary imports.
Open your emulator and go into the settings for your emulator.
We are going to turn off permission to our contacts for the MyRent app.
If your contact permission is on for MyRent, turn it off here.
Launch your MyRent app, add a new residence and then try to add a prospective tenant. The contacts list will be shown, but when you try to select one, you should see this dialog box appear:
Choose the Deny option and you should be returned to the residence you created above. No email/contact details should be shown and the button text should remain as "Prospective Tenant".
Now try to add a prospective tenant again but this time choose the Allow option. You should be returned to your residence activity and the email should be displayed for the user.
Return to the settings for the App and you should now see that the permission has now been set to "Allow" for the contact details.
The application at the end of this lab is available for download from GitHub: android-myrent-2017
Select Releases, followed by V6.0.