fluttercommunity / wakelock_plus

Flutter plugin that allows you to keep the device screen awake on Android, iOS, macOS, Windows, Linux, and web.
BSD 3-Clause "New" or "Revised" License
71 stars 54 forks source link

Does not keep the screen awake on Android when accessed via chrome #7

Open odkken opened 1 year ago

odkken commented 1 year ago

Hosting the app locally, accessing it on an android device via chrome over LAN (e.g. 192.168.1.12:port)

The future returns the updated enabled/disabled value, but the screen still turns off.

If I go to the nosleep demo page on the same phone / browser (https://richtr.github.io/NoSleep.js/example) the screen stays on.

diegotori commented 1 year ago

@odkken thank you for bringing this up.

Unfortunately, I don't have the experience in debugging mobile web apps from Chrome, so I might be hamstrung in trying to investigate this further.

If you can provide an example app that reproduces this, that would also help.

Lastly, I do take pull requests to resolve this issue. So if you have a lead on a possible fix, I'll be happy to review it.

odkken commented 1 year ago

Sure, the provided example app is all I'm running. If you just launch it with

flutter run -d web-server --web-hostname 0.0.0.0 --web-port 12345

then access that from your phone's browser, you should be able to reproduce

odkken commented 1 year ago

Huh, this seems to be an android-specific issue. I tried it on an iphone and it works fine.

odkken commented 1 year ago

Here is a very simple working widget to provide the functionality:

NOTE: the wakeLock object on the navigator is only available on https connections!

class WakeLockWidget extends StatefulWidget {
  const WakeLockWidget({super.key});

  @override
  _WakeLockWidgetState createState() => _WakeLockWidgetState();
}

class _WakeLockWidgetState extends State<WakeLockWidget> {
  bool _isSupported = false;
  var _wakeLock;

  @override
  void initState() {
    super.initState();
    _checkSupport();
  }

  _checkSupport() {
    final navigatorObj = js.JsObject.fromBrowserObject(js.context['navigator']);
    if (navigatorObj.hasProperty('wakeLock')) {
      setState(() => _isSupported = true);
    }
  }

  enable() {
    if (!_isSupported) return;

    final navigatorObj = js.JsObject.fromBrowserObject(js.context['navigator']);
    final promise = navigatorObj['wakeLock'].callMethod('request', ['screen']);

    // Handle the promise resolution
    js.JsObject.fromBrowserObject(promise).callMethod('then', [
      (val) {
        setState(() {
          _wakeLock = val;
        });
      }
    ]);
  }

  disable() {
    if (!_isSupported || _wakeLock == null) return;

    final wakeLockObj = js.JsObject.fromBrowserObject(_wakeLock);
    if (wakeLockObj.hasProperty('release')) wakeLockObj.callMethod('release');
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(onPressed: enable, child: Text('Enable WakeLock')),
        ElevatedButton(onPressed: disable, child: Text('Disable WakeLock')),
      ],
    );
  }
}

I will leave this here rather than submitting a pull request, as I am not familiar with flutter package development, and I think this would need to be added to the original wakelock package (the web implementation specifically).

okku commented 1 year ago

I can confirm there is some kind of issue with web, I tried on mobile both chrome and safari. nosleep.js testpage works fine.

ocinon commented 11 months ago

@diegotori any update on including/fixing this? I'd love to remove the hack, as it breaks cross-platform compatibility while js is included directly.

ocinon commented 9 months ago

It works in the latest Flutter version for me now. Thank you for making/maintaining the package!

yannis216 commented 4 months ago

Hi @ocinon, can you please specify in which Flutter Version it started working for you? Did you do any other fixes/workarounds or it just "started working"? I´m still having this issue on an Android device with Chrome..

Specifically I'm getting this error in the browser bonsole: Permissions policy violation: screen-wake-lock is not allowed in this document. from no_sleep.js:115

ocinon commented 4 months ago

@yannis216 I haven't tested it in a while and can't tell you which version it was. The two things that I did were update Flutter and call the enable function once the user presses a button on the page, as otherwise, it doesn't work (actually, it could be that I'm calling enable during each build call).