Prevent iOS mobile safari from going idle / auto-locking / sleeping?
Asked Answered
M

10

45

In an iOS app you can set application.idleTimerDisabled = YES to prevent the phone from auto locking.

I need to do this in mobile safari for a game like Doodle Jump where the user may not touch the screen for an extended period of time. Is there any documented method or hack to do this?

(Update) They seem to be doing it somehow in this site http://www.uncoveryourworld.com. Visit from your iphone and when you get to the buildings/street scene with music playing in the background just leave your phone alone. It never goes to sleep.

(Update 2) I've spent some time taking a closer look at how they might be keeping the phone from going to sleep. I've done a barebones test and it seems that the way they are looping the audio in the street scene is what keeps it from going to sleep. If you'd like to test this just put a simple audio player that loops on your page and click play:

<audio src="loop.mp3" onended="this.play();" controls="controls" autobuffer></audio>

Everywhere I searched it is being said that this isn't possible, so it is nice to see there is at least some way to do it even if a bit of a hack. Otherwise a browser based game with doodle-jump style play would not be possible. So you could have a loop in your game/app if appropriate or just play a silent loop.

Mid answered 14/3, 2012 at 20:36 Comment(6)
Possible duplicate of #7477924Plante
I didn't know about application.idleTimerDisabled = YES for iOS programming (or it didn't exist in iOS3 when I did this) and so I used to play a silent audio tone every minute or so. A delay between plays should increase battery life rather over your constant loop. (But you'd need to test that it still keeps it awake)Harborage
I tired adding the audio loop, but the phone still goes to sleep.Stringent
Any updates on this? I want my web app to stay "awake" without it always auto-locking.Rhodarhodamine
None of the suggestions on this page so far work for me, except actually disabling lock in general settings on the iOS device. Tested on iOS 7.1.2. If any of these worked, they worked due to a bug in iOS which must have been fixed. This includes the site from the question.Octahedron
This seems to work well on both iOS and Android: github.com/richtr/NoSleep.jsHobbs
C
14

NoSleep.js seems to work in iOS 11 and it reportedly works on Android as well.


Old answer

This is a simple HTML-only method to do that: looping inline autoplaying videos (it might also work in Android Chrome 53+)

<video playsinline muted autoplay loop src="https://rawgit.com/bower-media-samples/big-buck-bunny-480p-30s/master/video.mp4" height=60></video>

See the same demo on CodePen (includes a stopwatch)

Notes

  • Avoid loading a big video just for this. Perhaps make a short, tiny, black-only video or use
  • To make it fully work, the videos needs to be always in the viewport or you need to start its playback via JS: video.play()
Classieclassification answered 14/12, 2016 at 4:24 Comment(6)
Whoops, I'm lying! I was testing it on my device using Firefox as the browser, using Safari it works. Confirmed working on 10.2 😄Pulmonate
Confirmed NoSleep.js on iPhone 5S running iOS 10.2.Posh
Please edit your answer again to mention that NoSleep.js works: your answer begins with "EDIT: none of the solutions currently on this page work on iOS 10.2+" which is misleading.Sitdown
Hi, is that working at the moment? Because for me is not. I’m in iOS 12.2. Thanks!Unbrace
Does not work for IOS15.1Philae
Works on iOS 15.3.1Kyte
D
8

Edit: This work around no longer works. It is not currently possible to prevent the phone from sleeping in safari.

Yes, you can prevent the phone to sleep using an audio loop. The trick won't start automatically, you will have to play it when the visitor touches the screen.

<audio loop src="http://www.sousound.com/music/healing/healing_01.mp3"></audio>

Test page: tap play and the display will stay on but it will dim on some devices, like an iPhone with iOS 7.

Note: be careful using this trick because it will stop any music that the visitors might be using—and it will annoy them.

Dalton answered 4/3, 2013 at 19:58 Comment(3)
Is this entire thing is needed to keep the screen from turning off? Which part is the crucial part?Selfless
@Selfless I cleaned it up. An <audio> tag is all that's necessary.Classieclassification
Shouldn't a looped VIDEO do the trick? Android definitely does not go to sleep when watching a video in Chrome (e.g. on YouTube, meaning the website). Does iOS??Gotama
D
3

[edit] random bug behavior, sometimes lockscreen media controls showing, sometimes not

Years later, updated my code

Easy steps :

  • unlock audio context
  • create silent sound
  • loop it and play forever
  • keep tab active

Working on Safari iOs 15.3.1, tab & browser in background, screen off

// unlock audio context
let ctx = null;

// create silent sound
let bufferSize = 2 * ctx.sampleRate, 
    emptyBuffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate), 
    output = emptyBuffer.getChannelData(0);

// fill buffer
for(let i = 0; i < bufferSize; i++) 
    output[i] = 0;

// create source node
let source = ctx.createBufferSource();
source.buffer = emptyBuffer;
source.loop = true;

// create destination node
let node = ctx.createMediaStreamDestination();
source.connect(node);

// dummy audio element
let audio = document.createElement("audio");
audio.style.display = "none";
document.body.appendChild(audio);

// set source and play
audio.srcObject = node.stream;
audio.play();

// background exec enabled
Dagley answered 2/3, 2022 at 2:0 Comment(0)
P
2

No, you can't do this, unfortunately. The only way to achieve this is by making a UIWebView-application and setting the variable you provided there.
https://mcmap.net/q/374756/-html5-app-screen-sleep-timeout-on-ipad

