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) version 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 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 which are normal in nature; the app needs to access data or resources outside the app's sandbox that does not access user's private things and there is a very little risk of user information on others appsis  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 user and there is a risk of user's privacy and could produce the damage to stored data of user in phone and other apps is called dangerous permission.
Examples are : Reading the contacts of 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.
  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.   
  25.   
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.activity_main);  
  30.         contactTextView = (TextView)findViewById(R.id.textView);  
  31.   
  32.         if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.READ_CONTACTS)  
  33.                 == PackageManager.PERMISSION_GRANTED) {  
  34.             getContacts();  
  35.         } else {  
  36.             requestLocationPermission();  
  37.         }  
  38.   
  39.     }  
  40.     protected void requestLocationPermission() {  
  41.         if (ActivityCompat.shouldShowRequestPermissionRationale(this,  
  42.                 android.Manifest.permission.READ_CONTACTS)) {  
  43.            // show UI part if you want here to show some rationale !!!  
  44.   
  45.         } else {  
  46.   
  47.             ActivityCompat.requestPermissions(thisnew String[]{android.Manifest.permission.READ_CONTACTS},  
  48.                     REQUEST_READ_CONTACTS);  
  49.         }  
  50.   
  51.     }  
  52.   
  53.     @Override  
  54.     public void onRequestPermissionsResult(int requestCode,  
  55.                                            String permissions[], int[] grantResults) {  
  56.         switch (requestCode) {  
  57.             case REQUEST_READ_CONTACTS: {  
  58.   
  59.                 if (grantResults.length > 0  
  60.                         && grantResults[0] == PackageManager.PERMISSION_GRANTED) {  
  61.   
  62.                     getContacts();  
  63.   
  64.                 } else {  
  65.   
  66.                     // permission denied,Disable the  
  67.                     // functionality that depends on this permission.  
  68.                 }  
  69.                 return;  
  70.             }  
  71.   
  72.         }  
  73.     }  
  74.   
  75.     public void getContacts() {  
  76.   
  77.         String phoneNumber = null;  
  78.         String email = null;  
  79.   
  80.         Uri CONTENT_URI = ContactsContract.Contacts.CONTENT_URI;  
  81.         String _ID = ContactsContract.Contacts._ID;  
  82.         String DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME;  
  83.         String HAS_PHONE_NUMBER = ContactsContract.Contacts.HAS_PHONE_NUMBER;  
  84.   
  85.         Uri PhoneCONTENT_URI = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;  
  86.         String Phone_CONTACT_ID = ContactsContract.CommonDataKinds.Phone.CONTACT_ID;  
  87.         String NUMBER = ContactsContract.CommonDataKinds.Phone.NUMBER;  
  88.   
  89.         Uri EmailCONTENT_URI =  ContactsContract.CommonDataKinds.Email.CONTENT_URI;  
  90.         String EmailCONTACT_ID = ContactsContract.CommonDataKinds.Email.CONTACT_ID;  
  91.         String DATA = ContactsContract.CommonDataKinds.Email.DATA;  
  92.   
  93.         StringBuffer output = new StringBuffer();  
  94.   
  95.         ContentResolver contentResolver = getContentResolver();  
  96.   
  97.         Cursor cursor = contentResolver.query(CONTENT_URI, null,nullnullnull);  
  98.   
  99.         // Loop for every contact in the phone  
  100.         if (cursor.getCount() > 0) {  
  101.   
  102.             while (cursor.moveToNext()) {  
  103.   
  104.                 String contact_id = cursor.getString(cursor.getColumnIndex( _ID ));  
  105.                 String name = cursor.getString(cursor.getColumnIndex( DISPLAY_NAME ));  
  106.   
  107.                 int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex( HAS_PHONE_NUMBER )));  
  108.   
  109.                 if (hasPhoneNumber > 0) {  
  110.   
  111.                     output.append("\n First Name:" + name);  
  112.   
  113.                     // Query and loop for every phone number of the contact  
  114.   
  115.                     Cursor phoneCursor = contentResolver.query(PhoneCONTENT_URI, null, Phone_CONTACT_ID + " = ?"new String[] { contact_id }, null);  
  116.   
  117.                     while (phoneCursor.moveToNext()) {  
  118.                         phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(NUMBER));  
  119.                         output.append("\n Phone number:" + phoneNumber);  
  120.   
  121.                     }  
  122.   
  123.                     phoneCursor.close();  
  124.   
  125.                     // Query and loop for every email of the contact  
  126.                     Cursor emailCursor = contentResolver.query(EmailCONTENT_URI,    null, EmailCONTACT_ID+ " = ?"new String[] { contact_id }, null);  
  127.   
  128.                     while (emailCursor.moveToNext()) {  
  129.   
  130.                         email = emailCursor.getString(emailCursor.getColumnIndex(DATA));  
  131.   
  132.                         output.append("\nEmail:" + email);  
  133.   
  134.                     }  
  135.   
  136.                     emailCursor.close();  
  137.                 }  
  138.   
  139.                 output.append("\n");  
  140.             }  
  141.   
  142.             contactTextView.setText(output.toString());  
  143.         }  
  144.     }  
  145. }  
activity_main.xml

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

On 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 the 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 Implementation of 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:

 

Up Next
    Ebook Download
    View all
    Learn
    View all