Android API 23 Requesting Multiple Permissions - android

I am trying to request permissions on my Launcher Activity. For API < 23, it works perfect. However, when I test the app on a device running API 23, it says: "PostPaid Balance has stopped." I hit the "close App button," the app closes and immediately asks for one permission. I hit accept. Then I tap on the app icon to reopen and the same thing happens, except that now it asks for the next permission. Then I tap on the app icon and this time executes correctly.
It seems like it is asking for permissions one at a time. Any ideas on how to go about this?
// Below code is implemented on onCreate() of the launcher activity.
if (Build.VERSION.SDK_INT < 23) {
ActivityCompat.checkSelfPermission(this.getApplicationContext(), "android.permission.READ_SMS");
ActivityCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.READ_CALL_LOG);
ActivityCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.READ_PHONE_STATE);
if ((ActivityCompat.checkSelfPermission(this, "android.permission.READ_SMS") != PackageManager.PERMISSION_GRANTED)) {
requestSmsPermission();
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
requestPhoneStatePermission();
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
requestCallLogPermission();
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if ((this.checkSelfPermission("android.permission.READ_SMS") != PackageManager.PERMISSION_GRANTED) &&
(this.checkSelfPermission(Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) &&
(this.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED)) {
this.requestPermissions(new String[]{"android.permission.READ_SMS", Manifest.permission_group.PHONE}, REQUEST_SMS);
}
}

To answer your question on how to request for multiple permissions in one go, add permissions to your array of strings. In this example, I want to request permissions for READ_PHONE_STATE and WRITE_EXTERNAL_STORAGE:
ArrayList<String> arrPerm = new ArrayList<>();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
arrPerm.add(Manifest.permission.READ_PHONE_STATE);
}
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
arrPerm.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if(!arrPerm.isEmpty()) {
String[] permissions = new String[arrPerm.size()];
permissions = arrPerm.toArray(permissions);
ActivityCompat.requestPermissions(this, permissions, MY_PERMISSIONS_REQUEST);
}
Now, check which permissions were granted:
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0) {
for(int i = 0; i < grantResults.length; i++) {
String permission = permissions[i];
if(Manifest.permission.READ_PHONE_STATE.equals(permission)) {
if(grantResults[i] == PackageManager.PERMISSION_GRANTED) {
// you now have permission
}
}
if(Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission)) {
if(grantResults[i] == PackageManager.PERMISSION_GRANTED) {
// you now have permission
}
}
}
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
break;
}
}
// other 'case' lines to check for other
// permissions this app might request
}

Related

Can't access camera on API < 23 devices with app having permissions

I'm developing an android app and i have problems with the camera permission.
On click of a button i call this
if (android.os.Build.VERSION.SDK_INT > 23) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST_CAMERA);
}
} else {
BarCodeReaderActivity.startActivity(this, REQUEST_CODE_BAR_CODE, mStatus);
}
}else{
if (cameraAvailable)
BarCodeReaderActivity.startActivity(this, REQUEST_CODE_BAR_CODE, mStatus);
else {
Toast.makeText(this, KanbanBoxSettings.getInstance(this).getTranslationString(Strings.message_camera_not_available), Toast.LENGTH_LONG).show();
}
}
When i look on
Settings > Apps > "Your app" > Permissions i see that the app has the camera permission so why is the camera still unavailable?
I don't know if this errorlog is usefull but here is what i get:
E/StopWatchTimer: [LOG_ERR]StopWatchTimerStart : 63 - StopWatchTimer have already start!
Call this method before executing your camera code.
public void checkLocationPermission(){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED ){
// You don't have the permission you need to request it
ActivityCompat.requestPermissions(YourActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},PERMISSION_REQUEST_CODE_LOCATION);
} else {
// You have the permission.
setUserLocation();
}
}
Then, Override onRequestPermissionsResult
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE_LOCATION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
setUserLocation();
} else {
toast(getApplicationContext(),"You have cancelled location accessed request");
currentLoaction.setImageDrawable(getResources().getDrawable(R.drawable.location));
}
}
}
Now call your camera method. If this is not working then post your camera calling code.

