如何确保 Android 应用程序处于待机状态时的网络连接?

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

我目前正在编写一个 Android 应用程序,它使用 webview 和 webrtc 来传输音频流。这个问题,至少在我的手机上 phone 屏幕关闭几分钟后连接就断开了。

我已经获得了 CPU 锁和 wifi 锁(通过 isHeld 验证),但没有任何区别。

该应用程序也可用作 web application:在这里它似乎按预期工作并且连接保持活动状态。

我已经检查了 wifi 设置:它设置为始终打开。

任何 pointers/ideas 非常感谢。该应用程序是开源的,所以如果有任何帮助,我很乐意分享任何代码。锁抓取是这样完成的:

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();
}

我的清单中有以下权限:

    <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" />

非常感谢!

更新:

Android Doze 似乎是这种行为的原因。手动触发 Doze 会导致相同的行为。还有

    return pm.isIgnoringBatteryOptimizations(packageName);

返回 false,因此应用程序的网络将被关闭!问题:article 中描述的白名单在我的 phone 中似乎不存在。我无法在设置和执行中找到它:

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

导致无法找到 Activity 的异常。

这是一个"Android, please don't kill my long running background operation"食谱

  1. 将你的流传输代码移动到service running in foreground
  2. Keep the CPU running(如果需要)
  3. 确保您的应用程序已排除在打瞌睡模式之外(因为用户必须为您执行此操作,所以您必须在要求之前在漂亮的覆盖层中解释原因)

正在检查:

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

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

要求 white-listing:

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

不要将此视为鼓励将其用作一般方法,只有少数用例使此过程合法化。