Android check camera permission in target sdk 22 or lower - android

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;
}

Related

Ask Multiple Permissions Android

I'm modifying an existing Face Tracker app Android's Facial Recognition sample projects. I'm having an issue with requesting multiple permanent permissions. The method below is a modified version of the existing method that successfully creates a pop up window to ask for camera permissions. I'm trying to replicate this with the storage permissions but so far I've been unsuccessful and I'm not sure what needs to be changed here.
private void requestAllPermissions() {
Log.w(TAG, "Camera + Storage permissions are not granted. Requesting permissions");
final String[] permissions = new String[]{Manifest.permission.CAMERA};
final String[] permissions2 = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
ActivityCompat.requestPermissions(this, permissions, RC_HANDLE_CAMERA_PERM);
return;
}
//new
if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
ActivityCompat.requestPermissions(this, permissions2, RC_HANDLE_STORAGE_PERM);
return;
}
final Activity thisActivity = this;
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View view) {
ActivityCompat.requestPermissions(thisActivity, permissions,
RC_HANDLE_CAMERA_PERM);
}
};
View.OnClickListener listener2 = new View.OnClickListener() {
#Override
public void onClick(View view) {
ActivityCompat.requestPermissions(thisActivity, permissions2,
RC_HANDLE_STORAGE_PERM);
}
};
Snackbar.make(mGraphicOverlay, R.string.permission_camera_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, listener)
.show();
Snackbar.make(mGraphicOverlay, R.string.permission_storage_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok, listener2)
.show();
}
you should have only one String array if you want to ask all permissions in one dialog box, like this:
int ALL_PERMISSIONS = 101;
final String[] permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};
ActivityCompat.requestPermissions(this, permissions, ALL_PERMISSIONS);
Why do you want to request permissions multiple times. The requestpermission method accepts array of Permissions. To request for any permission you can use the below code and add the permissions you need. This is how you handle runtime permissions by requesting them before accessing any data related to permission
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.CAMERA)
== 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.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, 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 0:
boolean isPerpermissionForAllGranted = false;
if (grantResults.length > 0 && permissions.length==grantResults.length) {
for (int i = 0; i < permissions.length; i++){
if (grantResults[i] == PackageManager.PERMISSION_GRANTED){
isPerpermissionForAllGranted=true;
}else{
isPerpermissionForAllGranted=false;
}
}
Log.e("value", "Permission Granted, Now you can use local drive .");
} else {
isPerpermissionForAllGranted=true;
Log.e("value", "Permission Denied, You cannot use local drive .");
}
if(isPerpermissionForAllGranted){
shoro();
}
break;
}
}
Once you do that, for devices with API >=23 You will get popup at runtime and then once the user accepts the permission or rejects it, your onRequestPermissionsResult method is called. so here you will have to handle your check whether user granted the app the permission. If yes you can continue with your logic
What you have to do is just put the permission sin a String array like
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {
android.Manifest.permission.READ_CONTACTS,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION
};
and to Check the permission use then
public static boolean hasPermissions(Context context, String... permissions) {
if (context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
Now the Last thing to do finally is use it in oncreate() or onStart()
if(!hasPermissions(this, PERMISSIONS)){
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
I faced the issue today and answer from Aman Grover actually worked for me, you simple need to do following
final String[] permissions = new String[]{
android.Manifest.permission.READ_CONTACTS,
Manifest.permission.READ_EXTERNAL_STORAGE
};
ActivityCompat.requestPermissions(this, permissions, 123);
This is the simplest solution:
Add this code in your MainActivity's onCreate method
//Requesting permissions
int PERMISSION_ALL = 1;
String[] PERMISSIONS = {
android.Manifest.permission.READ_CONTACTS,
android.Manifest.permission.RECORD_AUDIO,
android.Manifest.permission.CALL_PHONE,
};
if (!hasPermissions(this, PERMISSIONS)) {
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
Now, add this function in your main activity class
public static boolean hasPermissions(Context context, String... permissions) {
if (context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
You can add ass many permissions you need to ask at the application startup.

Android permissionCheck not working

AndroidManifest.xml :
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Code :
button.setOnClickListener {
var permissionCheck = ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
toast("success")
} else {
toast("fail")}}
Why does this return "fail" ?
For Android 6.0+ or targetSdk=23 you have to consider asking for run-time permissions. The permissions android.permission.ACCESS_FINE_LOCATION is considered dangerous so you have to ask for it at run-time. See Normal and Dangerous Permissions for an overview.
What you have to do is to ask it at run-time e.g.
from the developer guidelines
// 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.
}
}
Read more here at Requesting Permissions at Run Time
In this case you should request the permission like:ActivityCompat.requestPermissions(thisActivity,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE);
and you should get an answer in onRequestPermissionsResult callback.
Then, if the user grant the permission, at the next time you will use the checkSelfPermission method you will get success.
For more details read this: https://developer.android.com/training/permissions/requesting.html
It seems you are using target sdk >=23 and run app on device with api level also >=23. So since api 23 there is new flow to recive permissions. Permissions are divided into two categories, normal and dangerous. Dangerous permissions should be asked in runtime like this:
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_LOCATION);
This will show system dialog for user:
So result of user's selections will be returned to public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
With request code that you passed in ActivityCompat.requestPermissions, in my case it is MY_PERMISSIONS_REQUEST_LOCATION
Permissions' names will be in String permissions[] and user's selections will be accordingly in int[] grantResults, with can be PackageManager.PERMISSION_GRANTED or PERMISSION_DENIED.
Also it's good to explain to user why you need that permission before asking it.
See more here:Requesting Permissions at Run Time
You can check Permission after/in Android 6.0
public class MainActivity extends AppCompatActivity {
private final int PERMISSIONS_CODE = 1001;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION,}, PERMISSIONS_CODE);
} else {
// You can do you operation directly. If you added permissions in AndroidManifest...
// Or visit following link to read about permission check.
// https://stackoverflow.com/questions/7203668/how-permission-can-be-checked-at-runtime-without-throwing-securityexception
}
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSIONS_CODE:
if (grantResults.length > 0 && grantResults[grantResults.length-1] == PackageManager.PERMISSION_GRANTED) {
Log.d("permission", "accepted");
} else {
Log.d("permission", "denied");
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
}
Happy coding...
for Android 6.0 and your targetSdkVersion >=23 , you should ask permission at run time,I have two advise:
1、you can change your targetSdkVersion in model gradle file,eg:
targetSdkVersion=22
but,I don't recommend use this method.
2、this return 'fail' mean you don't have this permission,your should
consider if your have request but user refuse,in this your can show a dialog to tell use ,why you need this perssion,and then request the permession you want,you can use this code below:
private boolean check(){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)== PackageManager.PERMISSION_GRANTED){
//you have this permession
return true;
}else{
//don't hava permession ,you shoud check if you can request
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
//the use refuse you request this permission ,the system well't show request dialog,you shoul show a dialog tu explain why you need this permission
//and guide he go to system setting open this permission.
}else {
// you can request permission direct
//requestCode is a integer code,that you can use is in onRequestPermissionsResult
ActivityCompat.requestPermissions(this, Manifest.permission.ACCESS_FINE_LOCATION, requestCode);
}
}
return false;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//in this you can listen the request result
if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
//user Agree permission
}else{
//user reject permission
}
}
I'm sorry,I only know java,so,this code is jave. hope this can help you to deal this problem.
Requesting permissions is too confusing for me, EasyPermissions solved all my problems
Manifest :
compile 'pub.devrel:easypermissions:0.4.2'
Code :
button.setOnClickListener {
if (EasyPermissions.hasPermissions(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
toast("yes !")
} else {
EasyPermissions.requestPermissions(this, getString(R.string.location_perm), 1, Manifest.permission.ACCESS_FINE_LOCATION )
}}
worked perfect first try
public static int CAMERA_PERMISSSION_CODE = 1;
public static int STORAGE_PERMISSSION_CODE = 2;
public static int FINE_LOCATION_PERMISSSION_CODE = 3;
public static int COARSE_LOCATION_PERMISSSION_CODE = 3;
public static int READ_PHONESTATE_PERMISSSION_CODE = 4;
private void askForunTimePermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(PermissionsActivity.this,
Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSSION_CODE);
} else if (ContextCompat.checkSelfPermission(PermissionsActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSSION_CODE);
} else if (ContextCompat.checkSelfPermission(PermissionsActivity.this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, FINE_LOCATION_PERMISSSION_CODE);
} else if (ContextCompat.checkSelfPermission(PermissionsActivity.this,
Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, COARSE_LOCATION_PERMISSSION_CODE);
} else if (ContextCompat.checkSelfPermission(PermissionsActivity.this,
Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_PHONE_STATE}, READ_PHONESTATE_PERMISSSION_CODE);
} else {
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
try {
if (requestCode == CAMERA_PERMISSSION_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
askForunTimePermissions();
} else {
askForunTimePermissions();
}
} else if (requestCode == STORAGE_PERMISSSION_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
askForunTimePermissions();
} else {
askForunTimePermissions();
}
} else if (requestCode == FINE_LOCATION_PERMISSSION_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
askForunTimePermissions();
} else {
askForunTimePermissions();
}
} else if (requestCode == COARSE_LOCATION_PERMISSSION_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
askForunTimePermissions();
} else {
askForunTimePermissions();
}
} else if (requestCode == READ_PHONESTATE_PERMISSSION_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
askForunTimePermissions();
} else {
askForunTimePermissions();
}
}
} catch (Exception e) {
Toast.makeText(PermissionsActivity.this, "No permission requests matched", Toast.LENGTH_SHORT).show();
}
}
//call this method where u want
askForunTimePermissions();
To check Location Permission via PermissionChecker.checkSelfPermission, you need to enable Location first. Otherwise PermissionChecker.checkSelfPermission will always return -2.

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 debugging on real device - MissingPermissionException [duplicate]