Ask runtime permission one after another only,not at once in array

In onCreate()of my activity I check for permissions.
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 2);
}
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CHECK_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
}
For every permission,in its callback method I perform certain tasks.So I cannot ask the permissions in array like
String[] permissions { };
as it will provide me only one call back for all permissions.I perform tasks in every callback in following way.
case ConstantClass.READ_PERMISSION:
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
doSomething();
Toast.makeText(MainActivity.this, getResources().getString(R.string.Cannot_Vibrate_Phone), Toast.LENGTH_LONG).show();
}
break;
case ConstantClass.CALL_PERMISSION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
dialPhoneNumber();
} else {
Toast.makeText(MainActivity.this, getString(R.string.permission_access_call), Toast.LENGTH_LONG).show();
}
break;
If I ask these permissions one after other in onCreate(). Only the first permission is displayed.So I get only one call back working. So how to achieve the scenario that for every single permission I get a separate call back and call some functions in them.
Thank you :)
Check this Demo Code
Ask next permission in response of first permission reject/grant in
onRequestPermissionsResult()
public class MainActivity extends Activity {
private Context context;
private static final int REQUEST_RUNTIME_PERMISSION_1 = 111;
private static final int REQUEST_RUNTIME_PERMISSION_2 = 222;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
if (CheckPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// you have permission go ahead
} else {
// you do not have permission go request runtime permissions
RequestPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE, REQUEST_RUNTIME_PERMISSION_1);
}
}
#Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions,
int[] grantResults) {
switch (permsRequestCode) {
case REQUEST_RUNTIME_PERMISSION_1: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// you have permission go ahead ask next permission and get separate callback
RequestPermission(MainActivity.this, Manifest.permission.CAMERA, REQUEST_RUNTIME_PERMISSION_2);
} else {
// you do not have permission show toast.
/*check your logic ask again*/
//RequestPermission(MainActivity.this, Manifest.permission.CAMERA, REQUEST_RUNTIME_PERMISSION_2);
}
return;
}
case REQUEST_RUNTIME_PERMISSION_2: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// you have 2nd permission go ahead
} else {
// you do not have 2nd permission show toast.
}
return;
}
}
}
public void RequestPermission(Activity thisActivity, String Permission, int Code) {
if (ContextCompat.checkSelfPermission(thisActivity,
Permission)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Permission)) {
} else {
ActivityCompat.requestPermissions(thisActivity,
new String[]{Permission},
Code);
}
}
}
public boolean CheckPermission(Context context, String Permission) {
if (ContextCompat.checkSelfPermission(context,
Permission) == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
}
You can ask the next permission in onRequestPermission to show permission request one after another. You can examine the below code and get the idea. In onRequestPermissionResult method:
case ConstantClass.READ_PERMISSION:
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
doSomething();
Toast.makeText(MainActivity.this, getResources().getString(R.string.Cannot_Vibrate_Phone), Toast.LENGTH_LONG).show();
}
// Ask for Camera permission
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CHECK_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
break;
Hope this helps.
String permissions[] = new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.INTERNET};
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
&&ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&&ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ){
ActivityCompat.requestPermissions(this, permissions, ALL_REQUEST_CODE);
}
else if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&&ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[] {permissions[1], permissions[2], permissions[3]}, ALL_REQUEST_CODE);
}
else if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[] {permissions[2], permissions[3]}, ALL_REQUEST_CODE);
}
This is the best way to get permissions

Android check camera permission in target sdk 22 or lower

