Allow wifi data while sleeping and wake device - android

I searched and was not able to find the answer to this question. I am working on app that will run all the time. I am using wifi and everything works fine until the device sleeps. One device sends out multicast packets and the other one should get them and wake up but it is not. Right now the network thread is started from a service thread started by StartService() from my main class. IN the service I get a wifi lock and a wifi multicast lock so that wifi and multicast "should" stay on when the device sleeps. I also tried adding a partial wake lock to the mix but still nothing works. Any ideas? I am devleoping on two nexus ones running android 2.3.3 right now.

You need to set the PowerManager.ACQUIRE_CAUSES_WAKEUP flag in your WakeLock, however PowerManager.ACQUIRE_CAUSES_WAKEUP flag doesn't work with PowerManager.PARTIAL_WAKE_LOCK, but it should work with PowerManager.SCREEN_DIM_WAKE_LOCK.
Below code should wake the display and CPU of your device, when you call acquire() on the WakeLock. The 5 second sleep should give your WiFi enough time to wake.
WakeLock lock = ((PowerManager) getSystemService(POWER_SERVICE)).newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
lock.acquire();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
// do work here..
lock.release()

Related

Android check is bluetooth in doze mode

Good day.
I would like to know if the bluetooth scanning is unavailable now (locked by doze mode?).
Now i check it by this method:
fun isInDozeMode(context: Context) : Boolean {
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && powerManager.isDeviceIdleMode
}
But this method returns true even if i receive bluetooth (iBeacon) event just now.
Bluetooth is not directly affected by Doze mode:
Doze does not affect the ability to do bluetooth scans or run Handler-based timers, but it does affect the ability to use the Android AlarmManager system, which some beacon-based systems use to schedule bluetooth scans. For apps based on the Android Beacon Library, the disabling of Alarms does not cause problems in scanning for beacons because it only uses Alarms as a backup should Handler-based timers fail. Tests on a Nexus 9 running the third preview release of Android M (build number MPA44l) show that beacon detection continues normally under Doze.
See my blog post here. While that blog post was written for Android 6.0, subsequent doze changes added in 7.0 also do not affect Bluetooth scanning. See here.
Detect when the app enters/exits idle mode due to Doze
The OS will send a DEVICE_IDLE_MODE_CHANGED broadcast so we can track when the app has entered or exited idle mode.
Note: This broadcast will be sent when the device occasionally starts or ends the 10 minute idle maintenance window.
See: https://developer.android.com/reference/android/os/PowerManager.html#ACTION_DEVICE_IDLE_MODE_CHANGED)

What is causing multicast messages not to flow immediately after wifi restart

I have an Android app that creates a MulticastSocket, joins a MC group and receives messages from another machine on the local wifi network.
MulticastSocket socket = new MulticastSocket(null); // Create an unbound socket.
socket.setSoTimeout(LISTEN_TIMEOUT_MILLIS);
socket.setReuseAddress(true);
socket.bind(new InetSocketAddress(listenPort)); // Bind to the configured multicast port
final WifiManager.MulticastLock lock = wifiManager.createMulticastLock("my_lock");
lock.acquire();
socket.setNetworkInterface(networkInterface);
socket.joinGroup(multicastGroup);
while (true) {
socket.receive(packet);
// Do something with the packet
// Handle timeout etc.
// Handle change of network interface by leaving group, setting netIntf and joining group again.
}
socket.leaveGroup(multicastGroup);
socket.close();
lock.release();
Works well on most Android devices (Huawei, Samsung), but on some (Pixel3), if the WiFi on the device is switched off and then back on again, while the app sees the Wifi connection come live, it can take up to 14 mins (it is extremely variable) before the MC messages start being received again.
Even throwing away the Socket and creating a fresh MCSocket doesn't alleviate the delay.
But it has to be some state that is held within the JVM, because a restart of the app causes it to connect immediately.
It feels like there is some lease that is being held for the MC connection that is only being renewed on a clock cycle.
So my questions are:
What is causing the MC messages to not flow immediately after the
WiFi connection comes back up and a new MCSocket is created to
listen to it.
What can I do to ensure timely resumption of the message flow?
I notice you've updated your question to include WifiManager.MulticastLock
I wonder if you are you reacquiring the lock when the Wifi connection comes back, some posts here on SO imply this is necessary.
I note the comment on the following post:
Re: https://stackoverflow.com/a/4002084/1015289
it turns out that your multicast lock is destroyed when the connectivity goes away (the long delay was me rewriting my code three times before I figured this out). So, you have to reacquire the lock every time the connection comes back

Internet connection paused after Android phone lock

