Android camera runtime permission error? - android

I am trying to use Camera2 api in my app even though i am checking runtime camera permission using the following code.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
cameraManager.openCamera(cameraId, stateCallBack, null);
} else {
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA))
Toast.makeText(getApplicationContext(), "PLease allow the app to use camera app", Toast.LENGTH_LONG).show();
}
ActivityCompat.requestPermissions(CaptureImageActivity.this,new String[]{"android.manifest.permissin.CAMERA"}, CAMERA_REQUEST_RESULT);
} else {
cameraManager.openCamera(cameraId, stateCallBack, null);
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permission, int[] grantResult) {
switch (requestCode) {
case CAMERA_REQUEST_RESULT:
if (grantResult[0] == PackageManager.PERMISSION_GRANTED) {
try {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
//this method is created because of openCamera method below i don't understand why this method is created
return;
}
cameraManager.openCamera(cameraId, stateCallBack, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
if (grantResult[0] != PackageManager.PERMISSION_GRANTED)
Toast.makeText(getApplicationContext(), "camera is not granted", Toast.LENGTH_LONG).show();
break;
default:
super.onRequestPermissionsResult(requestCode, permission, grantResult);
break;
}
}
I have also permission included in the AndroidManifest.xml file.
<uses-permission android:name="android.permission.CAMERA" />
But when i run my app the permission dialog is not showing up but camera is not granted toast is showing up.
1) Why is the permission dialog not showing up?
2) Even there is no dialog showing up how is the camera is not granted toast showing up? I have searched a lot but nothing help!

Here is the working runtime permission for camera api
private static final int PERMISSIONS_REQUEST_CAPTURE_IMAGE = 1;
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// User may have declined earlier, ask Android if we should show him a reason
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
// show an explanation to the user
// Good practise: don't block thread after the user sees the explanation, try again to request the permission.
} else {
// request the permission.
// CALLBACK_NUMBER is a integer constants
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSIONS_REQUEST_CAPTURE_IMAGE);
// The callback method gets the result of the request.
}
} else {
}
#Override
public void onRequestPermissionsResult ( int requestCode, String[] permissions,
int[] grantResults){
switch (requestCode) {
case PERMISSIONS_REQUEST_CAPTURE_IMAGE: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted
Log.d("", "permission granted success");
} else {
// permission denied
Log.d("", "permission denied");
}
return;
}
}
}

Related

Android, can't get permission for Camera dialog box to appear Marshmallow version

I can't seem to get the dialog box to pop up for camera request permission. I don't see what mistake I made. I think I followed the Android Developer document on permissions well enough yet I'm still not seeing a dialog box appear for permissions. What is wrong with the code and what can I do to fix it?
private static final int REQUEST_CAMERA_PERMISSION_RESULT = 0;
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// v checks for request code
if (requestCode == REQUEST_CAMERA_PERMISSION_RESULT){
// v check if request was granted or not
if (grantResults[0] != PackageManager.PERMISSION_GRANTED){
Toast.makeText(getApplicationContext(),
"Application will not run without camera services", Toast.LENGTH_SHORT).show();
}
}
}
private void connectCamera() {
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); //connects to camera
try {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //android version "marshmallow" requires permissions
if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_GRANTED) { //checks if permission is granted or not
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
} else { //if permission isn't granted. Tells user, app needs permission for camera
if(shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
Toast.makeText(this,
"app requires access to camera", Toast.LENGTH_SHORT).show();
}
requestPermissions(new String[] { Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO
}, REQUEST_CAMERA_PERMISSION_RESULT);
}
} else {
cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}

App is crashed on first time after granting write permission?

I struct at first page, I am not able to open Dialog soon after permission granted(Write). First time I asked Permission and I granted Permission,in onRequestPermissionsResult() I opened Dialog, here App is closed with Unfortunately APP has crashed issue. When reopen App the issue not here, It is running normally.I got issue in Monitor
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState .I Searched lot but different answers I've seen.Please help me ,I am not getting why app is crashed first time.
Here is my code:
llAddPhoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!tvAddPhotoOrNext.getText().toString().equals("Next")) { // When Image not gone selected
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//First checking if the app is already having the permission
if (isReadStorageAllowed()) {
//If permission is already having then showing the toast
Toast.makeText(AddUserProfilePic.this, "You already have the permission", Toast.LENGTH_LONG).show();
//Existing the method with return
showFourButtonsBSDialog();
}else {
//If the app has not the permission then ask for the permission
checkPermissions();
}
} else
showFourButtonsBSDialog();
} else { // When image gone selected.
mSetProfilePicByAPI();
}
}
});
#SuppressLint("InlinedApi")
private void checkPermissions() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PICKIMAGE);
} else {
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_PICKIMAGE:
//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();
showFourButtonsBSDialog();
} else {
//Displaying another toast if permission is not granted
Toast.makeText(this, "Oops you just denied the permission", Toast.LENGTH_LONG).show();
}
}
}
/* BottomSheetDialog */
private void showFourButtonsBSDialog() {
MoreOptionsDialogFragment mTBFragment = new MoreOptionsDialogFragment(); // ThreeButtonsFragment
Bundle mTextNamesArgs = new Bundle(); //Send buttons names
mTextNamesArgs.putStringArray("buttons_names",new String[]{"Take Photo","Choose from library",
"Photo from Facebook","Photo from Instagram"});
mTBFragment.setArguments(mTextNamesArgs);
mTBFragment.show(getSupportFragmentManager(),mTBFragment.getTag());
}
private boolean isReadStorageAllowed() {
//Getting the permission status
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
//If permission is granted returning true
if (result == PackageManager.PERMISSION_GRANTED)
return true;
//If permission is not granted returning false
return false;
}
What are your compile SDK and target SDK versions? Make sure them to be 23 or higher.
https://developer.android.com/guide/topics/permissions/requesting.html

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.

