Contact list & Email support

Supplementary MyRent lab to demonstrate how to request permissions at run time. We restrict ourselves to the single permission READ_CONTACTS.

ResidenceActivity

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:

  • If it does have permission, the readContact() method will be called
  • If it doesn't, it will request the permission via a pop-up dialog box. The user can choose to Allow or Deny access.
    //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.

Testing Permissions

Open your emulator and go into the settings for your emulator.

Figure 1: Settings on your emulator

We are going to turn off permission to our contacts for the MyRent app.

Figure 2: Settings -> Apps - > MyRent

If your contact permission is on for MyRent, turn it off here.

Figure 3: Settings -> Apps - > MyRent: Turn off contact list permission

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:

Figure 4: Dialog Box requesting permission to access the contact details

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.

Figure 4: MyRent is allowed to access 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.