I am building application which can get location using NETWORK_PROVIDER periodically in background without using GPS_PROVIDER. I am using ALARM_SERVICE and WakeLock(PARTIAL_WAKE_LOCK). but the problem which i am facing is that internet connection gets disconnected once the screen goes off. when I unlocks the phone I starts receiving the location, but when the screen goes off I am not getting the locations.
Is it because:
Internet connection gets paused once the screen goes off and also when I unlocks the screen I get the USSD code messages of Data Usage, so does it means my internet connection goes off once the screen goes off?
Even though the internet connection is on but location doesn't gets updated in background as the screen is in off state.
I am using GpsTracker class to get location from here and using AlarmManager get location periodically. also in LatLongBroadcastReceiver class i am fetching a location.
Intent intent = new Intent(GPSlatlongActivity.this,
LatLongBroadcastReceiver.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
pendingIntent = PendingIntent.getBroadcast(
GPSlatlongActivity.this.getApplicationContext(), 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(),
(AlarmManager.INTERVAL_FIFTEEN_MINUTES / 15),
pendingIntent);
According to documentation WifiManager.WifiLock
Allows an application to keep the Wi-Fi radio awake. Normally the Wi-Fi radio may turn off when the user has not used the device in a while. Acquiring a WifiLock will keep the radio on until the lock is released. Multiple applications may hold WifiLocks, and the radio will only be allowed to turn off when no WifiLocks are held in any application.
I guess you need this lock. Acquire this lock if the device is connected to WiFi. But please
Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane Mode. They simply keep the radio from turning off when Wi-Fi is already on but the device is idle.
Unless your application has a very good reason to keep a Wi-Fi connection, you should really try to respect the user's preference to disable WiFi when the screen locks. Your application will quickly cause the device to consume significantly more power by using any sort of lock. As mentioned by others, in your case, you'll need the PowerManager.PARTIAL_WAKE_LOCK to keep the CPU running (without preventing the screen from locking) and WifiManager.WakeLock to keep Wi-Fi connected.
You'll probably find the setting causing this behaviour under the system settings for Wi-Fi, under advanced Wi-Fi settings:
By disabling this setting on a device with mobile data, your network location listener should still work as Android will continue to use Google's Location API in the background to resolve the device's location based on cellular towers.
If your device is also switching off mobile data, perhaps some power-saving application is disabling it. BlueEFFICIENCY and Juice Defender are some apps that have an option for this optimization, but HTC and Sony have included some power saving
options on their devices that may also be exhibiting this behavior.

Android audio streaming getting interrupted when lock screen

I'm having a problem with my app when I try to stream musics on background and it only occurs on some devices.
When the app plays any music on foreground it works without problems, but in some devices, when I press the power button, the stream immediately loses its quality (looks like when I'm on a low speed internet connection). When I turn on the screen the stream gets better again.
I've already tried WakeLocks but it didn't work.
Edit 1:
This is how I used the wake locks:
OnCreate of my activity:
//Setting the wakelock
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
and than I do this when the music starts:
wl.acquire();
and this when the stream stops:
if(wl.isHeld()){
wl.release();
}
Edit 2:
Tried this as well:
mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
Edit 3:
Tried with WiFi Locks too:
//Setting the proper lockMode depending on the android version:
int wifiLockMode = WifiManager.WIFI_MODE_FULL;
int sdkVersion = Build.VERSION.SDK_INT;
//WIFI_MODE_FULL_HIGH_PERF was added on Android 3.1 so
//I need to implement this to make sure the wifi will execute on its full power(even if it consumes more battery)
if (sdkVersion >= Build.VERSION_CODES.HONEYCOMB_MR1) {
wifiLockMode = WifiManager.WIFI_MODE_FULL_HIGH_PERF;
}
//Setting the WifiLock
WiFiManager wm = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
WifiLock mWiFiLock = wm.createWifiLock(wifiLockMode, "MyFlag");
mWiFiLock.acquire();
//Releasing the WifiLock
if(mWiFiLock.isHeld()){
mWiFiLock.release();
}
With the WifiLock it seems to be a little better(or I'm getting used to the interrupted sound)
Any ideas?
I had the same quality issues with Nexus 4 using android 4.3 and discovered that the problem was solved if I turned off the "wifi optimization": Wi-Fi-> Advanced -> Wi-Fi optimization.
Seems consistent with this other threads:
https://code.google.com/p/android/issues/detail?id=42272#c319
http://forum.xda-developers.com/showthread.php?t=2072930&page=55
If this is true, wifi lock is not preventing the wifi optimization. I also tested that the wake lock is not required to stream quality music with screen turned off, at least with Nexus 4.
I think that you cannot do something really because I think that each OEM rewrite it's "battery optimization" rules that will try to preserve battery when the screen is OFF.
The best thing to do is to follow Android Standard about MediaPlayer's wakelock system and cross your finger :)

How to keep CPU from 'sleeping' when screen is turned off in Android?

I have an application in which I am sending network data over WiFI. Everything is fine until I turn the display off or the device goes to 'sleep'. I'm already locking the WiFi however, it seems to be the case that the CPU speed ramps down when in sleep which causes my streaming to not behave properly (i.e. packets don't flow as fast as I would like as they do when the device is not sleeping).
I know that I possibly can/possibly should address this at the protocol level however, that might possibly not be possible as well...
Is there any way to "prevent the CPU from going to 'sleep' when the screen is off"? If so, how? If not, any advice on how to keep the speed of my WiFi stream consistent whether the device is in sleep mode or not?
Grab a PARTIAL_WAKE_LOCK from the PowerManager. You'll also need to add the WAKE_LOCK permission to your manifest.
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Tag");
wl.acquire();
//do what you need to do
wl.release();
Okay, so, after much more research and experimenting, it seems that the real issue is the fact that, at least on some phones, their WiFi goes into a 'partial sleep' mode EVEN IF you've taken the WiFi lock. It seems that this is what the 'WIFI_MODE_FULL_HIGH_PERF' flag was invented for when taking the WiFi lock... unfortunately, this flag is only available on some devices/Android versions (I have no clue as to which but, it wasn't available to me). So, therefore, it isn't a fix for all devices.
The only "solution" (which is actually a kludge) seems to be to 'detect when the screen is turned off and then, set an alarm that turns the screen back on immediately thereafter'. The links that helped a little bit with this are:
How to keep a task alive after phone sleeps?
and
http://android.modaco.com/topic/330272-screen-off-wifi-off/
I hope that this helps people who are experiencing WiFi disruption when the phone goes to sleep/screen is turned off (and the phone is unplugged/disconnected [e.g. you won't see this effect when connected to adb; only when the phone is running with nothing connected to it]).

Categories

Resources