13

I am currently writing an Android application which uses a webview and webrtc to transmit an Audio stream. The problem, at least on my mobile phone the connection is cut after a few minutes after the screen is turned off.

I already acquired a CPU lock and a wifi lock (verified with isHeld), but it does not make any difference.

The application is also available as a web application: Here it seems to work as expected and the connection stays alive.

I already checked the wifi settings: It is set to always on.

Any pointers/ideas greatly appreciated. The application is open source so I am happy to share any code, if that helps in any way. Lock grabbing is done with this:

private void grabWakeLock() {
  PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
  wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                                               "MyWakelockTag");
  wakeLock.acquire();
  WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
  wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "gonimo-wifi-lock");
  wifiLock.acquire();
}

I have the following permissions in my Manifest:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-feature android:name="android.hardware.camera" />

Many thanks in advance!

Update:

Android Doze seems to be the reason for this behaviour. Manually triggering Doze, results in the same behaviour. Also

    return pm.isIgnoringBatteryOptimizations(packageName);

is returning false, so network will be turned off for the app! The problem: the whitelist as described in the article does not seem to exist on my phone. I can't find it in settings and doing:

    Intent intentBattery = new  Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
    intentBattery.setData(Uri.parse("package:" + "org.gonimo.gonimo"));
    startActivity(intentBattery);

results in an Exception that the Activity cannot be found.

robert
  • 363
  • 1
  • 9
  • Almost forgot: Android version: 7.0, EMUI Version: 5.0.1 (It is a Huawei Nova) – robert Feb 09 '18 at 14:04
  • 3
    Please add what is shown in the log when 'the connection is cut'. – brandall Feb 17 '18 at 16:06
  • how did you start your audio streaming service? – user1506104 Feb 19 '18 at 10:01
  • 2
    have you tried `getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);` ? – Rahul Khurana Feb 20 '18 at 06:33
  • I am starting the audio streaming service via WebRTC in the WebView. – robert Feb 20 '18 at 13:04
  • I haven't tried getWindow() ...., I will look into this function. Although it is not what I want. I want the display to go off, I just want the stream to stay alive. – robert Feb 20 '18 at 13:08
  • Logs: http://lpaste.net/362689 I don't know how I missed that, there are a whole bunch of those messages: chromium: [INFO:socket_host_udp.cc(403)] sendto() has failed twice returning a transient error net::ERR_ACCESS_DENIED. Dropping the packet. The disconnect happened around: 14:12:00 . – robert Feb 20 '18 at 13:21
  • also interesting in the logs: 02-20 14:12:29.182 17523 17523 I chromium: [INFO:CONSOLE(252)] "WebSocket connection to 'wss://b00.alpha.gonimo.com/' failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", source: (252) 02-20 14:12:29.183 17523 17538 D HaskellActivity: [INFO:CONSOLE(252)] "WebSocket connection to 'wss://b00.alpha.gonimo.com/' failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT", source: (252) 02-20 14:12:29.193 17523 17538 D HaskellActivity: WebSocket got closed! (JS event) hmmm – robert Feb 20 '18 at 14:05
  • It seems different devices have different solutions according to this [forum](https://forums.androidcentral.com/ask-question/599333-wifi-turning-goes-sleep-despite-settings-keep.html). Solutions include turning off battery optimization, keep-alive-apps, rebooting,toggling *"Keep Wi-Fi on during sleep"*, and keeping the charger plugged in ! – Jon Goodwin Feb 21 '18 at 02:16
  • Regarding your last update: you should use `Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS` – artkoenig Feb 21 '18 at 10:49

1 Answers1

7

Here is an "Android, please don't kill my long running background operation" recipe

  1. Move your stream transmission code into a service running in foreground
  2. Keep the CPU running (if needed)
  3. Make sure, that your app is excluded from the doze mode (because the user has to do this for you, you have to explain the reason in a nice overlay, before asking for it)

Checking:

PowerManager powerManager =
     (PowerManager)getActivity().getSystemService(Activity.POWER_SERVICE);

powerManager.isIgnoringBatteryOptimizations(getActivity().getPackageName());

Asking for the white-listing:

Intent intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
startActivity(intent);

Don't see that as encouragement to use this as general approach, There are only a few use cases that legitimize this procedure.

artkoenig
  • 7,117
  • 2
  • 40
  • 61
  • Many thanks! Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS did the trick. Unfortunately the user experience sucks a lot, but at least it works. The service running in foreground solution, is I believe not really applicable, as the streaming service is part of the WebView and can't be a service - is that correct? – robert Feb 21 '18 at 19:16
  • OMG somebody [solved](https://stackoverflow.com/questions/18865035/android-using-webview-outside-an-activity-context) this madness already :) But I would really encourage you to solve this by a native implementation. – artkoenig Feb 21 '18 at 19:52
  • I actually found that one already during my research, but I misunderstood a few things. I believe having an Activity that is a foreground service is no problem at all, so this should solve my problem. I will give it a try! Thank you very much for your help! I'd like to avoid a native implementation, because Android is just one of our target platforms and rewriting all of that for Android would be quite a bunch of work. ;-) – robert Feb 21 '18 at 21:11