I need to access to programmatically turn ON & OFF Power Saving Mode in android.
Is there any API for this ? As I can see Power Saving mode option is not available
for all mobile devices, is there any code to check these settings availability and if available then turn it ON and OFF ?
Also is there any work around ?
If you want to test the Power Saving Mode (PSM):
The following works with Android Studio 3.4.1 and a Google Pixel 2 XL phone:
$ adb shell dumpsys battery unplug # a charging device cannot enter PSM
$ adb shell settings put global low_power 1 # enter Power Saving Mode (PSM)
This only works on devices that has the standard Power Saving Mode, like Samsung's, but not Huawei's, for example. On some Samsung devices, this setting is stored in global setting keyed psm_switch, as mentioned above.
You can leave PSM by setting low_power to 0 or by enabling charging again with:
$ adb shell dumpsys battery reset
Source: https://developer.android.com/training/monitoring-device-state/doze-standby#testing_doze_and_app_standby
It's bad practice to control the user's device settings from your app.
Rather consider suspending background services when battery levels are low.
Or to notify the user of low battery power and advising the user to switch of unnecessary settings like Bluetooth or WiFi.
Most devices won't have a built-in power-saver API, so you could try to make your own power-saver mode by turning off the bluetooth if it's on, the wi-fi, etc, deactivating location in settings, or checking for other power-eating options enabled.
There are no available API's to do this in android SDK. however You can control/save the power by Turning off Blutooth,Wi-Fi and other unused sevices inside your coding.
You can't set the power saving mode programmatically. Allowing this would be a bad idea.
On certain Samsung devices you can check if it is enabled:
final String result = Settings.System.getString(getContentResolver(), "psm_switch");
Log.v("Debug", "Powersaving active: " + TextUtils.equals(result, "1"));
See this for more info: https://stackoverflow.com/a/39296959/3600178
Related
I am working on Preferred Network Mode Settings in AOSP code. I have to change the network mode to 4g, 3g or 2g based on selection from the UI without switching on/off Airplane mode or rebooting the device.
For 2g scenario I am setting NETWORK_MODE_GSM_ONLY by setting networkmode to '1'. But still whenever I select 2G, It shows 'E' in the status bar icon and changes to '3G' in just 1 or 2 seconds.
mTelephonyManager.setPreferredNetworkType(mSubId, 1);
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.PREFERRED_NETWORK_MODE + mSubId, 1)
I even tried in phone settings on typing *#*#4636#*#*, selecting 'GSM only' there, then also the behavior is same. The behavior is same even after turning on/off Airplane mode or rebooting the device.
Please Let me know if anyone has seen any issue like this, and where i might be going wrong.
I tried this command "adb shell settings list global | findstr preferred" and below was the output
preferred_network_mode1=1
preferred_network_mode=9
I even tried from adb using "adb shell settings put global preferred_network_mode 1" but didn't help.
later the output was
preferred_network_mode1=1
preferred_network_mode=1
But there was no change in behavior.
Please help me in understanding why this issue is occuring and Kindly enlighten me with what is difference between preferred_network_mode, preferred_network_mode1 and preferred_network_mode2.
this has many similar questions (google for: "no internet access detected. won't automatically reconnect." or: android force wifi connection programmatically).
i thought i had a answer here, but it stopped working after installing 6.0.1 updates (i have may 1 security patches).
seems like this is a behaviour change.
i have some 2013 nexus 7's with 6.0.1 that run a kiosk type app and want to connect programmatically to a specific wireless network that has no internet connection. each tablet has a unique static ip address of the form: 192.168.0.xx. i use the normal java socket constructors and check to see if the interface is up using: NetworkInterface.getNetworkInterfaces().
a manual connection has been made. sometimes there is a dialog that asks whether or not you want to always connect. i always check yes.
but the wifi says: "no internet access detected. won't automatically reconnect" after the router cycles power.
doing a disconnect, enable, reconnect does not work. at best it gets: ip6-localhost/::1.
has anyone had any luck using a request object, or bindProcessToNetwork?
edit: related.
edit: the problem seems to be with: CAPTIVE_PORTAL_DETECTION_ENABLED - this string seems to be defined in the source:
public static final String
CAPTIVE_PORTAL_DETECTION_ENABLED = "captive_portal_detection_enabled";
...
MOVED_TO_GLOBAL.add(Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED);
but throws" android.provider.Settings$SettingNotFoundException: captive_portal_detection_enabled when used explicitly and is not visible to android studio.
also, doing a settings list global does not contain the constant.
edit doing a adb shell settings put global captive_portal_detection_enabled 0 does seem to work, but this can not be done in the field when the router cycles power. this value seems to persist when the tablet cycles power. and now this value shows up in a settings list global. also, using the raw string: Settings.Global.getInt(getContentResolver(),"captive_portal_detection_enabled"); now returns 0.
edit: looks like setting it requires: android.permission.WRITE_SECURE_SETTINGS, but of course this fails when put into the manifest since we are not a system app.
edit: trying to exec the shell command throws: java.lang.SecurityException, so it looks like you need to issue the command from adb :(
thanks
Could you try and set the global setting captive_portal_detection_enabled to 0 (false).
What's actually happening is that by default, everytime you connect to a wifi, the FW will test against a server (typically google) to see if it's a captive wifi (needs login). So if your wifi is not connected to google, this check will fail. After that, the device knows that wifi has no internet connection and simply will not autoconnect to it.
Setting this setting to 0, will avoid this check.
Programatically Settings.Global.putInt(getContentResolver(), Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED, 0);
You can do it through adb for testing purposes:
adb shell settings put global captive_portal_detection_enabled 0
And retrieve it's value like this:
adb shell settings list global | grep "captive"
IMHO this is not very nice thing to do, since you are changing a setting for the user and many FWs don't provide even an advanced setting to enable/disable this by the user itself. (Google doesn't). But maybe it suits your needs.
Hope it helps!
A non-root solution which is a kind of hack tech. :P
Reboot phone, connect to the non-Internet Wifi;
Go to Settings and create a new user;
Continue, continue, and continue until you see "Checking connection";
As soon as you see "checking connection", switch off your phone;
Switch on your phone again, you will be in "Owner" user, keep it;
Toggle Wifi, and the exclamation mark should disappear quickly :)
Remove that new user or just leave it there;
I don't know why, but it works...
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.
I'm trying to change in my emulator the battery status as capacity and ac status but isn't working.
I made the whole steps:
1) Connected to the emulator via telnet;
2) Tried to use the commands such power ac off and power capacity 70
3) Every time I checked the power display, the same configuration appears and no change I input is save, and the emulator always show the battery with a "!".
FR I saw this link Change emulator battery level in Windows, tried it and nothing resolved.
Follow my data about the battery:
power display
AC: online
status: Not charging
health: Dead
present: false
capacity: 0
Thank you!
It seems like your emulator device has battery option turned off.
You can change AVD battery configuration through:
Open AVD configuration file:
Default location for Linux/MAC
~/.android/avd/<AVD name>.avd/config.ini
Default location for Windows XP
C:\Documents and Settings\<user>\.android\avd\<AVD name>.avd\config.ini
Default location for Windows Vista and later
C:\Users\<user>\.android\avd\<AVD name>.avd\config.ini
Change the line:
hw.battery=no
to
hw.battery=yes
You made right. I did it on my computer and sometimes it did not worked too, I just had to set battery status to discharging before setting its capacity.
power status discharging
Additionally there is a nice tutorial that could help you with additional commands:
http://www.stealthcopter.com/blog/2010/07/changing-the-battery-percentage-in-an-avd-android-virtual-device-emulator/
How could I programmatically set data roaming on/off in my android application ?
Apologies in advance for reopening a dead post but I have managed to achieve it by calling this executable:
su -c settings put global data_roaming0 1
Also to get the roaming setting for first SIM card:
su -c settings get global data_roaming0
If your app is signatureOrSystem/Privileged app (app resides in /system/priv-app) and your have valid android.permission.WRITE_SECURE_SETTINGS permission in system/etc/permissions. Then you can do it as below.
Enable :
Settings.Global.putInt(context.getContentResolver(), Settings.Global.DATA_ROAMING, 1)
Disable :
Settings.Global.putInt(context.getContentResolver(), Settings.Global.DATA_ROAMING, 0)
I hope that it's not possible to turn on data roaming programmatically as this would be a serious security issue from my point of view ...
Data roaming (i.e. UMTS data transfer via a foreign network) may result in a huge bill from your network provider - at least in europe.
If data roaming is currently on, then I think you can manipulate the Access Points Names in order to make it appear that a data service isn't available. See this post which also links to apndroid. You could browse their source and see the approach they have taken.
If data roaming has been set to off by the user, then this approach won't work. Though you could prompt users to turn it on as part of your install/setup process, which is the route apndroid take.
apndroid also provide an API for changing these kind of settings, which might be more convenient than reimplementing the same functionality.
On rooted devices when using su to enable data roaming, on multi sim devices the data roaming setting is sim specific.
So you need to get the sim number that is active for data calls
sim_num = settings get global multi_sim_data_call
and use this in the data_roaming + sim_num setting. EG sim_num 3
settings get global data_roaming3
if this is null then not multi sim device and use data_roaming otherwise use
settings put global data_roaming3
I was able to enable data roaming on my dual sim Motorola G8 without the need to root it via ADB. I'm posting here the procedure, because the phone has a bug that prevents data roaming from being enabled normally.
You need a computer and to install ADB installed
Enable developer mode and USB debugging in your phone
Connect the phone to the computer via USB and accept the debugging connection.
Start an "adb shell", be sure that it is correctly connected to your phone.
Issue the command
settings put global data_roaming1 1
to enable data roaming for SIM card 1, or
settings put global data_roaming2 1
to enable it for SIM 2
Note: if you do not have the USB cable, this can be done via wifi, but the pairing process is a bit complicated and version dependent.
If you do not have a computer, it may be possible to run the commands directly on the phone using a "local adb" app (there are a few on the play store), but I have not tested any.