Android Marshmallow 6.0 final stable version is released in October 2015. Android Marshmallow brought some new API changes and one of the most important API change is the addition of new granular permissions. Below is the type of permissions required for Marshmallow Devices:
In Marshmallow these dangerous permissions should be granted at run time and the normal permissions are granted automatically. For Lollipop (API level 22) or lower android versions the permissions specified in manifest are granted at installation.
Due to this permissions now no more popup dialog of permissions while installing app from Play Store. The permissions will be asked manually during run time via asking user to allow or deny the permissions. Below is the type of permissions dialog:
You can navigate to App Info and go to Permission option to revoke back and grant access the permissions manually.
In this tutorial, we are going to learn how to check if the permission is already granted and if not granted how to grant permissions.
1. Create a new project in Android Studio by navigating to File ⇒ New ⇒ New Project and fill required details. By default my activity is MainActivity.java.
2. Open strings.xml located under res=>values folder and add following strings.
1 2 3 4 5 6 7 8 9 10 11 |
<resources> <string name="app_name">MarshMallow Permissions Demo</string> <string name="hello_world">Hello world!</string> <string name="action_settings">Settings</string> <string name="storage">Storage</string> <string name="sms">SMS</string> <string name="contacts">Contacts</string> <string name="location">Location</string> <string name="title">Click below buttons to allow permissions…</string> </resources> |
3.Create activity_main.xml and add the following code. In this xml file add the button to access permission.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="fill_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:elevation="5dp" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="10dp" android:text="@string/title" android:textColor="@android:color/black" android:textSize="15sp" /> <Button android:id="@+id/access_location_permission" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="7dp" android:onClick="allowLocationPermission" android:text="@string/location" android:textColor="@android:color/black" android:textSize="15sp" /> <Button android:id="@+id/access_contacts_permission" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="allowContactsPermission" android:text="@string/contacts" android:textColor="@android:color/black" android:textSize="15sp" /> <Button android:id="@+id/access_sms_permission" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="allowSmsPermission" android:text="@string/sms" android:textColor="@android:color/black" android:textSize="15sp" /> <Button android:id="@+id/access_storage_permission" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="allowStoragePermission" android:text="@string/storage" android:textColor="@android:color/black" android:textSize="15sp" /> </LinearLayout> |
4. Now open your AndroidManifest.xml and add the following permission for Pre-Marshmallow Devices.
1 2 3 4 5 |
<!-- Permissions for Devices below Marshmallow Versions --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
5. Now to access permission for Marshmallow Devices below are some steps to do it:
1 2 3 4 5 6 |
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) MarshMallowPermission.requestLocationPermission(MainActivity.this); else Toast.makeText(MainActivity.this, "Permission is already granted.", Toast.LENGTH_SHORT).show(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.ACCESS_FINE_LOCATION)) { // Provide an additional rationale to the user if the permission was not granted // and the user would benefit from additional context for the use of the permission. // For example if the user has previously denied the permission. ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MarshmallowIntentId.ACCESS_FINE_LOCATION_INTENT_ID); } else { // permission has not been granted yet. Request it directly. ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MarshmallowIntentId.ACCESS_FINE_LOCATION_INTENT_ID); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case MarshmallowIntentId.ACCESS_FINE_LOCATION_INTENT_ID: // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // task you need to do. Toast.makeText(MainActivity.this, "Location Permission granted.", Toast.LENGTH_SHORT).show(); } else { // permission denied, boo! Disable the // functionality that depends on this permission. Toast.makeText(MainActivity.this, "Location Permission denied.", Toast.LENGTH_SHORT).show(); } break; } } |
6. For Permission Intent Id’s we have created a class naming MarshmallowIntentId.java and put all Intent Id into it and access from here only.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.marshmallow_permissions_demo; /** * Created by SONU on 01/03/16. */ public class MarshmallowIntentId { //Intent id's for Marshmallow Permissions public static final int WRITE_EXTERNAL_STORAGE_PERMISSION = 1; public static final int READ_SMS_INTENT_ID = 2; public static final int ACCESS_FINE_LOCATION_INTENT_ID = 3; public static final int ACCESS_CONTACTS_INTENT_ID = 4; } |
7. Now to ask permission to user we have to create a class naming MarshmallowPermission.java and add all required permission methods into it and call it whenever we require.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
package com.marshmallow_permissions_demo; import android.Manifest; import android.app.Activity; import android.content.Context; import android.support.v4.app.ActivityCompat; /** * Created by SONU on 13/01/16. */ public class MarshMallowPermission { public static void requestStoragePermission(final Context context) { if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { // Provide an additional rationale to the user if the permission was not granted // and the user would benefit from additional context for the use of the permission. // For example if the user has previously denied the permission. ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MarshmallowIntentId.WRITE_EXTERNAL_STORAGE_PERMISSION); } else { // permission has not been granted yet. Request it directly. ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MarshmallowIntentId.WRITE_EXTERNAL_STORAGE_PERMISSION); } } public static void requestReadSMSPermission(final Context context) { if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.READ_SMS)) { // Provide an additional rationale to the user if the permission was not granted // and the user would benefit from additional context for the use of the permission. // For example if the user has previously denied the permission. ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_SMS}, MarshmallowIntentId.READ_SMS_INTENT_ID); } else { // permission has not been granted yet. Request it directly. ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_SMS}, MarshmallowIntentId.READ_SMS_INTENT_ID); } } public static void requestLocationPermission(final Context context) { if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.ACCESS_FINE_LOCATION)) { // Provide an additional rationale to the user if the permission was not granted // and the user would benefit from additional context for the use of the permission. // For example if the user has previously denied the permission. ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MarshmallowIntentId.ACCESS_FINE_LOCATION_INTENT_ID); } else { // permission has not been granted yet. Request it directly. ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MarshmallowIntentId.ACCESS_FINE_LOCATION_INTENT_ID); } } public static void requestContactsPermission(final Context context) { if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.READ_CONTACTS)) { // Provide an additional rationale to the user if the permission was not granted // and the user would benefit from additional context for the use of the permission. // For example if the user has previously denied the permission. ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_CONTACTS}, MarshmallowIntentId.ACCESS_CONTACTS_INTENT_ID); } else { // permission has not been granted yet. Request it directly. ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_CONTACTS}, MarshmallowIntentId.ACCESS_CONTACTS_INTENT_ID); } } } |
8. Finally create MainActivity.java and add the following code. In this class we need to check the permission is granted or not on button click and grant permission if not granted.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
package com.marshmallow_permissions_demo; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.Toast; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setUpToolbar(); } //set up toolbar private void setUpToolbar() { Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); } public void allowLocationPermission(View view) { //Check if permission is granted or not if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) MarshMallowPermission.requestLocationPermission(MainActivity.this); else Toast.makeText(MainActivity.this, "Permission is already granted.", Toast.LENGTH_SHORT).show(); } public void allowStoragePermission(View view) { //Check if permission is granted or not if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) MarshMallowPermission.requestStoragePermission(MainActivity.this); else Toast.makeText(MainActivity.this, "Permission is already granted.", Toast.LENGTH_SHORT).show(); } public void allowSmsPermission(View view) { //Check if permission is granted or not if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) MarshMallowPermission.requestReadSMSPermission(MainActivity.this); else Toast.makeText(MainActivity.this, "Permission is already granted.", Toast.LENGTH_SHORT).show(); } public void allowContactsPermission(View view) { //Check if permission is granted or not if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) MarshMallowPermission.requestContactsPermission(MainActivity.this); else Toast.makeText(MainActivity.this, "Permission is already granted.", Toast.LENGTH_SHORT).show(); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case MarshmallowIntentId.ACCESS_FINE_LOCATION_INTENT_ID: // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // task you need to do. Toast.makeText(MainActivity.this, "Location Permission granted.", Toast.LENGTH_SHORT).show(); } else { // permission denied, boo! Disable the // functionality that depends on this permission. Toast.makeText(MainActivity.this, "Location Permission denied.", Toast.LENGTH_SHORT).show(); } break; case MarshmallowIntentId.ACCESS_CONTACTS_INTENT_ID: // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // task you need to do. Toast.makeText(MainActivity.this, "Contact Permission granted.", Toast.LENGTH_SHORT).show(); } else { // permission denied, boo! Disable the // functionality that depends on this permission. Toast.makeText(MainActivity.this, "Contact Permission denied.", Toast.LENGTH_SHORT).show(); } break; case MarshmallowIntentId.READ_SMS_INTENT_ID: // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // task you need to do. Toast.makeText(MainActivity.this, "SMS Permission granted.", Toast.LENGTH_SHORT).show(); } else { // permission denied, boo! Disable the // functionality that depends on this permission. Toast.makeText(MainActivity.this, "SMS Permission denied.", Toast.LENGTH_SHORT).show(); } break; case MarshmallowIntentId.WRITE_EXTERNAL_STORAGE_PERMISSION: // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // task you need to do. Toast.makeText(MainActivity.this, "Storage Permission granted.", Toast.LENGTH_SHORT).show(); } else { // permission denied, boo! Disable the // functionality that depends on this permission. Toast.makeText(MainActivity.this, "Storage Permission denied.", Toast.LENGTH_SHORT).show(); } break; } } } |
9. Finally, all done – now you can also add permissions to your app on run time.
Thanks. 🙂
Subscribe to us and get the latest news.
3 Comments
Jagdish
Tuesday, October 10th, 2017Thanks Dr. Droid. Very very helpful !!!
thomas
Tuesday, August 7th, 2018Which permission would I need to set for screenshots?
Where do I put the step:
Check if Permission is already granted : Lets check permission for ACCESS_FINE_LOCATION, if permission is granted then it will display toast else it will ask user to Allow or Deny the Location permission.
Dr. Droid
Wednesday, August 8th, 2018Hi Thomas,
You will be needing WRITE_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions. If permission is granted then take screenshot else ask user to allow/deny.
Make sure you also put uses_permission in AndroidManifest.xml too.
Thanks