I have my code like this to check camera permission.
if (Build.VERSION.SDK_INT >= 23) {
Log.e("Permission State",ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA)+"");
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED){
showCameraActivityForResult(activity);
}else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA}, Constant.MY_PERMISSIONS_REQUEST_CAMERA);
}
}else{
showCameraActivityForResult(activity);
}
Problem is that I always have permission granted in 5.1 or lower. Other user also said here.
How can I know if my app's camera permission is granted?
In some device like samsung, user can disable camera permission from device setting and as a result, when user open my app and tap on camera, it always show blank. How can I detect whether user can use camera? (it need to be different from my code since it is not working.)
If you use AppCompatActivity, you can use checkSelfPermission to check if permission have been granted.
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.CAMERA)) {
//Show permission dialog
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.CAMERA}, code);
}
}
On API 22 and below permissions are granted if specified in the manifest.
For API 23+ ContextCompat#checkSelfPermission could be of use. It "degrades" gracefully on earlier APIs and will tell you the permission is granted if it appears in the manifest. On API 23 and above it will actually check if it's granted.
It returns PackageManager.PERMISSION_GRANTED if the permission is granted.
call it in an Activity with Manifest.permission.CAMERA to avoid typos.
ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA));
Try this,
private Context mContext=YourActivity.this;
private static final int REQUEST = 112;
if (Build.VERSION.SDK_INT >= 23) {
String[] PERMISSIONS = {android.Manifest.permission.CAMERA};
if (!hasPermissions(mContext, PERMISSIONS)) {
ActivityCompat.requestPermissions((Activity) mContext, PERMISSIONS, REQUEST );
} else {
showCameraActivityForResult(activity);
}
} else {
showCameraActivityForResult(activity);
}
get Permissions Result
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
showCameraActivityForResult(activity);
} else {
Toast.makeText(mContext, "The app was not allowed to write in your storage", Toast.LENGTH_LONG).show();
}
}
}
}
check permissions for marshmallow
private static boolean hasPermissions(Context context, String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
Manifest
<uses-permission android:name="android.permission.CAMERA" />
OR :
if (Build.VERSION.SDK_INT >= 23)
{
Log.e("Permission State",ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA)+"");
// Here, thisActivity is the current activity
if (ActivityCompat.checkSelfPermission(activity, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)
{
showCameraActivityForResult(activity);
}
else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(activity, new String[]{android.Manifest.permission.CAMERA}, Constant.MY_PERMISSIONS_REQUEST_CAMERA);
}
}else{
showCameraActivityForResult(activity);
}
checkSelfPermission is available above sdk 23.
we can check the permission is available or not using package manager
public static Boolean checkpermissions(Activity activity) {
PackageManager mPackageManager = activity.getPackageManager();
int hasPermStorage = mPackageManager.checkPermission(android.Manifest.permission.CAMERA, activity.getPackageName());
if (hasPermStorage != PackageManager.PERMISSION_GRANTED) {
// do stuff
// Toast.makeText(getApplicationContext(), "No permission", Toast.LENGTH_LONG).show();
return false;
} else if (hasPermStorage == PackageManager.PERMISSION_GRANTED) {
// do stuff
// Toast.makeText(getApplicationContext(), "Has permission", Toast.LENGTH_LONG).show();
return true;
} else {
return false;
}

App starts twice in oncreate

I am using the following code to obtain read write permissions, however the problem is, by having this piece of code in oncreate, my app starts twice instead of once. How do I fix this?
// **check if app has permission 1**//
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.System.canWrite(this)) {
requestPermissions(new String[] {
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE }, 2909);
} else {
// continue with your code
}
} else {
// continue with your code
}
here is rest of the code which is outside oncreate-
// **check if app has permission 2**//
#Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
switch (requestCode) {
case 2909: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e("Permission", "Granted");
} else {
Log.e("Permission", "Denied");
}
return;
}
}
}
have you tried to use this to check permission
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
this well return if permission is granted or revoked ...
refer to this tutorial Requesting Permissions at Run Time
for this particular example first you can check if permission is granted or not
checkSelfPermission( Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED)
if result is false then request permission
edit
change if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
to
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && (checkSelfPermission( Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) || checkSelfPermission( Manifest.permission.READ_EXTERNAL_STORAGE )
!= PackageManager.PERMISSION_GRANTED)))