Camera permission is not working on Marshmallow and above devices and crashes

Since I have made a flashlight application and it works properly on the device which have SDK 22 and below. But when I come to check on marshmallow and above devices, it doesn't run and crashes at the beginning only I asked for permission using following code but it doesn't seems to be working at all. here is my code for requesting permission of camera at run time. here is my code:
if( ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.CAMERA},
5);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 5) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Now user should be able to use camera
}
else {
// Your app will not have this permission. Turn off all functions
// if permission not granted it will force close the app
}
}
I have tried in marshmallow, nougat devices but it doesnt ask for camera permission and i have to go through manually from setting-app-flashlight-permission-allow. can anyone help me please. Currently I am testing my app in Lineage os 7.1.1
You need to add the SDK 23 permission in manifest. add the below line in manifest then you will get runtime permission callback.
<uses-permission-sdk-23 android:name="android.permission.CAMERA"/>
Just you change only if condition your code is perfect like this,
if( ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{android.Manifest.permission.CAMERA},
5);
}
}
to
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if( ContextCompat.checkSelfPermission(this,
android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{android.Manifest.permission.CAMERA},
5);
}
}
if(currentAPIVersion>= 23)
{
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context,
Manifest.permission.CAMERA)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Camera Permission Necessary");
alertBuilder.setMessage("Camera permission is necessary");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((Activity) context,
new String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CAMERA);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions((Activity) context,
new String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CAMERA);
}
return false;
} else {
return true;
}
} else {
return true;
}
Use the below code and call the "requestPermission" method in onCreate of the Activity:
private static final int REQUEST_CODE_PERMISSION = 2;
List<String> mPermission=new ArrayList<String>();
public void requestPermission()
{
try {
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= MockPackageManager.PERMISSION_GRANTED)
mPermission.add(Manifest.permission.CAMERA);
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= MockPackageManager.PERMISSION_GRANTED
)
mPermission.add(Manifest.permission.WRITE_EXTERNAL_STORAGE
);
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= MockPackageManager.PERMISSION_GRANTED)
mPermission.add(Manifest.permission.READ_EXTERNAL_STORAGE);
if(mPermission.size()>0)
{
String[] array = mPermission.toArray(new String[mPermission.size()]);
ActivityCompat.requestPermissions(this, array, REQUEST_CODE_PERMISSION);
// If any permission aboe not allowed by user, this condition will execute every tim, else your else part will work
}
} catch (Exception e) {
e.printStackTrace();
}
}
Overwrite the method "onRequestPermissionsResult":
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Log.e("Req Code", "" + requestCode);
if (requestCode == REQUEST_CODE_PERMISSION) {
if (grantResults.length == mPermission.size()) {
for(int i=0;i<grantResults.length;i++)
{
if(grantResults[i] == MockPackageManager.PERMISSION_GRANTED)
{
//don't do anything....
}
else{
mPermission=new ArrayList<String>();
requestPermission();
break;
}
}
}
else{
Toast.makeText(this,"permition not granted",Toast.LENGTH_LONG).show();
mPermission=new ArrayList<String>();
requestPermission();
}
}
}
do this way:
if (ContextCompat.checkSelfPermission(UserProfileActivity.this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(UserProfileActivity.this, new String[]{Manifest.permission.CAMERA},
5);
} else {
//start flashlight
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
switch (requestCode) {
case 5: {
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
//start flashlight
Log.d("Permissions CAMERA", "Permission Granted: " + permissions[i]);
} else if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
Log.d("Permissions CAMERA", "Permission Denied: " + permissions[i]);
}
}
break;
}
default: {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
} break;
}
}
I also had the same problem but managed to fixed it. Here's my case (I don't know if its the same as yours but it's worth a try)
So I have this two activities namely: MainActivity, and FlashlightActivity.
I used to ask for camera permission explicitly in FlaslightActivity just before I tap the switch button but I forgot that I was checking if a user's phone has a camera in the onCreate() method. while I was asking for permission onClick of the switch button of the flashlight, in which that was after I checked if a user's phone has a camera. So what I did was to ask for the permission in my MainActivity just before I start FlashlightActivity.
flashBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(hasPermission()){
Intent flashIntent = new Intent("FlashlightActivity");
startActivity(flashIntent);
}else{
requestPermission();
}
}
});
So basically ask for the permission before you call any Camera related stuffs

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.

Categories

Resources