Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ensure network connectivity for an Android app on standby?

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.

like image 685
robert Avatar asked Feb 09 '18 13:02

robert


People also ask

What is app standby Optimizer?

App Standby preserves battery life by suspending the background network activity of unused applications. Phone calls and text messaging (SMS) are not affected.

How do Android apps connect to the internet?

Before starting your application, Android studio will display following window to select an option where you want to run your Android application. Now just click on button, It will check internet connection as well as it will download image. Out would be as follows and it has fetch the logo from internet.

Which system service can you use to determine if there is an available network connection in your app?

The API enables you to determine whether the device is currently connected to a network that satisfies your app's requirements.

How does Android determine Internet connection?

In a wireless network the device may have a valid TCP/IP connection to the network but have no or limited connection to the Internet. Android NetworkMonitor service does check the Internet connection by trying to access special servers: http://connectivitycheck.gstatic.com/generate_204. http://www.google.com/gen_204.


1 Answers

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.

like image 157
artkoenig Avatar answered Sep 26 '22 00:09

artkoenig