I need to add the new permission things to an old project, which still has to stick to ant building. The following is the previous configuration:
project.properties:
target=android-23
AndroidManifest.xml:
<uses-sdk android:minSdkVersion="13" />
I changed AndroidManifest.xml to
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="23" />
but found that on my Android 6.0 phone it still warns me that my app is not compatible with the lastest Android permission requirements. And it behaves as if it really targets pre-23.
So is there any solutions?
I just share the code to add check for permissions, which has been made mandatory procedure since Marshnmallow. For instance, I check for permission to access camera.
private void launchCamera() {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(MyActivity.this,
Manifest.permission.CAMERA)) {
// Showing explanation to user to require permission
// <Build a dialog here. Following shows how to handle dialog clicks>
dialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Yes, user wants to give permission
dialog.dismiss();
ActivityCompat.requestPermissions(MyActivity.this,
new String[] {Manifest.permission.CAMERA},
Constants.PERMISSION_CAMERA);
}
});
alog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// No, user does not want to give permission now
dialog.dismiss();
}
});
} else {
// No explanation needed, requesting for permission now.
ActivityCompat.requestPermissions(this,
new String[] {Manifest.permission.CAMERA},
Constants.PERMISSION_CAMERA);
}
} else {
// Permission to get location has been granted already.
try {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, Constants.CAMERA_CAPTURE_REQUEST);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Log.e(TAG, "Camera is not found!");
}
}
}
Next we have a method to implement based on user's response provided to system dialog (which pops up just after our dialog).
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == Constants.PERMISSION_CAMERA ){
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
launchCamera();
} else if (grantResults[0] == PackageManager.PERMISSION_DENIED){
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
/*Here we have to show a dialog/ something else to show user why app requires permission. This is a good practice.*/
// Handle dialog clicks again
// Build a dialog here
btnPositiveOfDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Yes, I want to give permission now after reading detailed message
dialog.dismiss();
ActivityCompat.requestPermissions(UserInfoActivity.this,
new String[] {Manifest.permission.CAMERA},
Constants.PERMISSION_CAMERA);
}
});
btnNegativeOfDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// No, I still don't understand detailed message and want give permission away
dialog.dismiss();
}
});
} else {
// User checked 'Never ask again'
// Build a dialog here
btnPositiveOfDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Yes, go to app settings and manually enable settings
dialog.dismiss();
final Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + UserInfoActivity.this.getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
MyActivity.this.startActivity(i);
}
});
btnNegativeOfDialog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// No, I don't want to go to user settings and give permission now.
dialog.dismiss();
}
});
dialog.show();
}
}
}
}
Related
How can I request the permission popup without “Never ask again” text?
Here java Code ,
if
(intent.getAction().equals("com.finish.canceltrip.DriverMapActivity")) {
if (!checkAccessFineLocationPermission() || !checkAccessCoarseLocationPermission() || !checkWriteExternalStoragePermission()) {
requestPermission();
} else {
Intent i = new Intent(DriverMapActivity.this, DriverMapActivity.class);
i.putExtra("availability", "Yes");
finish();
startActivity(i);
}
How can I request the permission popup without “Never ask again” text?
NO you can not remove “Never ask again” from Permission Dialog
try this this hack if user selects Never ask again
ask for permission like this
btnCurrentLocationSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String permission = android.Manifest.permission.ACCESS_FINE_LOCATION;
if (ActivityCompat.checkSelfPermission(SearchCityClass.this, permission)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.
checkSelfPermission(SearchCityClass.this, android.Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
Toast.makeText(SearchCityClass.this, "Permission not granted", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(SearchCityClass.this, new String[]
{permission}, requestCode);
} else {
isPermissionGranted(true);
}
}
});
than handle permission result in onRequestPermissionsResult
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == requestCode) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
isPermissionGranted(true);
} else {
isPermissionGranted(false);
}
}
}
than create a method like this
public void isPermissionGranted(boolean permission) {
if (!permission) {
Toast.makeText(this, "Permission not Granted", Toast.LENGTH_SHORT).show();
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null)));
} else {
Toast.makeText(SearchCityClass.this, "true", Toast.LENGTH_SHORT).show();
Toast.makeText(SearchCityClass.this, "Permission granted", Toast.LENGTH_SHORT).show();
// you need to perform all action here if user grants the permission
}
}
No u can not remove Never ask again from that dialog
If the user declines again the app should either shut down if it absolutely needs that permission or keep running with limited functionality.
If the user reconsiders (and selects re-try), the permission is requested again. This time the prompt looks like this:
I'm working on checking and getting permission from user with API level 23 and above. So here is a confusing thing for me, android.com says:
shouldShowRequestPermissionRationale() method returns true if the app has requested this permission previously and the user denied the request.
If the user turned down the permission request in the past and chose the Don't ask again option in the permission request system dialog, this method returns false
in other side it gives following code for checking permission and request permission if its neccessery
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
else scope in above example runs if user doesn't allow permission and check Don't Ask Again, Right? So with this code user never being asked for permission at first time run. I tested that code and the result is what I expected.
So How could I request permission for first time run and do something if user previously denied my request and do something if user deny my request and check Don't Ask Again?
You can do the following.
Ask permission every time by only checking that permission is not granted already. Don't handle the "Don't ask again" in this method. (if user checks "Don't ask again" the OS will automatically handle and will not ask for permission again and will give a call back of permission denied)
Handle the ActivityCompat.shouldShowRequestPermissionRationale() in the call back method onRequestPermissionsResult().
Here is my code in which I am asking for permission everytime
public void checkAndAskCameraPermission() {
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(context,
new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_ID);
}
}
This is how I handles the call back
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case CAMERA_PERMISSION_REQUEST_ID: {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
// Do something if permission is not granted and the user has also checked the **"Don't ask again"**
} else if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
// Do something if permission not granted
}
}
}
}
first check if the permission is granted then do what you need
else if permission is denied then check weather you should request the permission you need or not through shouldShowRequestPermissionRationale.
if shouldShowRequestPermissionRationale return false then you can just show a message to the user to told them to enable the permission manually.
other then if shouldShowRequestPermissionRationale return true then request the permission and get the result of granting permission in onRequestPermissionsResult
update , this is just a simple code to show the steps:
if (checkSelfPermission == granted){
// do what you want
} else if (shouldShowRequestPermissionRationale == true) {
// you can request the permission you want from the user, then check whether permission granted or not inside onRequestPermissionsResult method
} else {
// here you know the permission is not granted , and also the user check on "Dont ask Again!" checkbox, so all you can to do is just tell the user to enable the permission manually from app permissions through Toast message or any thing else
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//initilize your views
if(iscontactsAllowed){
// do your code here
} else {
requestcontactsPermission();
}
}
private void requestcontactsPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_CONTACTS)) {
//If the user has denied the permission previously your code will come to this block
//Here you can explain why you need this permission
//Explain here why you need this permission
Log.d("scancode", "denied permission before");
}
Log.d("perm", "fourth");
//And finally ask for the permission
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_CONTACTS}, READ_CONTACTS_CODE /*can be any interge */);
}
private boolean iscontactsAllowed() {
//Getting the permission status
int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_CONTACTS);
//If permission is granted returning true
if (result == PackageManager.PERMISSION_GRANTED)
return true;
//If permission is not granted returning false
return false;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
//Checking the request code of our request
if(requestCode == READ_CONTACTS_CODE){
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// you have the permission call yur method here
} else {
// permission denied show user why you need it or ask again by calling reuestpermission if you need the permission
}
}
#ArtinArtin I have expanded on #salmanyahya updated simple code and provided my logic with Alert Dialog's and one Snackbar (not a big fan of Snackbar's) any way see if this helps
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
//.... write file into storage ...
System.out.println("SDK > BuildVersion TRUE");
} else {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 666); // Comment 26
System.out.println("go to requestPermissions");
}
}
onLoad();
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 666: // Allowed was selected so Permission granted
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Snackbar s = Snackbar.make(findViewById(android.R.id.content),"Permission Granted",Snackbar.LENGTH_LONG);
View snackbarView = s.getView();
TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.RED);
textView.setTextSize(18);
textView.setMaxLines(6);
s.show();
// do your work here
} else if (Build.VERSION.SDK_INT >= 23 && !shouldShowRequestPermissionRationale(permissions[0])) {
// User selected the Never Ask Again Option Change settings in app settings manually
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Change Permissions in Settings");
alertDialogBuilder
.setMessage("" +
"\nClick SETTINGS to Manually Set\n"+"Permissions to use Database Storage")
.setCancelable(false)
.setPositiveButton("SETTINGS", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 1000); // Comment 3.
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
} else {
// User selected Deny Dialog to EXIT App ==> OR <== RETRY to have a second chance to Allow Permissions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Second Chance");
alertDialogBuilder
.setMessage("Click RETRY to Set Permissions to Allow\n\n"+"Click EXIT to the Close App")
.setCancelable(false)
.setPositiveButton("RETRY", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, Integer.parseInt(WRITE_EXTERNAL_STORAGE));
Intent i = new Intent(MainActivity.this,MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
})
.setNegativeButton("EXIT", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
dialog.cancel();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
}
break;
}};
This code helps to handles the run time permission Management in Android
public String storagePermissions = Manifest.permission.READ_EXTERNAL_STORAGE;
private static final int REQUEST_ACCESS =101;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(checkSelfPermission(storagePermissions)== PackageManager.PERMISSION_GRANTED){
result(); // result is your block of code
}else {
requestPermissions(new String[]{storagePermissions},REQUEST_ACCESS);
}
}
else{
result(); //so if user is lower than api verison M, no permission is requested
}
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(MainActivity.this)
.setMessage(message)
.setTitle("Hi User..")
.setPositiveButton("Ok", okListener)
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) { //idea calling showMessage funtion again
Snackbar mySnackbar = Snackbar.make( findViewById(R.id.coordinatorlayout),"You Press Cancel.. ", Snackbar.LENGTH_INDEFINITE);
mySnackbar.setAction("Exit", new cancelButton());
mySnackbar.show();
}
})
.create()
.show();
}
private void result(){
//your code
}
#RequiresApi(api = Build.VERSION_CODES.M)
public class NeverAskAgain implements View.OnClickListener{
#Override
public void onClick(View view)
{
goToSettings();
}
}
#RequiresApi(api = Build.VERSION_CODES.M)
private void goToSettings() {
Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
finish();
myAppSettings.addCategory(Intent.CATEGORY_DEFAULT);
myAppSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivityForResult(myAppSettings, REQUEST_APP_SETTINGS);
}
public class cancelButton implements View.OnClickListener{
#Override
public void onClick(View view){
Toast.makeText(MainActivity.this,"To use this app , you must grant storage permission",Toast.LENGTH_SHORT);
finish();
}
}
#Override
#RequiresApi(api = Build.VERSION_CODES.M)
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode,permissions,grantResults);
switch(requestCode) {
case REQUEST_ACCESS:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission is granted
result();
break;
}
else if (!shouldShowRequestPermissionRationale(permissions[0])){
showMessageOKCancel("You choose Never Ask Again,option",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Snackbar mySnackbar = Snackbar.make(findViewById(R.id.coordinatorlayout), "Permission=>Storage=>On", Snackbar.LENGTH_INDEFINITE);
mySnackbar.setAction("Settings", new NeverAskAgain());
mySnackbar.show();
}
});
break;
}
else {
showMessageOKCancel("You Denid permission Request..",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(new String[]{storagePermissions}, REQUEST_ACCESS);
}
});
break;
}
}
}
What I have found is that shouldShowRequestPermissionRationale only returns true if the user has denied permission (at least once) and not selected "Don't Ask Again". Meaning, it won't be displayed on the first time the permission is requested either.
I have app that requests runtime permission for call on app start with dialog, but somehow my code doesn't request any permission or work. I need that when the app starts; ask the user for permission to call and in case the user refused, ask again for permission and move to in permissions settings.
Here's my code:
public class MainActivity extends AppCompatActivity {
private FirebaseAnalytics mFirebaseAnalytics;
private AdView mAdView;
private Button button_id;
private Button button_mobily;
private Button button_stc;
private Button button_zain;
private Button button_share;
private Button button_exit;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dash);
NativeExpressAdView adView = (NativeExpressAdView)findViewById(R.id.adView);
AdRequest request = new AdRequest.Builder().build();
adView.loadAd(request);
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.ITEM_ID, "main");
bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, "opened");
bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "image");
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle);
isPermissionGranted();
button_exit = (Button) findViewById(R.id.exit_buton_id);
button_share = (Button) findViewById(R.id.Share_buton);
button_id = (Button) findViewById(R.id.edit_id);
button_mobily = (Button) findViewById(R.id.mobily_buton);
button_stc = (Button) findViewById(R.id.stc_buton);
button_zain = (Button) findViewById(R.id.zain_buton);
button_id.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent myIntent = new Intent(MainActivity.this, NationalId.class);
MainActivity.this.startActivity(myIntent);
}
});
button_share.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
try {
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_SUBJECT, "test");
String sAux = "\n download my app\n\n";
sAux = sAux + "https://play.google.com/store/apps/details?id=Orion.Soft \n\n";
i.putExtra(Intent.EXTRA_TEXT, sAux);
startActivity(Intent.createChooser(i, "share on"));
} catch (Exception e) {
//e.toString();
}
}
});
button_exit.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
close();
}
});
button_mobily.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Intent myIntent = new Intent(MainActivity.this, OpreatorMobily.class);
MainActivity.this.startActivity(myIntent);
}
});
button_stc.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Intent myIntent = new Intent(MainActivity.this, OpreatorSTC.class);
MainActivity.this.startActivity(myIntent);
}
});
button_zain.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Intent myIntent = new Intent(MainActivity.this, OpreatorZain.class);
MainActivity.this.startActivity(myIntent);
}
});
}
public boolean isPermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.CALL_PHONE)
== PackageManager.PERMISSION_GRANTED) {
Log.v("TAG", "Permission is granted");
return true;
} else {
Log.v("TAG", "Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 1);
return false;
}
} else { //permission is automatically granted on sdk<23 upon installation
Log.v("TAG", "Permission is granted");
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "Permission granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Permission denied", Toast.LENGTH_SHORT).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
public void close() {
// TODO Auto-generated method stub
finish();
System.exit(0);
}
}
You don't need to check the Android version, Android is smart enough to know what the OS version is on the user's device.
Also if you're trying to get the ability to Call you need to change how the permission is called.
public boolean isPermissionGranted() {
Intent callOfficeIntent = new Intent(Intent.ACTION_CALL);
callOfficeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
callOfficeIntent.setData(Uri.parse("tel:" + mNumberToCall));
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CALL_PHONE},
10);
return;
} else {
try {
startActivity(callOfficeIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), "No number to call", Toast.LENGTH_SHORT).show();
}
}
}
If you just want to get the permission but not make the call right away place this inside your method. This just asks for permission as a DialogBox.
if(ActivityCompat.checkSelfPermission(getActivity(),Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED){
if(ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),Manifest.permission.READ_PHONE_STATE)){
//Show Information about why you need the permission
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Need Permission");
builder.setMessage("This app needs phone permission.");
builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE},PERMISSION_CALLBACK_CONSTANT);
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
} else if (permissionStatus.getBoolean(Manifest.permission.READ_PHONE_STATE,false)) {
//Previously Permission Request was cancelled with 'Dont Ask Again',
// Redirect to Settings after showing Information about why you need the permission
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Need Permission");
builder.setMessage("This app needs storage permission.");
builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
sentToSettings = true;
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
Toast.makeText(getActivity(), "Go to Permissions to Grant Phone", Toast.LENGTH_LONG).show();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
} else {
//just request the permission
requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE},PERMISSION_CALLBACK_CONSTANT);
}
txtPermissions.setText("Permissions Required");
SharedPreferences.Editor editor = permissionStatus.edit();
editor.putBoolean(Manifest.permission.READ_PHONE_STATE,true);
editor.commit();
} else {
//You already have the permission, just go ahead.
proceedAfterPermission();
}
}
});
}
private void proceedAfterPermission() {
txtPermissions.setText("We've got the permission");
Toast.makeText(getActivity(), "We got All Permissions", Toast.LENGTH_LONG).show();
}
Don't have to use the last method, just change the textView to a toast.
I found a simple Github library developed by "Nabin Bhandari". It is easy to implement and can be customized directly. Github library link...
Please add this dependency to add this library to your code.
implementation 'com.nabinbhandari.android:permissions:3.8'
This allow you to request single permission, multiple permission and do customize your own dialog.
Furthermore,
You can also override other methods like onDenied, onJustBlocked, etc if you want to change the default behaviour.
Dialogue messages and texts can be modified by building the options parameter.
See documentation in the source code for more customizations.
Use this code to ask multiple permissions samuntanely.
String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
Permissions.check(this/*context*/, permissions, null/*rationale*/, null/*options*/, new PermissionHandler() {
#Override
public void onGranted() {
// do your task.
}
});
Use this code if you want to Customized permissions request:
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION};
String rationale = "Please provide location permission so that you can ...";
Permissions.Options options = new Permissions.Options()
.setRationaleDialogTitle("Info")
.setSettingsDialogTitle("Warning");
Permissions.check(this/*context*/, permissions, rationale, options, new PermissionHandler() {
#Override
public void onGranted() {
// do your task.
}
#Override
public void onDenied(Context context, ArrayList<String> deniedPermissions) {
// permission denied, block the feature.
}
});
I am working on a demo application that ask run time permission on android
Marshmallow . I just when when user denial the permission user get an alert dialog again again or at least five clicks . If he denied more than five time application would stop.
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
if(null != actionBar){
actionBar.hide();
}
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_INTERNET);
}
htmlWebView = (WebView)findViewById(R.id.webView);
assert htmlWebView != null;
WebSettings webSetting = htmlWebView.getSettings();
webSetting.setJavaScriptEnabled(true);
webSetting.setDisplayZoomControls(true);
htmlWebView.setWebViewClient(new CustomWebViewClient());
htmlWebView.loadUrl("https://inducesmile.com/blog");
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_INTERNET) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED
) {
//start audio recording or whatever you planned to do
}else if (grantResults[0] == PackageManager.PERMISSION_DENIED){
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.RECORD_AUDIO)) {
//Show an explanation to the user *asynchronously*
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("This permission is important to record audio.")
.setTitle("Important permission required");
builder.setNegativeButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_INTERNET);
dialog.dismiss();
}
}
);
builder.show();
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_INTERNET);
}else{
//Never ask again and handle your app without permission.
}
}
}
}
Thanks for any help .
try this code:
int count =0;
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_INTERNET: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//do your task here
} else {
permission_denied();
}
break;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
public void permission_denied() {
// permission was not granted
//permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
// shouldShowRequestPermissionRationale will return true
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
Manifest.permission.RECORD_AUDIO)) {
showDialogOK("This permission is important to record audio.",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
//user enables permisssion do your task..
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
if(count==5){
finish();
//finish activity
}
else{
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_INTERNET);
++count;
}
break;
}
}
});
} //permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
Toast.makeText(getApplicationContext(), "Go to settings and enable record audio permissions", Toast.LENGTH_LONG).show();
}
}
private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(Mainactivity.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
If user press Never ask again.. permission dialog will not show again
This is expected behaviour.
From the documentation:
When the system asks the user to grant a permission, the user has the
option of telling the system not to ask for that permission again. In
that case, any time an app uses requestPermissions() to ask for that
permission again, the system immediately denies the request. The
system calls your onRequestPermissionsResult() callback method and
passes PERMISSION_DENIED, the same way it would if the user had
explicitly rejected your request again. This means that when you call
requestPermissions(), you cannot assume that any direct interaction
with the user has taken place.
see this also:Does checking the Never ask again box when asking for a runtime permission disable future dialogs?
I made message sending app it work perfect in all version till kitkat 4.4.4 but not working in Lollipop and Marshmallow I don't understand why?
public void sendsms()
{
try
{
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNo, null,smsmessage, null, null);
printmsg(1);
}
catch (Exception e)
{
printmsg(0);
e.printStackTrace();
}
}
public void printmsg(int a)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Information:");
if(a==1)
builder.setMessage("SMS Send Wait For Response!!!");
else
builder.setMessage("Sending Failed, Please Try Again Later!!!");
builder.setPositiveButton("OK",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which)
{
//Toast.makeText(getApplicationContext(), "changing activity",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(ResWindow.this, Home.class);
startActivity(intent);
ResWindow.this.finish();
}
});
builder.show();
From API 23, i.e. Android Marshmallow, the app will have to ask for permissions while running instead of declaring them beforehand. The logic here is, to see if the device is below 23, if it is, then the SMS would be sent without any problem, if it 23 and above, you will have to prompt the user to allow the app to send the message.
Here is a sample code with explanation which might help you out there.
private static final int PERMISSION_REQUEST = 100;
//This is the onClick listener of 'Send SMS' button
public void send(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//This if checks if the device is API 23 or above
if (checkSelfPermission(Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
//This checks if the permission is already granted.
if (shouldShowRequestPermissionRationale(Manifest.permission.SEND_SMS)) {
//This displays a message to the user as to why do we
//need the permission. If the user accepts, we display the permission granting dialog.
Snackbar.make(findViewById(R.id.rl), "You need to grant SEND SMS permission to send sms",
Snackbar.LENGTH_LONG).setAction("OK", new View.OnClickListener() {
#Override
public void onClick(View v) {
requestPermissions(new String[]{Manifest.permission.SEND_SMS}, PERMISSION_REQUEST);
}
}).show();
} else {
//This displays the permission granting dialog directly.
requestPermissions(new String[]{Manifest.permission.SEND_SMS}, PERMISSION_REQUEST);
}
} else {
sendSMS(); // Runs if the permission is already granted.
}
} else {
sendSMS(); // Runs if the device's API is below 23.
}
}
private void sendSMS() {
//Code for sending sms.
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Snackbar.make(findViewById(R.id.rl), "Permission Granted",
Snackbar.LENGTH_LONG).show();
sendSMS();
//SMS sent
} else {
Snackbar.make(findViewById(R.id.rl), "Permission denied",
Snackbar.LENGTH_LONG).show();
//SMS not sent.
}
}
The code was taken from here. A more elaborated explanation can be found there.