Permission Model In Android Marshmallow Using READ_CONTACTS Permission

Introduction

 
Android Marshmallow is the most recent version for users launched by Google. A wide variety of changes have been done to the Lollipop(5.0 and 5.1) versions of Android. One change is called permission model changes, i.e., initially, all the app permissions were static, that is at install time, and now in the Marshmallow version of Android, it has changed to Run time. In the midst of running application, it requires the user to provide permission to access particular parts and services that app wants to use, for example, "Camera permission" while your app wants to use a camera and "location access" and reading and "access to the Contacts" and much more.
 

Types of Permissions

 
There are two types of permission in android as in the following:
  • Normal Permission
  • Dangerous Permission

Normal Permissions

 
The Permission is normal in nature; the app needs to access data or resources outside the app's sandbox that does not access the user's private things and there is very little risk of user information on others' apps is called normal permissions.
 
Examples are permission to set the time zone, Access Network State, Bluetooth and much more.
 

Dangerous Permissions

 
The permissions are said to be dangerous in which an app needs to access data that is private to the user and there is a risk of user's privacy and could produce the damage to stored data of the user in the phone and other apps are called dangerous permission.
 
Examples are Reading the contacts of the user, Access the fine location, camera permission, and much more.
 
Let's take one of the dangerous permissions to illustrates the permission model in Marshmallow that is READ_CONTACTS. Let's have a project in which we have take the MainActivity in which we will fetch Contacts of the user.
 
AndroidManifest.xml
 