Plante answered 14/3, 2012 at 20:41 Comment(2)
I added a link to a site I found, which seems to be achieving this in mobile Safari.Mid
You might want to send them an email and ask them about it. I didn't make that site ;)Plante
G
1

Today, I tried using the WakeLock API to keep Safari iOS alive (works as of now). It looks like they began supporting this is March 2023 for https. Note, at this time it looks like typescript isn't caught up with Navigator's use of WakeLock, so feel free to write extensions or just use @ts-ignore. Here's a react solution, you would probably want to call your functions with some kind of useEffect unless you're planning on keeping WakeLock active with persistence.

const wakeLockRef = useRef(null)

if (wakeLockRef.current) {
    wakeLockRef.current.release()
    wakeLockRef.current = null
}

const startWakeLock = () => {
    try {
      // @ts-ignore
      if ("wakeLock" in navigator && navigator.wakeLock.request) {
        // @ts-ignore
        wakeLockRef.current = await navigator.wakeLock.request("screen")
        console.log("Wake Lock is active")
      }
    } catch (err) {
      console.error(`Could not obtain wake lock: ${err.message}`)
    }
}

const stopWakeLock = () => {
    if (wakeLockRef.current) {
      wakeLockRef.current.release()
      wakeLockRef.current = null
      console.log("Wake Lock has been released")
    }
}
Grajeda answered 9/11, 2023 at 18:23 Comment(0)
G
0

Even if this approach might not be suitable in every case, you can prevent your phone from locking by reloading the page using Javascript.

// This will trigger a reload after 30 seconds
setTimeout(function(){
    self.location = self.location
}, 30000);

Please note that I tested this with iOS7 beta 3

Goethite answered 28/7, 2013 at 21:16 Comment(3)
It does in Safari iOS 7.1.2 and iOS 8. Demo: jsbin.com/nekizeloca/1 It doesn't work in WebViews like Chrome and Facebook, though.Classieclassification
I'm testing in Safari iOS 7.1.2, on iPhone 4s and iPad and I can't get it to work with this demo as well...Octahedron
What about using iframe and setting the source of iframe over and over? Kinda faking reload without to really reload?Hyperplane
C
0

You can stop sleeping and screen dimming in iOS Safari by faking a refresh every 20–30 seconds

var stayAwake = setInterval(function () {
    location.href = location.href; //try refreshing
    window.setTimeout(window.stop, 0); //stop it soon after
}, 30000);

Please use this code responsibly, don't use it "just because". If it's only needed for a bit, disable it.

clearInterval(stayAwake); //allow device sleep again when not needed

Tested in Safari iOS 7, 7.1.2, and 8.1, but it may not work in UIWebView browsers like Chrome for iOS or the Facebook app.

Demo: http://jsbin.com/kozuzuwaya/1

Classieclassification answered 22/6, 2014 at 13:24 Comment(7)
It works fine on iOS 7.1.2 and iOS 8. Try the demo. Both of my devices are awake after 4 minutes even though the auto-lock timer is at 1 minute.Classieclassification
demo doesn't work for me on both iPad and iPhone, iOS 7.1.2. Don't know why, auto-lock is respected.Octahedron
There seems to be few issues with this approach. Firstly, when the current URL has hash in it, this will not work. Probably because updating the location that has hash string does not trigger page load. This can be worked around by using a location without hash string (just "/" for example). This works on iOS 8.3, but brings us to the second issue, on Android it obviously doesn't work and seems that when the device goes to sleep, it executes the location change without it being stopped.Rigel
Related to comment above, so what I ended up using is a version of this solution with location.href = "/"; and then only execute this code on iOS (check OS from user-agent) and this seems to work as far as I have tested it.Rigel
Also, it does not work if you add the page to home screen (probably for the same reason it doesn't work in other browsers), it only works in Safari.Rigel
I just tried this on iOS 10, as of late 2016. It doesn't appear to work for my iPhone device.Survey
Try my new answer for iOS 10, I just tried that and it works on iOS 10.1Classieclassification
D
0

bfred.it's answer works if you replace the audio-tag with a <video src="..." ... playsinline> tag - but only if the page is open in iOS10+ Safari AND the user has started the video. You can hide the video with CSS.

Also, I suspect that this feature will also be removed at some point.

Dissension answered 3/10, 2016 at 12:25 Comment(0)
S
0

This is based on nicopowa's answer, which saves a PWA from being suspended by iOS. (Playing an infinite loop of nothing keeps the app running - even with the screen turned off.)

In order to also make sure that it's triggered by user interaction,
the only thing to change is instead of

let ctx = null

put

let ctx = new AudioContext()
Sudorific answered 16/9, 2022 at 19:16 Comment(2)
You know about the commenting privilege which you do not have, so well that you can even put it into words. You are aware of the rule meta.stackexchange.com/questions/214173/… . In that situation please do not decide to misuse a different mechanism (an answer) for something it is not meant for and which you are not allowed yet to do.Poly
I have however done an edit, which I think turns you post into an answer. Please review to find what I might have logically broken. Maybe you can also edit to further improve according to How to Answer.Poly
H
0

Note that for audio only (the reason I came here), the phone will continue playing after sleeping/ locking. But ONLY if safari is not in Private mode. Makes some sense of course, but not obvious.

Hedwighedwiga answered 20/7 at 17:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.