Runtime permissions
Here I am showing only for read contact permission.
Android 6.0 M, application will not be accepted any permission at installation time.
Apps may request permission to access information or use device capabilities at any time after installation. When a user needs to perform an action in an app, such as using the device camera, the app may request permission at that moment.
Users may also allow or deny the permissions of any app from Android Settings anytime after installation.
Android's permission system is one of the biggest security concern all along since those permissions are asked for at install time.
How to make your application support new Runtime Permission.
Set you android application compileSdkVersion and targetSdkVersion to 23. For that use below line
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
minSdkVersion 15
targetSdkVersion 23
}
Add a permission into AndroidManifest.xml
<uses-permission android:name="android.permission.READ_CONTACTS" />
Read Contact Permission:
If permission has already been granted,
showContactDetails will be suddenly called. Otherwise launch a permission request dialog like below.
In order to check permission before going to read contacts -
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.readContactBtn:
requestContactsPermission();
break;
}
}
Once user click on button
readContact will be called then it will check permission granted or not.
public void requestContactsPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
before = ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_CONTACTS);
if (before) {
showMessageOKCancel("You need to allow access to Contacts",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(RuntimePermission.this, PERMISSIONS_READ_CONTACT, REQUEST_CONTACTS);
}
});
return;
} else {
Log.d("this is else block", "Block Number");
ActivityCompat.requestPermissions(this, PERMISSIONS_READ_CONTACT, REQUEST_CONTACTS);
return;
}
}
showContactDetails();
}
// show message dialog when user deny permission
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(RuntimePermission.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
Once user select ALLOW or DENY
onRequestPermissionsResult will always be called to inform a result which we can check from the 3rd parameter, grantResults:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_CONTACTS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
showContactDetails();
} else {
// Permission Denied
Toast.makeText(RuntimePermission.this, "READ_CONTACTS Denied", Toast.LENGTH_SHORT).show();
after = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS);
boolean goToSettings = !(after || before);
if (goToSettings)
openApplicationInfoSetting();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
//open application setting screen for enabling permission
private void openApplicationInfoSetting() {
new AlertDialog.Builder(RuntimePermission.this)
.setMessage("Allow App access to your contact. \n\nTo enable this, click App settings Below and activate Contact under the permission menu.")
.setPositiveButton("APP SETTINGS", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.parse("package:" + getPackageName());
intent.setData(uri);
startActivity(intent);
}
})
.setNegativeButton("NOT NOW", null)
.create()
.show();
}
let's explain about
shouldShowRequestPermissionRationale() method return value.
Step 1-When it will return
true
- If the app has requested this permission previously and the user denied the request.
Step 2-When it will return
false
- The app didn't request for this permission yet.
- If the app has requested this permission previously and the user denied the request with Don't ask again.
- If a device policy prohibits the app from having that permission
In the same way you can check permission for writing contacts(insert contact).
MainActivity.java
package com.demo.test.readcontactruntimepermission;
import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
public class RuntimePermission extends AppCompatActivity implements View.OnClickListener {
private static String[] PERMISSIONS_READ_CONTACT = {Manifest.permission.READ_CONTACTS};
private static final int REQUEST_CONTACTS = 11;
boolean before, after;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_runtime_permission);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.readContactBtn:
requestContactsPermission();
break;
}
}
public void requestContactsPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
//
before = ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.READ_CONTACTS);
if (before) {
showMessageOKCancel("You need to allow access to Contacts",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(RuntimePermission.this, PERMISSIONS_READ_CONTACT, REQUEST_CONTACTS);
}
});
return;
} else {
Log.d("this is else block", "Block Number");
ActivityCompat.requestPermissions(this, PERMISSIONS_READ_CONTACT, REQUEST_CONTACTS);
return;
}
}
showContactDetails();
}
//open application setting screen for enabling permission
private void openApplicationInfoSetting() {
new AlertDialog.Builder(RuntimePermission.this)
.setMessage("Allow App access to your contact. \n\nTo enable this, click App settings Below and activate Contact under the permission menu.")
.setPositiveButton("APP SETTINGS", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.parse("package:" + getPackageName());
intent.setData(uri);
startActivity(intent);
}
})
.setNegativeButton("NOT NOW", null)
.create()
.show();
}
// show message dialog when user deny permission
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(RuntimePermission.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
private void showContactDetails() {
Log.i("CONTACT",
"Going to read contact");
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_CONTACTS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission Granted
showContactDetails();
} else {
// Permission Denied
Toast.makeText(RuntimePermission.this, "READ_CONTACTS Denied", Toast.LENGTH_SHORT).show();
after = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS);
boolean goToSettings = !(after || before);
if (goToSettings)
openApplicationInfoSetting();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}