Prevent mobile device auto lock screen on iOS / Android

Hi, I’ve been searching a while and cannot find an answer to this question : is it possible to prevent mobile devices from screen locking while the app is in foreground ? Some kind of idle timer to reset periodically? I want my app to keep the phone awake. Is this possible from Juce ? Thanks :slight_smile:

I was looking for the same thing on Android and stumbled over your post… and thought that I can answer that for iOS even if the post is 6 months old, so people can also find the answer to that question here :slight_smile:

There’s a method in Apples UIKit that will take care of this. To implement it you’re gonna have to write a tiny bit of native code and here’s how you can do that:

  1. You’ll need an .h/.mm file pair instead of the ‘regular’ .h/.cpp pair, lets call them Autolock.h/Autolock.mm (mm files will let you mix C++ and Obj-C)

  2. In Autolock.h:

#pragma once
#include <JuceHeader.h>

#if JUCE_IOS
struct AutoLock
{
    static void setEnabled (bool state);
};
#endif
  1. In Autolock.mm:
#include "Autolock.h"

#if JUCE_IOS
#define Point CarbonDummyPointName
#define Component CarbonDummyCompName
#import <UIKit/UIApplication.h>
#undef Point
#undef Component

void AutoLock::setEnabled (bool state)
{
     [[UIApplication sharedApplication] setIdleTimerDisabled: !state];
}
#endif

That whole ugly #define-#undef block is necessary for the newer iOS sdks, since they also have a Point/Component class now, which will clash with the respective juce classes. If there’s a better solution to this, let me know.

With that just include Autolock.h and call AutoLock::setEnabled (bool) from anywhere you deem appropriate.

Now, anyone got a solution to this for Android :slight_smile: ?

1 Like

Well I guess I just helped myself, here’s the Android solution if anyone’s interested:

  1. Keep the same Autolock.h file as in the post above and just add a JUCE_ANDROID flag on top, so the AutoLock struct is available for Android as well.

  2. Add an Autolock.cpp file

  3. In the Autolock.cpp file

    #include "AutoLock.h"
    
    #if JUCE_ANDROID
    #include <juce_core/native/juce_android_JNIHelpers.h>
    
    #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK)\
         METHOD (addFlags, "addFlags", "(I)V") \
         METHOD (clearFlags, "clearFlags", "(I)V") \
    
    DECLARE_JNI_CLASS (Window, "android/view/Window")
    #undef JNI_CLASS_MEMBERS
    
    void AutoLock::setAutolockEnabled (bool state)
    {
          auto activity = getMainActivity();
          auto env = getEnv();
          auto window = env->CallObjectMethod(activity.get(), AndroidActivity.getWindow);
    
             //https://developer.android.com/reference/android/view/WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON
          const auto keepScreenOnFlag { 0x00000080 };
    
          if (state)
               env->CallVoidMethod(window.get(), Window.clearFlags, keepScreenOnFlag);
          else
               env->CallVoidMethod(window.get(), Window.addFlags, keepScreenOnFlag);
    
          DBG("Android Auto Lock " << String(state? "enabled" : "disabled"));
    }
    #endif
    

Hope this will help somebody :slight_smile:

4 Likes

There’s a JUCE level call you can make that will solve this on iOS. It’s nice in that you don’t need to do the whole .mm/.h file, etc. However, this method will NOT work for Android. I might need to try benediktsailer’s version of the Android solution to get the same result.

        // Prevent the screen for entering screen saver mode
        //
        Desktop::setScreenSaverEnabled(false);