Requesting Permission dialogue not showing up at all with this code, why? - android

I am trying to request STORAGE Permission from the user at runtime after clicking a certain button. But somehow, this code (which is contained within a fragment's class) is not working at all no matter what I try.
binding.button.setOnClickListener {
requestPermissions(this.requireActivity(), "android.permission.WRITE_EXTERNAL_STORAGE", 392)
}
This piece of code isn't working either for both write and read permissions :
binding.button.setOnClickListener {
ActivityCompat.requestPermissions(this.requireActivity(), "android.permission.WRITE_EXTERNAL_STORAGE", 392)
}
No dialogue appears no matter what.
NOTE: I am testing on a physical device running on API 29.
NOTE2: I added the permission both WRITE and READ permissions to the manifest.
NOTE3: Performing any IO task crashes my app.
I looked up all over the internet but I still don't understand why it's not working.

As for your way for checking the permissions if it's inside a fragment maybe it's not correct , since these methods are deprecated and you may use another way which is the recommended one
Documentation for how to request permissions|android developers
which is the right way which goes as this:
Step 1 -You put this code as global in fragment/activity:
private final ActivityResultLauncher<String> requestPermissionLauncher =
registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
if (isGranted) doSomething()
else
Toast.makeText(getContext(), "Can't continue without the required permissions", Toast.LENGTH_LONG).show();
});
Step 2- Then when you need to request for a permission you call launch on the object you declared as global , which is to be called in the OnCreate() function of the Fragment / Activity .So if you want to ask these permissions at the creation of the fragment / Activity then just place this code in OnCreate() or if are using a button to check permission then set the onClickListener for the same in onCreate() function:
public void getNecessaryPermissionsAnddoSomething() {
if (ActivityCompat.checkSelfPermission(getContext(),
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE);
} else doSomething();
}

Related

Bring app back to foreground from code doesn't work on Android 12+

I made a Xamarin.Forms project to create and show local notifications, and it's supposed to be able to put the app back to the foreground when the notification is clicked.
The thing is, my code works on Android 11 and before, but on Android 12 & 13 the notification click is received by the app, if I have a callback for that notification it is called, but the app stays in background.
This is the part of the code that runs when I received a notification click and that I want to set the app in foreground (this is in the Xamarin Android project) :
var packageManager = Application.Context.PackageManager;
Intent launchIntent = packageManager.GetLaunchIntentForPackage(Constants.PackageName);
if (launchIntent != null)
{
launchIntent.AddCategory(Intent.CategoryLauncher);
Application.Context.StartActivity(launchIntent);
}
I have found a lot of posts on how to start/set to foreground an app, and the code I use is what's working for others, but all these posts where from 2020 and before, so no Android 12+ at the time and I can't find anything about a new way of doing this.
Does anyone have this functionality working on the newest Androids ?
I have found the solution so I'll post it here if someone needs it.
The code I use to put the application back to the foreground is correct, but I was missing the System_Alert_Window permission in my main application.
So to handle this permission I did :
Add it to my main application's manifest
Create a native method that checks if it is enabled
Create a native method that redirect the user to the overlay settings so they can allow the permission.
To check if the permission is enabled :
public bool HasOverlayPermission()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.M)
return true;
return Android.Provider.Settings.CanDrawOverlays(Application.Context);
}
To redirect the user to their phone settings for AppOverlay (this permission can only be allowed from the settings) :
public void AskForOverlayPermission()
{
if (Android.Provider.Settings.CanDrawOverlays(Application.Context))
return;
var uri = Android.Net.Uri.Parse("package:" +
Application.Context.PackageName);
Intent intent = new Intent(
Android.Provider.Settings.ActionManageOverlayPermission, uri);
_mainActivity.StartActivityForResult(intent, 101);
}
The StartActivityFromResult method is only accessible in Activity classes, so you can either write it in you MainActivity or give your MainActivity as constructor parameter of another class.
This code will directly redirect the user to the settings page, so it's better if you ask them if they want to allow this permission in a popup or something beforehand (so they can understand why they're redirected).
I have found the code in this post : How to enable screen overlay permission by default

Screen Overlay Detected | (Android 6.x) Lenovo, Redmi & Samsung Devices