First declare permission to access and read user Contacts as shown in code below:
  1. <?xml version="1.0" encoding="utf-8"?>    
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"    
  3.     package="com.example.gkumar.readcontactsapp">    
  4.     <uses-permission android:name="android.permission.READ_CONTACTS" />    
  5.     
  6.     <application    
  7.         android:allowBackup="true"    
  8.         android:icon="@mipmap/ic_launcher"    
  9.         android:label="@string/app_name"    
  10.         android:supportsRtl="true"    
  11.         android:theme="@style/AppTheme">    
  12.         <activity android:name=".MainActivity">    
  13.             <intent-filter>    
  14.                 <action android:name="android.intent.action.MAIN" />    
  15.     
  16.                 <category android:name="android.intent.category.LAUNCHER" />    
  17.             </intent-filter>    
  18.         </activity>    
  19.     </application>    
  20.     
  21. </manifest>   
    MainActivity.java
     
    All the logic and procedure to fetch stored data means to fetch contacts. In this code, I have written code to fetch three fields like name, phone no., and even email. You can see the loops just to find these three fields by making queries via contentResolver object and collecting data in the cursor form.
     
    activity_main.xml
    1. package com.example.gkumar.readcontactsapp;        
    2.         
    3. import android.Manifest;        
    4. import android.content.ContentResolver;        
    5. import android.content.DialogInterface;        
    6. import android.content.pm.PackageManager;        
    7. import android.database.Cursor;        
    8. import android.net.Uri;        
    9. import android.os.Build;        
    10. import android.provider.ContactsContract;        
    11. import android.support.v4.app.ActivityCompat;        
    12. import android.support.v4.content.ContextCompat;        
    13. import android.support.v7.app.AlertDialog;        
    14. import android.support.v7.app.AppCompatActivity;        
    15. import android.os.Bundle;        
    16. import android.util.Log;        
    17. import android.view.Gravity;        
    18. import android.widget.TextView;        
    19.         
    20. public class MainActivity extends AppCompatActivity {        
    21.         
    22.     private TextView contactTextView;        
    23.     public static final int REQUEST_READ_CONTACTS = 79;        
    24.     @Override        
    25.     protected void onCreate(Bundle savedInstanceState) {        
    26.         super.onCreate(savedInstanceState);        
    27.         setContentView(R.layout.activity_main);        
    28.         contactTextView = (TextView)findViewById(R.id.textView);        
    29.         
    30.         if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_CONTACTS)        
    31.                 == PackageManager.PERMISSION_GRANTED) {        
    32.             getContacts();        
    33.         } else {        
    34.             requestLocationPermission();        
    35.         }        
    36.         
    37.     }        
    38.     protected void requestLocationPermission() {        
    39.         if (ActivityCompat.shouldShowRequestPermissionRationale(this,        
    40.                 android.Manifest.permission.READ_CONTACTS)) {        
    41.            // show UI part if you want here to show some rationale !!!        
    42.         
    43.         } else {        
    44.         
    45.             ActivityCompat.requestPermissions(thisnew String[]{android.Manifest.permission.READ_CONTACTS},        
    46.                     REQUEST_READ_CONTACTS);        
    47.         }        
    48.         
    49.     }        
    50.         
    51.     @Override        
    52.     public void onRequestPermissionsResult(int requestCode,        
    53.                                            String permissions[], int[] grantResults) {        
    54.         switch (requestCode) {        
    55.             case REQUEST_READ_CONTACTS: {        
    56.         
    57.                 if (grantResults.length > 0        
    58.                         && grantResults[0] == PackageManager.PERMISSION_GRANTED) {        
    59.         
    60.                     getContacts();        
    61.         
    62.                 } else {        
    63.         
    64.                     // permission denied,Disable the        
    65.                     // functionality that depends on this permission.        
    66.                 }        
    67.                 return;        
    68.             }        
    69.         
    70.         }        
    71.     }        
    72.         
    73.     public void getContacts() {        
    74.         
    75.         String phoneNumber = null;        
    76.         String email = null;        
    77.         
    78.         Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;        
    79.         String _ID = ContactsContract.Contacts._ID;        
    80.         String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;        
    81.         String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;        
    82.         
    83.         Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;        
    84.         String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;        
    85.         String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;        
    86.         
    87.         Uri EmailCONTENT_URI =  ContactsContract.CommonDataKinds.Email.CONTENT_URI;        
    88.         String EmailCONTACT_ID = ContactsContract.CommonDataKinds.Email.CONTACT_ID;        
    89.         String DATA = ContactsContract.CommonDataKinds.Email.DATA;        
    90.         
    91.         StringBuffer output = new StringBuffer();        
    92.         
    93.         ContentResolver contentResolver = getContentResolver();        
    94.         
    95.         Cursor cursor = contentResolver.query(CONTENT_URI, null,nullnullnull);        
    96.         
    97.         // Loop for every contact in the phone        
    98.         if (cursor.getCount() > 0) {        
    99.         
    100.             while (cursor.moveToNext()) {        
    101.         
    102.                 String contact_id = cursor.getString(cursor.getColumnIndex( _ID ));        
    103.                 String name = cursor.getString(cursor.getColumnIndex( DISPLAY_NAME ));        
    104.         
    105.                 int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex( HAS_PHONE_NUMBER )));        
    106.         
    107.                 if (hasPhoneNumber > 0) {        
    108.         
    109.                     output.append("\n First Name:" + name);        
    110.         
    111.                     // Query and loop for every phone number of the contact        
    112.         
    113.                     Cursor phoneCursor = contentResolver.query(PhoneCONTENT_URI, null, Phone_CONTACT_ID + " = ?"new String[] { contact_id }, null);        
    114.         
    115.                     while (phoneCursor.moveToNext()) {        
    116.                         phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));        
    117.                         output.append("\n Phone number:" + phoneNumber);        
    118.         
    119.                     }        
    120.         
    121.                     phoneCursor.close();        
    122.         
    123.                     // Query and loop for every email of the contact        
    124.                     Cursor emailCursor = contentResolver.query(EmailCONTENT_URI,    null, EmailCONTACT_ID+ " = ?"new String[] { contact_id }, null);        
    125.         
    126.                     while (emailCursor.moveToNext()) {        
    127.         
    128.                         email = emailCursor.getString(emailCursor.getColumnIndex(DATA));        
    129.         
    130.                         output.append("\nEmail:" + email);        
    131.         
    132.                     }        
    133.         
    134.                     emailCursor.close();        
    135.                 }        
    136.         
    137.                 output.append("\n");        
    138.             }        
    139.         
    140.             contactTextView.setText(output.toString());        
    141.         }        
    142.     }        
    143. }      
    We have taken only a text view just to set contacts as shown below:
    1. <?xml version="1.0" encoding="utf-8"?>    
    2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    
    3.     xmlns:tools="http://schemas.android.com/tools"    
    4.     android:layout_width="match_parent"    
    5.     android:layout_height="match_parent"    
    6.     tools:context="com.example.gkumar.readcontactsapp.MainActivity">    
    7.     
    8.     <TextView    
    9.         android:id="@+id/textView"    
    10.         android:layout_width="wrap_content"    
    11.         android:layout_height="wrap_content"    
    12.         android:layout_alignParentLeft="true"    
    13.         android:layout_alignParentRight="true"    
    14.         android:layout_alignParentTop="true"    
    15.         android:layout_margin="10dp"    
    16.         android:textSize="16sp"    
    17.         android:gravity="center"    
    18.         android:text="Contacts Information" />    
    19.     
    20. </RelativeLayout>   
    Running the Application
     
    Running it in Marshmallow we can see that it is asking for permission to Read the Contacts. If you deny nothing happens and contacts will not be seen.
     
    If you grant permission then it will take a while to fetch and show the contacts to the screen as shown below.
     
     
    After clicking on allow, that is granting the permission, now it is fetching contacts it might take a while to get data.
     
     
    We can see that all three things like name, phone no., and email have been fetched. It is showing one record because I have only one phone number in my contacts and phone.
     

    Summary

     
    In this article, we just see the Implementation of the Permission Model via fetching and READ_CONTACTS contacts data. We have Implemented the Runtime permission that is dangerous by nature.
     
    Read more articles on Android: