Programmatically enable Mock Locations - android

Is there any possible way to enable mock locations on Android without having to do it through the settings app? I would like to try and turn on Mock Locations directly from my app. So I was wondering if there is an API for that or if there was some sort of Intent I could use.

Prior to Marshmallow, "allow mock locations" setting could be changed programmatically (but it requires root):
Settings.Secure.putInt(getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, 1);
So, unfortunately, the best you can do is point the user to the actual screen where the mock location app is set using the code below:
startActivity(new Intent(android.provider.Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS));

There is no way to do that "programmatically" unless the device is rooted.

Process proc = Runtime.getRuntime().exec(new String[]{"su","pm grant YOUR_APP_PACKAGE_NAME android.permission.WRITE_SECURE_SETTINGS", "settings put secure mock_location 1"});
proc.waitFor();
int value = Settings.Secure.getInt(getContentResolver(),
Settings.Secure.ALLOW_MOCK_LOCATION);
SOP.OUT("mock_location::::::::::::::::::::::::::::::::: " + value);
works only on rooted device

On Android 6+ you can run shell command appops to allow certain app to mock locations:
adb shell appops set <PACKAGE> android:mock_location allow
For example:
adb shell appops set ru.gavrikov.mocklocations android:mock_location allow
I'm not a developer and not sure that you can do this from within your app, but I guess running Runtime.getRuntime().exec(cmd) with root privelege would work.

Related

Android 5.0 how to automatically obtain permissions when recording the screen?

MediaProjectionManager.createScreenCaptureIntent();
When sharing the screen, a window asking for permission will pop up.
I am looking for a way to automatically obtain all content (permissions) on the screen.
I have root access to this device!
Thanks in advance!
If this is for testing where you have ADB access to the device – the media projection checks the OP_PROJECT_MEDIA AppOps (code), and you can enable it through ADB like this:
adb shell cmd appops set <your.package.name> PROJECT_MEDIA allow

Remove Permissions at runtime

I am trying to make a form where people can toggle notifications on and off. I figured the easiest way to do that would be set the permissions to allow or deny but I can't figure out how to remove the permission once it has been granted.
I am triggering the initial permission request by doing the following in android and not too sure what I will do with iOS as it requests the permissions somewhat automatically.
string rec = "android.c2dm.intent.RECEIVE";
string reg = "android.c2dm.intent.REGISTRATION";
ActivityCompat.RequestPermissions(Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity, new string[] { rec, reg },0);
I essentially would like a page that has a few Switch controls to enable/disable permissions.
any help would be greatly appreciated.
Thanks,
There's no built in method for you to toggle a permission (ie, allow, then disallow), but you could do it if your app can run an adb command.
To undo a permission:
adb shell pm revoke <package_name> <permission_name>
https://stackoverflow.com/a/32683390/6668797
To run an adb command within your app, a couple of variations, but all involve:
Process process = Runtime.getRuntime().exec("your command")
how to run adb shell commands from android code?
Is it possible to execute adb commands through my android app?

how to turn on / turn off developer mode in Android from app?

I want to create an app to turn on/turn off Android developer mode. This will be on a rooted device. What api's do need to call?
I know i am answering it very late but i will surely help other who are searching on this.
To enable developer options programatically :
Settings.Global.putString(this.getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, "1");
To disable :
Settings.Global.putString(this.getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, "0");
But to access this Settings.Global... , it requires a permission
android.permission.WRITE_SECURE_SETTINGS
But normally , This permission is only granted to system app
You can also grant this permission to user app using ADB
Since you said your app would be running on a rooted deice , so have access to the shell , so you can grant this permission to your app by running the below shell command
pm grant <your.package.name> android.permission.WRITE_SECURE_SETTINGS
I don't think it is possible. Since it is part of the Settings.Secure.
Secure system settings, containing system preferences that applications can read but are not allowed to write. These are for preferences that the user must explicitly modify through the system UI or specialized APIs for those values, not modified directly by applications.

Can't set value of location_providers_allowed using "adb shell settings put"

