"non-static variable cannot ..." error - MarshMallow permission - android

I am trying to implement the permissionChecker for Marshmallow 6.0
In my onCreate I put the permission check method (this is where the error happens every time on onCreate(), see error below).
#Override
public void onCreate() {
Permission();
//other codes here
}
And this is INSIDE the MainActivity class and is called on onCreate()
//Permision code that will be checked in the method onRequestPermissionsResult
public int STORAGE_PERMISSION_CODE = 23;
//We are calling this method to check the permission status
public 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;
}
//Requesting permission
public void requestStoragePermission(){
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_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[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
}
//This method will be called when the user will tap on allow or deny
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
//Checking the request code of our request
if (requestCode == STORAGE_PERMISSION_CODE) {
//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();
}
}
}
public void Permission(){
////Android marshmallow new Permission Code////
if (isReadStorageAllowed()) {
//If permission is already having then showing the toast
return;
}
//If permission is already having then showing the toast
else{
requestStoragePermission();
}
}
}
This happens only if the permission is off, if I enable it manually from settings it works just fine.
" Error on main activity "
Caused by: java.lang.NullPointerException: Attempt to get length of null array
at com.nephi.motionmusicplayer_2mp.MusicService.updateSongList(MusicService.java:210)
at com.nephi.motionmusicplayer_2mp.MusicService.init(MusicService.java:323)
at com.nephi.motionmusicplayer_2mp.MusicService.onCreate(MusicService.java:110)

Related

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 camera runtime permission error?

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

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

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