I was wondering if there is a way to deep-link to app`s specific settings when asking for permission.
For example, I do the following to ask the user to grant accessibility permission.
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivity(intent);
The issue is that(And this is the case on Samsung S10 for example) That this takes me to general Accessibility page, after this the user still need to tap on installed Services button and then they need to find and tap on my application and only then they can grant the accessibility permission.
I was wondering if there is a way to shorten this and take them directly to my specific application accessibility granting page.
If you want open directly the settings of your app, you can use the next code:
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", "yourPackageName", null);
intent.setData(uri);
startActivity(intent);
Related
How to get if user enable the permission from setting page of application
For Example
Consider a app has permission activity. In permission activity it show location permission default dialog. when user allow the permission I proceed the further steps. When user denied the permission, Then I show the permission dialog again. When user permanently denied. I redirect to app settings page using below code
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
How to get If user enable the particular permission from the settings page of app like get result from Activity Result.
The application details settings intent does not provide any activity result.
You need to keep track of what permissions were granted before starting the details settings intent and comparing that to what permissions are granted when your activity resumes.
To do this, you can use checkSelfPermission
I am writing an Android launcher that does not support widgets, but it does support shortcuts. One of the shortcuts provided by AOSP is Direct dial, and my launcher needs the android.permission.CALL_PHONE permission for that. My question is, are there any other permissions that I need to add, to allow all possible shortcuts, even those provided by third party apps?
FOR NOUGAT SHORTCUTS ( API LEVEL 25+ )
There is not standard permission to add/launch shortcuts. If target api level of your app is 25+, you can use ShortcutManager or static shortcut via .xml meta-data.
https://developer.android.com/guide/topics/ui/shortcuts.html
FOR LEGACY SHORTCUTS ( BELOW API LEVEL 25 )
If you want to install&use Legacy shortcuts without user interaction, you need to declare INSTALL SHORTCUT permission.
Legacy shortcuts use Intent Action:
Create shortcut for Launcher: "android.intent.action.CREATE_SHORTCUT"
Install shortcut on Launcher: "com.android.launcher.action.INSTALL_SHORTCUT"
Required permission on AndroidManifest.xml:
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
You can find more resources when you search for intent actions above.
There is no way to know this in advance. Some apps just assume that the caller of their shortcuts have some permissions (e.g. some system launcher shortcuts often only work in the system launcher itself, as they sometimes require some self defined permission).
In general, any app that offers shortcuts, should run the code in itself instead of the calling app to be sure the required permissions are present, but apparently this is not the case in some apps (especially in launchers e.g.).
I face this problem in an app of mine every now and then as well and catch the exception and tell the user, that the selected shortcut does not support other apps and is implemented in a wrong way.
Example - shortcut to call someone that works and that does not work
E.g. think about a third party app that offers a direct call shortcut. It can handle this in 2 way:
wrong way
It can return an intent like following:
Intent intent = new Intent();
Intent launchIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + number);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent);
...
This intent can ONLY be run by an app that has the action call permission
correct way
The app knows, that the caller may not have the call phone permission, so it does not return the direct phone call intent directly, but a custom one that it handles itself like e.g.
Intent.ShortcutIconResource icon = Intent.ShortcutIconResource.fromContext(this, R.mipmap.icon);
Intent intent = new Intent();
Intent launchIntent = new Intent(this, MyPhoneCallActivity.class);
launchIntent.putExtra("number", number);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(pause != null ? (pause ? R.string.shortcut_pause : R.string.shortcut_resume) : R.string.shortcut_toggle_pause_resume));
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
If the caller executes the shortcut, the MyPhoneCallActivity will be started - this runs inside the app itself and has all permissions of the shortcut provider. This activity then can simply execute the Intent.ACTION_CALL intent itself and finishes itself afterwards. This way, the calling app does not need any special permissions. The workaround via an activity is one solution for this problem that works.
This is not a definitive answer, as I couldn't find this explicitly stated anywhere, but it seems that only phone call shortcuts require a permission, so the CALL_PHONE permission is the only one you need, to launch shortcuts.
AOSP launcher only checks for the CALL_PHONE permission. Source: https://android.googlesource.com/platform/packages/apps/Launcher3/+/master/src/com/android/launcher3/Launcher.java#1630
I haven't been able to find any other types of shortcuts that require permissions.
Is there an Intent to go to my Application's "App Permissions" screen in Android-M?
I am making my App ready for Android-M and with the new permissions model. I have followed all the steps mentioned in the link
https://developer.android.com/training/permissions/requesting.html
Everything is set and all is good accept that if the user has checked the "Never ask again" button and denied permission, on next launch I want to give the user an option to go to the Application's "App Permissions" and change the permission himself, if he ever changes his mind. I wanted to make it a bit easier for the non-tech savvy user by providing a button which would take the user straight to my application's "App Permissions" screen. Is there a way? (It would be much better than giving the user instructions like Menu → Settings → Applications → Manage Applications → select application)
Thank you for helping out!
No, there is no intent to go directly to the Permissions screen.
However, just as in previous versions of Android, you can point people to your application's detail setting page using code such as:
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", getPackageName(), null));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
This will allow them to only hit a single button (the Permissions button on that screen) before they can access permissions.
Note that as per the UX around asking for permissions, consider linking to the settings page only as a last resort and only in cases where the permission is necessary for your app to function at all - ideally, you should show a strong rationale when shouldShowRequestPermissionRationale() returns true (i.e., they've denied it once but have not hit 'never ask again') such that the second time the user sees a permission dialog they know exactly why you need that permission. This means that users hitting 'never ask again' should be considered a very strong signal that the user will not ever grant you that permission.
Unfortunately this is not possible, however, as every other app does we can open the app's settings page so the user can grant the necessary permissions manually from there.
val intent = Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", packageName, null)
)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
Background
Android apps can gain some special rights using admin policies, like turning the lock screen on.
As such, those apps cannot be uninstalled till the user has revoked their admin rights.
I wish to have a function that will check if a given app (given a package name of the app) has admin rights, and if so, i will open the admin settings page of this app, to allow the user to revoke its rights.
The problem
As it turns out, there is already a function that does it.
First you get an instance of the DevicePolicyManager :
DevicePolicyManager dpm=(DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);
Then you are supposed to call isAdminActive , and get a result of true/false.
However, this function's parameter is ComponentName, meaning it needs not only the package name, but also the path to a specific class of the app.
An alternative would be to query all active admin apps, using getActiveAdmins.
Later, I you can go to the admin page using:
final Intent intent=new Intent();
intent.setComponent(new ComponentName("com.android.settings","com.android.settings.DeviceAdminSettings"));
startActivity(intent);
or even more specifically, to enable/disable the app admin rights :
final Intent intent=new Intent();
intent.setComponent(new ComponentName("com.android.settings","com.android.settings.DeviceAdminAdd"));
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,componentName);
activity.startActivity(intent);
However, both of those ways seems a bit hacky, as they do not use the official API of android, that could change over android versions and roms.
The question
What's the best way to check if a given app (package name) has admin rights?
What's the best way to go to the admin page ? is there a safer way to go there? maybe a fallback mechanism from what i've done to the security screen intent (which for some reason I can't find in the API) ?
The answer
After reading the answer on this post, I've decided to share the findings:
If you wish to be safe, you can tell the user to go to the admin screen by himself, and only guide him to the security screen:
intent=new Intent(Settings.ACTION_SECURITY_SETTINGS);
context.startActivity(intent);
however, i think the next way should work for all devices:
Intent intent=new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
final PackageManager packageManager=context.getPackageManager();
final List<ResolveInfo> resolveInfos=packageManager.queryIntentActivities(intent,0);
if(resolveInfos!=null&&!resolveInfos.isEmpty())
try
{
final ResolveInfo resolveInfo=resolveInfos.get(0);
intent=new Intent();
intent.setComponent(new ComponentName(resolveInfo.activityInfo.packageName,resolveInfo.activityInfo.name));
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,componentNameResult);
context.startActivity(intent);
return true;
}
catch(final Exception e)
{}
and if it fails, you can always use any of the methods i've written, and in the end, call the safe one.
Android apps can gain some special rights using admin policies, like turning on/off the screen.
A DevicePolicyManager can lock the screen with lockNow() and set the lock timeout via setMaximumTimeToLock(), if that's what you mean.
What's the best way to check if a given app (package name) has admin rights?
See if they are in the roster returned by getActiveAdmins(). That method returns null or List of ComponentName objects, and you can call getPackageName() on a ComponentName to compare it to your target package.
What's the best way to go to the admin page ?
There is no documented and supported way to get to this portion of the Settings app. The closest thing is ACTION_SECURITY_SETTINGS.
In one of my apps I'm using the following code to issue a phone call:
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(...));
startActivity(intent);
The docs say I do need the following Manifest permission to do so:
<uses-permission android:name="android.permission.CALL_PHONE" />
Is this really required? I do not understand the difference between a phone and a camera feature. When using a phone intent I do need a permission but I don't need permission for a camera intent:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
...
startActivityForResult(intent, 1);
Is there a list on hardware features that need a permission if fired with the help of an intent and those that don't?
Actually, if you wish to just open the dialer with a specific phone number, without direct calling (needs user confirmation), you can do it without any permission:
Uri uri = Uri.parse("tel:" + PHONE_NUMBER);
Intent callIntent = new Intent(Intent.ACTION_DIAL, uri);
try {
context.startActivity(callIntent);
} catch (ActivityNotFoundException activityNotFoundException) {
// TODO: place code to handle users that have no call application installed, otherwise the app crashes
}
Is this really required?
Yes.
I do not understand the difference between a phone and a camera feature.
Phone calls can cost people money. Hence, if you directly place a phone call (vs. ACTION_DIAL to just put the number in the dialer), Android wants the user to agree ahead of time to allow this.
Taking pictures with the camera does not usually directly cost users any money.
Is there a list on hardware features that need a permission if fired with the help of an intent and those that don't?
Not really.
When you issue a request to the camera, it merely opens an app requiring user interaction before it can do anything.
Phone calls open an app with the phone number already entered so you merely just have to press a button.
There's a much higher risk that you'll accidentally call someone than if you were to accidentally take a picture (Which you could just delete if taken accidentally.)