I have created an app which continuously run in background and show an floating overlay TextView(By using the permission android.permission.SYSTEM_ALERT_WINDOW).
I have problem in Lenovo android devices, when other applications try to request for user permission there is an alert dialog says "Screen Overlay Detected". While I have test the same application on Redmi 3S Prime device the "Allow" button in permission dialog is not clickable, until I have turned off the Floating Overlay TextView in my application.
So is there any solution to resolve this device specific issue? One of the possible solution may be disable floating TextView while permission dialog is visible to user and show floating overlay when permission dialog is closed, but the problem is how can I detect the permission dialog open/close state for other foreground application from my app.
Please suggest...
Unfortunately it seems that this is inherent to the Android OS, and as far as I know there is no way to detect when another app is requesting permissions. The general flow for interacting with other apps is to send intents to them in a push manner, so theoretically it could be done if the other apps send an intent to your app to disable the overlay, though this is not a practical solution.
I could be completely wrong, but I am yet to see a programmatic solution to this problem. The best you can probably do is warn your users that your app may cause this problem, and provide them with a quick temporary disable button.
how can I detect the permission dialog open/close state from my app??
Implement Method Mentioned Below, to run this check at the onCreate of the first Activity
public final static int PERM_REQUEST_CODE_DRAW_OVERLAYS = 1234;
/**
* Permission to draw Overlays/On Other Apps, related to
'android.permission.SYSTEM_ALERT_WINDOW'
in Manifest
Resolves issue of popup in Android M and above "Screen overlay detected- To change this permission setting you first have to turn off the screen overlay from Settings > Apps"
If app has not been granted permission to draw on the screen, create an Intent &
set its destination to
Settings.ACTION_MANAGE_OVERLAY_PERMISSION
&
* add a URI in the form of
"package:"
to send users directly to your app's page.
Note: Alternative Ignore URI to send user to the full list of apps.
public void permissionToDrawOverlays() {
if (android.os.Build.VERSION.SDK_INT >= 23) { //Android M Or Over
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, PERM_REQUEST_CODE_DRAW_OVERLAYS);
}
}
}
Called on the activity, to check on the results returned of the user action within the settings
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PERM_REQUEST_CODE_DRAW_OVERLAYS) {
if (android.os.Build.VERSION.SDK_INT >= 23) { //Android M Or Over
if (!Settings.canDrawOverlays(this)) {
// ADD UI FOR USER TO KNOW THAT UI for SYSTEM_ALERT_WINDOW permission was not granted earlier...
}
}
}
}
NOTE:Above code and extract is taken from following gist.
Hope this Helps!!!..
Just clear data of the Es explorer from device then after restart device.
I think these two links could help you.
firstlink
secondlink
Try to use for debug build -- targetSdkVersion 22.
After signed APK (for all targetSdkVersion(s)) application will work fine.

How to integrate Google Location API with android Marshmallow runtime permissions system?

I am trying to get the user's location in my Activity using Google Location API. I have a button, on which if user taps, the location of the user should be retrieved and sent to the app backend.
As per Google's documentation, the
LocationServices.FusedLocationApi
.getLastLocation(apiClient)
method has to be called in onConnected method. However, the method throws error if I am not checking for permission granted by the user.
My problem is I am asking for permission in onClick method of my button.
I tried putting
LocationServices.FusedLocationApi
.getLastLocation(apiClient)
inside the onClick method but it returns a null object.
Is there a proper way to ask location permission from user on tap of a button and not in onCreate method of the activity and still be able to get the location of the user?
I assume you are calling :
mGoogleApiClient.connect();
in onStart(). Which calls the onConnected() method when the activity starts. You can call it on Button Click after asking run-time permission for Location. Then you will be able to getLastLocation() in onConnected() and you won't face permission error.
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)){
mGoogleApiClient.connect();
}
else{
// ask run-time permission
}
}
}
});
Hope this helps.

Provide custom text for Android M permission dialog

Is it possible to provide a custom text for the system dialog which is displayed when the user is asked to grant permission?
No, you can't customize the text of the dialog, but you can provide an explanation before request the permission. Quoting from developer.android.com:
Request Permissions
If your app needs a dangerous permission that was listed in the app
manifest, it must ask the user to grant the permission. Android
provides several methods you can use to request a permission. Calling
these methods brings up a standard Android dialog, which you cannot
customize.
Explain why the app needs permissions
In some circumstances, you might want to help the user understand why
your app needs a permission. For example, if a user launches a
photography app, the user probably won't be surprised that the app
asks for permission to use the camera, but the user might not
understand why the app wants access to the user's location or
contacts. Before you request a permission, you should consider
providing an explanation to the user. Keep in mind that you don't want
to overwhelm the user with explanations; if you provide too many
explanations, the user might find the app frustrating and remove it.
One approach you might use is to provide an explanation only if the
user has already turned down that permission request. If a user keeps
trying to use functionality that requires a permission, but keeps
turning down the permission request, that probably shows that the user
doesn't understand why the app needs the permission to provide that
functionality. In a situation like that, it's probably a good idea to
show an explanation.
To help find situations where the user might need an explanation,
Android provides a utiltity method,
shouldShowRequestPermissionRationale(). This method returns true if
the app has requested this permission previously and the user denied
the request.
We cannot customize request permission dialog but we can provide user a custom explanation that why we are requesting below is the method with custom explanation
private void checkForCameraPermission() {
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Camera permission necessary");
alertBuilder.setMessage("FITsociety need camera permission to read barcode.");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(BarCodeScannerActivity.this,
new String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CAMERA);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CAMERA);
// MY_PERMISSIONS_REQUEST_CAMERA is an
// app-defined int constant. The callback method gets the
// result of the request.
}
} else {
setBarCodeScannerView();
}
}
the above method check whether permission is already granted if not then it check if custom explanation is required with this method
ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)
the documentation for this method is here shouldShowRequestPermissionRationale() this method return true only if user deny to permission dialog or user close the permission from the setting of the application if user did so then show alert dialog with custom explanation and proceed further hope it works

Android M, not ask every start for storage permission

My app needs to access the user's storage in near to every activity. How can I access the storage without making the app ask at every app startup for the permission to access it with the new Android M permission model? (Read and write)
Thanks!
If you do not want to prompt the user "on every app startup to give memory access to be able to do anything", then don't do that. Only call requestPermissions() if checkSelfPermission() returns PERMISSION_DENIED.
#Override
public void onCreate(Bundle icicle) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)==
PackageManager.PERMISSION_GRANTED) {
init();
}
else {
requestPermissions(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
REQUEST_STORAGE);
}
}
(native API Level 23 methods shown; you may want to use ContextCompat andActivityCompat` for backwards compatibility)
Or, only call requestPermissions() if the user does something positive in the UI that needs WRITE_EXTERNAL_STORAGE (e.g., clicks an action bar item) and you do not already have the permission.

Categories

Resources