Android runtime permissions Inaccessible

I am trying to set up location permission in android when I install the app in device automatically device assign the location permission to the app(using ManifestFile). if I manually disable the location from permission & run the app again It doesn't show me any popup (which I programmed to ask).
private const int LOCATION_GROUP_PERMISSION_REQUEST = 1;
if ((int)Build.VERSION.SdkInt > 22) {
if (ContextCompat.CheckSelfPermission (this, Android.Manifest.Permission_group.Location) != Android.Content.PM.Permission.Granted) {
Toast.MakeText (this, "Something Really wrong", ToastLength.Short).Show ();
var data = ActivityCompat.ShouldShowRequestPermissionRationale (this, Manifest.Permission_group.Location);
if (!data) {
AlertDialog.Builder builder;
builder = new AlertDialog.Builder (this);
builder.SetTitle ("Location Permission is Disabled");
builder.SetMessage ("Location permission is needed ");
builder.SetCancelable (false);
builder.SetPositiveButton ("Enable", delegate {
ActivityCompat.RequestPermissions (this, new String [] { Manifest.Permission_group.Location },
LOCATION_GROUP_PERMISSION_REQUEST);
});
builder.Show ();
} else {
ActivityCompat.RequestPermissions (this, new String [] { Manifest.Permission_group.Location },
LOCATION_GROUP_PERMISSION_REQUEST);
}
} else {
GoToActivity ();
}
}
the data variable always return false
public override void OnRequestPermissionsResult (int requestCode, string [] permissions, Android.Content.PM.Permission [] grantResults)
{
if (requestCode == LOCATION_GROUP_PERMISSION_REQUEST) {
for (int i = 0; i < permissions.Length; i++) {
if (grantResults [i] == Android.Content.PM.Permission.Granted) {
Toast.MakeText (this, "Param granted", ToastLength.Short).Show ();
} else if (grantResults [i] == Android.Content.PM.Permission.Denied) {
Toast.MakeText (this, "param Denied", ToastLength.Short).Show ();
}
}
} else {
base.OnRequestPermissionsResult (requestCode, permissions, grantResults);
}
}
// permissions length Zero
Runtime permission is only from Api level 23 and above
I know that this answer is not perfect answer for your question, i answered in native so at least it help you to convert it to xamarin.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// permissions have not been granted.
requestPermissions();
}
}
}
private void requestPermissions() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_COARSE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(this,
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 request has been denied previously.
// this is my custom dialog change as per ur requirement to notify user
showPermissionRationaleDialog("Locations permissions are needed to demonstrate access.", PERMISSIONS_LOCATION, false);
//when user click ok in dialog you have to call requestForPermission method
} else {
// permissions have not been granted yet. Request them directly.
requestForPermission(PERMISSIONS_LOCATION);
}
}
//request generating
private void requestForPermission(final String[] permissions) {
ActivityCompat.requestPermissions(NwSelectionActivity.this, permissions, REQUEST_CODE);
}
//result handling
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == REQUEST_CODE) {
if (PermissionUtil.verifyPermissions(grantResults)) {
// All required permissions have been granted,
} else {
boolean showRationale = ActivityCompat.shouldShowRequestPermissionRationale(this,
permissions[0]);
Log.i(TAG, "Locations permissions were NOT granted.");
if (!showRationale) {
//here you show dialog to user to manually enable location permission in setting
showPermissionRationaleDialog("Allow App to access your locations. Tap Setting > Permissions, and turn Location on.", PERMISSIONS_LOCATION, true);
}
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Check if the permission was denied or granted in
onRequestPermissionsResult.
If the permission was denied previously, this time there will be a
Never ask again checkbox in the permission dialog.
Call shouldShowRequestPermissionRationale to see if the user checked
Never ask again. shouldShowRequestPermissionRationale method returns
false only if the user selected Never ask again or device policy
prohibits the app from having that permission:
see https://stackoverflow.com/a/34612503/4623782 for more information

Categories

Resources