First i will give you Dangerous Permission List in Android M and Later version
Then give you example of how to request for permission in Android M and later version.
I ask user to WRITE_EXTERNAL_STORAGE permission.
First add permission in your android menifest file
Step 1 Declare requestcode
private static String TAG = "PermissionDemo";
private static final int REQUEST_WRITE_STORAGE = 112;
Step 2 Add this code when you want ask user for permission
//ask for the permission in android M
int permission = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission to record denied");
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Permission to access the SD-CARD is required for this app to Download PDF.")
.setTitle("Permission required");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Log.i(TAG, "Clicked");
makeRequest();
}
});
AlertDialog dialog = builder.create();
dialog.show();
} else {
makeRequest();
}
}
protected void makeRequest() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_WRITE_STORAGE);
}
Step 3 Add override method for Request
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_WRITE_STORAGE: {
if (grantResults.length == 0
|| grantResults[0] !=
PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission has been denied by user");
} else {
Log.i(TAG, "Permission has been granted by user");
}
return;
}
}
}
Note: Do not forget to add permission in menifest file
BEST EXAMPLE BELOW WITH MULTIPLE PERMISSION PLUS COVER ALL SCENARIO
I added comments so you can easily understand.
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
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.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.production.hometech.busycoder.R;
import java.util.ArrayList;
public class PermissionInActivity extends AppCompatActivity implements View.OnClickListener {
private static final int REQUEST_PERMISSION_SETTING = 99;
private Button bt_camera;
private static final String[] PARAMS_TAKE_PHOTO = {
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private static final int RESULT_PARAMS_TAKE_PHOTO = 11;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_permission_in);
bt_camera = (Button) findViewById(R.id.bt_camera);
bt_camera.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt_camera:
takePhoto();
break;
}
}
/**
* shouldShowRequestPermissionRationale() = This will return true if the user had previously declined to grant you permission
* NOTE : that ActivityCompat also has a backwards-compatible implementation of
* shouldShowRequestPermissionRationale(), so you can avoid your own API level
* checks.
* <p>
* shouldShowRequestPermissionRationale() = returns false if the user declined the permission and checked the checkbox to ask you to stop pestering the
* user.
* <p>
* requestPermissions() = request for the permisssiion
*/
private void takePhoto() {
if (canTakePhoto()) {
Toast.makeText(this, "You can take PHOTO", Toast.LENGTH_SHORT).show();
} else if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(this, "You should give permission", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this, netPermisssion(PARAMS_TAKE_PHOTO), RESULT_PARAMS_TAKE_PHOTO);
} else {
ActivityCompat.requestPermissions(this, netPermisssion(PARAMS_TAKE_PHOTO), RESULT_PARAMS_TAKE_PHOTO);
}
}
// This method return permission denied String[] so we can request again
private String[] netPermisssion(String[] wantedPermissions) {
ArrayList<String> result = new ArrayList<>();
for (String permission : wantedPermissions) {
if (!hasPermission(permission)) {
result.add(permission);
}
}
return (result.toArray(new String[result.size()]));
}
private boolean canTakePhoto() {
return (hasPermission(Manifest.permission.CAMERA) && hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
}
/**
* checkSelfPermission() = you can check if you have been granted a runtime permission or not
* ex = ContextCompat.checkSelfPermission(this,permissionString)== PackageManager.PERMISSION_GRANTED
* <p>
* ContextCompat offers a backwards-compatible implementation of checkSelfPermission(), ActivityCompat offers a backwards-compatible
* implementation of requestPermissions() that you can use.
*
* @param permissionString
* @return
*/
private boolean hasPermission(String permissionString) {
return (ContextCompat.checkSelfPermission(this, permissionString) == PackageManager.PERMISSION_GRANTED);
}
/**
* requestPermissions() action goes to onRequestPermissionsResult() whether user can GARNT or DENIED those permisssions
*
* @param requestCode
* @param permissions
* @param grantResults
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == RESULT_PARAMS_TAKE_PHOTO) {
if (canTakePhoto()) {
Toast.makeText(this, "You can take picture", Toast.LENGTH_SHORT).show();
} else if (!(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE))) {
final AlertDialog.Builder settingDialog = new AlertDialog.Builder(PermissionInActivity.this);
settingDialog.setTitle("Permissioin");
settingDialog.setMessage("Now you need to enable permisssion from the setting because without permission this app won't run properly \n\n goto -> setting -> appInfo");
settingDialog.setCancelable(false);
settingDialog.setPositiveButton("Setting", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
Toast.makeText(getBaseContext(), "Go to Permissions to Grant all permission ENABLE", Toast.LENGTH_LONG).show();
}
});
settingDialog.show();
Toast.makeText(this, "You need to grant permission from setting", Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_PERMISSION_SETTING) {
if (canTakePhoto()) {
Toast.makeText(this, "You can take PHOTO", Toast.LENGTH_SHORT).show();
}
}
}
}
Special Case for Configuration change
It is possible that the user will rotate the device or otherwise trigger a configuration change while our permission dialog is in the foreground. Since our activity is still visible behind that dialog, we get destroyed and recreated… but we do not want to re-raise the permission dialog again.
That is why we have a boolean, named isInPermission, that tracks whether or not
we are in the middle of requesting permissions. We hold onto that value in
onSaveInstanceState()
:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_IN_PERMISSION, isInPermission);
}
We restore it in onCreate()
. If we do not hold all of the desired permissions, but isInPermission is true, we skip requesting the permissions, since we are in the
middle of doing so already.
targetSdkVersion
23? Or an earlier version? – ianhanniballake