In Lollipop, the download functionality works fine in my app, but when I upgraded to Marshmallow, my app crashes and gives this error when I try to download from the internet into the SD card:
Neither user nor current process has android.permission.WRITE_EXTERNAL_STORAGE
It complains about this line of code:
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
I have the permissions in the manifest outside application:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
I cleaned and rebuilt the project, but it still crashes.
You should be checking if the user has granted permission of external storage by using:
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
//File write logic here
return true;
}
If not, you need to ask the user to grant your app a permission:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
Of course these are for marshmallow devices only so you need to check if your app is running on Marshmallow:
if (Build.VERSION.SDK_INT >= 23) {
//do your check here
}
Be also sure that your activity implements OnRequestPermissionResult
The entire permission looks like this:
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== 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.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted");
return true;
}
}
Permission result callback:
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Log.v(TAG,"Permission: "+permissions[0]+ "was "+grantResults[0]);
//resume tasks needing this permission
}
}
Android's permission system is one of the biggest security concern all
along since those permissions are asked for at install time. Once
installed, the application will be able to access all of things
granted without any user's acknowledgement what exactly application
does with the permission.
Android 6.0 Marshmallow introduces one of the largest changes to the
permissions model with the addition of runtime permissions, a new
permission model that replaces the existing install time permissions
model when you target API 23 and the app is running on an Android 6.0+
device
Courtesy goes to Requesting Permissions at Run Time .
Example
Declare this as Global
private static final int PERMISSION_REQUEST_CODE = 1;
Add this in your onCreate() section
After setContentView(R.layout.your_xml);
if (Build.VERSION.SDK_INT >= 23)
{
if (checkPermission())
{
// Code for above or equal 23 API Oriented Device
// Your Permission granted already .Do next code
} else {
requestPermission(); // Code for permission
}
}
else
{
// Code for Below 23 API Oriented Device
// Do next code
}
Now adding checkPermission() and requestPermission()
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(Your_Activity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
private void requestPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(Your_Activity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(Your_Activity.this, "Write External Storage permission allows us to do store images. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(Your_Activity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.e("value", "Permission Granted, Now you can use local drive .");
} else {
Log.e("value", "Permission Denied, You cannot use local drive .");
}
break;
}
}
FYI
onRequestPermissionsResult
This interface is the contract for receiving the results for
permission requests.
Check multiple Permission in API level 23
Step 1:
String[] permissions = new String[]{
Manifest.permission.INTERNET,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.VIBRATE,
Manifest.permission.RECORD_AUDIO,
};
Step 2:
private boolean checkPermissions() {
int result;
List<String> listPermissionsNeeded = new ArrayList<>();
for (String p : permissions) {
result = ContextCompat.checkSelfPermission(this, p);
if (result != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(p);
}
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), 100);
return false;
}
return true;
}
Step 3:
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
if (requestCode == 100) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// do something
}
return;
}
}
Step 4:
in onCreate of Activity
checkPermissions();
Unless there is a definite requirement of writing on external storage, you can always choose to save files in app directory. In my case I had to save files and after wasting 2 to 3 days I found out if I change the storage path from
Environment.getExternalStorageDirectory()
to
getApplicationContext().getFilesDir().getPath() //which returns the internal app files directory path
it works like charm on all the devices.
This is because for writing on External storage you need extra permissions but writing in internal app directory is simple.
you need to use runtime permission in marshmallow
https://developer.android.com/training/permissions/requesting.html
you can check in app info -> permission
is your app get permission for write external storage or not
From marshmallow version, developers need to ask for runtime permissions to user.
Let me give you whole process for asking runtime permissions.
I am using reference from here : marshmallow runtime permissions android.
First create a method which checks whether all permissions are given or not
private boolean checkAndRequestPermissions() {
int camerapermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
int writepermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
int permissionLocation = ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION);
int permissionRecordAudio = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);
List<String> listPermissionsNeeded = new ArrayList<>();
if (camerapermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.CAMERA);
}
if (writepermission != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if (permissionLocation != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (permissionRecordAudio != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(Manifest.permission.RECORD_AUDIO);
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
Now here is the code which is run after above method. We will override onRequestPermissionsResult() method :
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
Log.d(TAG, "Permission callback called-------");
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<>();
// Initialize the map with both permissions
perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.RECORD_AUDIO, PackageManager.PERMISSION_GRANTED);
// Fill with actual results from user
if (grantResults.length > 0) {
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for both permissions
if (perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "sms & location services permission granted");
// process the normal flow
Intent i = new Intent(MainActivity.this, WelcomeActivity.class);
startActivity(i);
finish();
//else any one or both the permissions are not granted
} else {
Log.d(TAG, "Some permissions are not granted ask again ");
//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
//show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
showDialogOK("Service Permissions are required for this app",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
checkAndRequestPermissions();
break;
case DialogInterface.BUTTON_NEGATIVE:
// proceed with logic by disabling the related features or quit the app.
finish();
break;
}
}
});
}
//permission is denied (and never ask again is checked)
//shouldShowRequestPermissionRationale will return false
else {
explain("You need to give some mandatory permissions to continue. Do you want to go to app settings?");
// //proceed with logic by disabling the related features or quit the app.
}
}
}
}
}
}
If user clicks on Deny option then showDialogOK() method will be used to show dialog
If user clicks on Deny and also clicks a checkbox saying "never ask again", then explain() method will be used to show dialog.
methods to show dialogs :
private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", okListener)
.create()
.show();
}
private void explain(String msg){
final android.support.v7.app.AlertDialog.Builder dialog = new android.support.v7.app.AlertDialog.Builder(this);
dialog.setMessage(msg)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// permissionsclass.requestPermission(type,code);
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:com.exampledemo.parsaniahardik.marshmallowpermission")));
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
finish();
}
});
dialog.show();
}
Above code snippet asks for four permissions at a time. You can also ask for any number of permissions in your any activity as per your requirements.
The easiest way I found was
private boolean checkPermissions(){
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
return true;
}
else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_CODE);
return false;
}
}
Add below code to your OnCreate() function in MainAcitivity, which will display pop up to ask for permission:
if (ActivityCompat.shouldShowRequestPermissionRationale(TestActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)){
}
else {
ActivityCompat.requestPermissions(TestActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
100);
}
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Log.d(TAG, "Permission granted");
} else {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
100);
}
fab.setOnClickListener(v -> {
Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.refer_pic);
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/*");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(requireActivity().getContentResolver(),
b, "Title", null);
Uri imageUri = Uri.parse(path);
share.putExtra(Intent.EXTRA_STREAM, imageUri);
share.putExtra(Intent.EXTRA_TEXT, "Here is text");
startActivity(Intent.createChooser(share, "Share via"));
});
After lots of searching This code work for me:
Check the permission already has:
Check WRITE_EXTERNAL_STORAGE permission Allowed or not?
if(isReadStorageAllowed()){
//If permission is already having then showing the toast
//Toast.makeText(SplashActivity.this,"You already have the permission",Toast.LENGTH_LONG).show();
//Existing the method with return
return;
}else{
requestStoragePermission();
}
private boolean isReadStorageAllowed() {
//Getting the permission status
int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
//If permission is granted returning true
if (result == PackageManager.PERMISSION_GRANTED)
return true;
//If permission is not granted returning false
return false;
}
//Requesting permission
private void requestStoragePermission(){
if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)){
//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
}
//And finally ask for the permission
ActivityCompat.requestPermissions(this,new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUEST_WRITE_STORAGE);
}
Implement Override onRequestPermissionsResult method for checking is the user allow or denie
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
//Checking the request code of our request
if(requestCode == REQUEST_WRITE_STORAGE){
//If permission is granted
if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
//Displaying a toast
Toast.makeText(this,"Permission granted now you can read the storage",Toast.LENGTH_LONG).show();
}else{
//Displaying another toast if permission is not granted
Toast.makeText(this,"Oops you just denied the permission",Toast.LENGTH_LONG).show();
}
}
Before starting your download check your runtime permissions and if you don't have permission the request permissions like this method
requestStoragePermission()
private void requestStoragePermission(){
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
android.Manifest.permission.READ_EXTERNAL_STORAGE))
{
}
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
STORAGE_PERMISSION_CODE);
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String[] permissions,
#NonNull int[] grantResults) {
if(requestCode == STORAGE_PERMISSION_CODE){
if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
}
else{
Toast.makeText(this,
"Oops you just denied the permission",
Toast.LENGTH_LONG).show();
}
}
}
In a simple way the permission can be granted using manifest.xml file, but it was ok till the api level 23 sdk version 6, after from here, if we want to get the permission we have to ask for the use to allow the permission which are needed.
Just add this code in the mainActivity.java
Override
public void onClick(View view) {
// Request the permission
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CAMERA},
PERMISSION_REQUEST_CAMERA);
Replace CAMERA or add with WRITE_EXTERNAL_STORAGE if you want, and with the unique code.
new String[]{Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE},
101);
This is the simple code to get permission.

Marshmallow permissions should ask only if not already granted

I'm developing an app that require multiple permissions, so i added it and did marshmallow code too, but the problem is when i re-open an app in marshmallow it always ask for permission, i want to ask only if its not granted.
kindly help me to code for it, Thanks in Advance!
Just check for the permission and only request if neccessary.
Check permission with the help of
checkSelfPermission(Manifest.permission.READ_CONTACTS)
Check if permission is already granted or not
if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant
return;
}
Then handle the permission
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! do the
} else {
// permission denied, Disable the
// functionality that depends on this permission.
}
return;
}
}}
the Permission system has changed. But here is a good explanation how to deal with it properly.
https://developer.android.com/training/permissions/requesting.html
This way the dialog is only opened once if the user grants permission. If he declines you have a option to show a explanation the next time the permission is requested.
They also have a section with best practices that is worth to read:
https://developer.android.com/training/permissions/best-practices.html
public Boolean marshmallowPermission(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkPermission()) {
Toast.makeText(this,"Permission already granted.", Toast.LENGTH_SHORT).show();
} else {
requestPermission();
//marshmallowRequest();
}
}
return true;
}
#TargetApi(Build.VERSION_CODES.M)
public boolean checkPermission(){
int phone= checkSelfPermission(android.Manifest.permission.CALL_PHONE);
if (phone == PackageManager.PERMISSION_GRANTED ){
return true;
} else {
return false;
}
}
#TargetApi(Build.VERSION_CODES.M)
private void requestPermission(){
if (shouldShowRequestPermissionRationale(android.Manifest.permission.CALL_PHONE)){
Toast.makeText(this," Permission must be needed which allows you to access an app. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", this.getPackageName(), null);
intent.setData(uri);
this.startActivity(intent);
} else {
requestPermissions(new String[]{android.Manifest.permission.CALL_PHONE},101);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 101:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"Permission Granted, Now you can access an app.",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this,"Permission Denied, You cannot access call.", Toast.LENGTH_LONG).show();
}
break;
}
}
Follow these steps :
Create a group of permission you need to access.
Pass the group/array to check permission granted or not
Sample code for your reference :
public static boolean hasPermissions(Context context, String[]permissions) {
if (android.os.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;
Above code will check your group of permissions later pass these all to ask for once
int PERMISSION_ALL = 1;
//create all permissions array
String[] PERMISSIONS = {Manifest.permission.READ_CONTACTS, //all your permissions};
//Now check whether permissions are granted or not
if(!hasPermissions(this, PERMISSIONS)){
ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL);
}
Hope this will works out for you.

Categories

Resources