I'm trying to turn location on using the following commands:
adb shell settings put secure location_providers_allowed gps,wifi,network
adb reboot
But it's neither changing the value of the variable location_providers_allowed nor turning it on under Android Settings UI after the reboot.
I tried the same command to set other variables, like mock_location, and it worked without problems.
Is this variable not possible to be changed?
Android version: M
I have yet to solve this problem, but wanted to provide additional information that I feel is relevant and may help somebody else solve this.
I tried to follow this, but it was mentioned in one of the comments that:
This used to work on Android 5, but it doesn't anymore on Android 6. With or without root the setting does not change and stays the same as is configured on the system. It probably has something to do with location_providers_allowed being deprecated (developer.android.com/reference/android/provider/…) – gw0 Nov 4 '15 at 7:45
I looked into the docs for Settings.Secure location_providers_allowed and sure enough:
This constant was deprecated in API level 19. use LOCATION_MODE and MODE_CHANGED_ACTION (or PROVIDERS_CHANGED_ACTION)
I tried to set location_mode but had no effect on enabling/disabling location services.
When turning on/off location services manually through the location_providers_allowed flag is affected, not location_mode. I find it weird that the docs say it's deprecated, but it's still used and location_mode
isn't.
That's all I got.
For Android 6.0
To Enable use :
For GPS : adb shell settings put secure location_providers_allowed +gps
For Network : adb shell settings put secure location_providers_allowed +network
To Disable :
GPS : adb shell settings put secure location_providers_allowed -gps
For Network : adb shell settings put secure location_providers_allowed -network
From Android 6 up-to Android 9 you can manipulate "location_providers_allowed" if you have WRITE_SECURE_SETTINGS permission.
From Android 10, this has no effect whatsoever as described here (search Android Q): https://developer.android.com/reference/android/provider/Settings.Secure#LOCATION_PROVIDERS_ALLOWED
There is a new API, but it doesn't have any public way to change any settings: https://developer.android.com/reference/android/location/LocationManager#isProviderEnabled(java.lang.String)
Maybe with root or as system app, one can access this:
#SystemApi
#TestApi
#RequiresPermission(WRITE_SECURE_SETTINGS)
public void setProviderEnabledForUser(String provider, boolean enabled, #NonNull UserHandle userHandle);
EDIT: This work perfectly as system app. Haven't tried with root.
I solved this by pulling /data/system/users/0/settings_secure.xml
change value in the xml of the setting below to gps,network or what you want
<setting id="0" name="location_providers_allowed" value="" package="android" />
than push it back to same place and reboot

Programmatically enable/disable "Battery Saver" mode

I am trying to find if I can enable and/or disable Android's built-in "Battery Saver" mode programmatically.
Any official approaches, or trickery, are welcome.
For reference, here is how to do it following Android's standard UI in 5.0:
http://www.androidcentral.com/android-50-lollipop-basics-how-get-more-life-between-charges-battery-saver
I am aware you can detect it -- that is not what I am after.
Thanks all.
You can enable/disable Battery Saver programmatically on rooted devices. You have to edit the low_power value in global table, in /data/data/com.android.providers.settings/databases/settings.db file.
If your device supports settings command, you can execute (as root):
settings put global low_power 1
to enable Energy Saver and
settings put global low_power 0
to disable it.
If it doesn't, use sqlite3 command:
sqlite3 /data/data/com.android.providers.settings/databases/settings.db "update global set value='1' where name='low_power';"
sqlite3 /data/data/com.android.providers.settings/databases/settings.db "update global set value='0' where name='low_power';"
Remember that you have to unplug your phone from PC first, otherwise system will disable Energy Saver. Use ADB over WiFi or Android Terminal (Emulator).
UPDATE:
The sqlite3 method doesn't seem to be reliable anymore.
I'm not sure if android.os.action.POWER_SAVE_MODE_CHANGED broadcast gets send. Maybe you have to send it manually, like in code from here:
private static String COMMAND_ENABLE = "settings put global low_power 1\n" +
"am broadcast -a android.os.action.POWER_SAVE_MODE_CHANGED --ez mode true\n";
private static String COMMAND_DISABLE = "settings put global low_power 0\n" +
"am broadcast -a android.os.action.POWER_SAVE_MODE_CHANGED --ez mode false\n";
Also, it's been reported that a new power_saving entry appeared in settings database, however in Android 6.0.1 I haven't managed to find it. In Android 7.1.1_r13 low_power is still used internally (e.g. here), however it may get changed in some Android release. You may want to keep checking changes in e.g. this and this file.
You cannot without rooting your phone. I am not sure why this is the case, especially where location services are required now for viewing scan results since SdkVersion 23+ .
This issue is very revealing.
https://code.google.com/p/android/issues/detail?id=185370
The best answer is application developers are being forced to crowd source network location for their google overlords. Notice, the OS itself has no problem displaying scan results without location services on.
Revealing that there is no way to turn on location services without GPS where location services are inactive. This two step shuffle is a major quality of experience issue for users. Turn location services on, then turn GPS off.
Watch this space, more lock downs on the way.

Categories

Resources