I am building an android app using Unity and it is coming along very well. However, I'm having an odd issue relating to the screen timing out and the lockscreen not showing.
What Should Happen
What IS happening
Notes
I suspect that this is caused by a wakelock that Unity does not give up when the screen times out. This causes the app to hold focus and the lockscreen never gets to 'load'. This is a pretty serious problem.
Does anyone know of any way to fix this?
Note: I've already asked this question on Unity Answers a little over a week ago and haven't gotten any responses yet. I thought maybe I'd have better luck here.
First I'd like to say thanks to MichaelTaylor3D's Answer for pointing me in the right direction.
There were a few issues with the way he solved the problem that I think I have corrected:
The first issue is with the KeyguardManager
approach to locking the screen. This was depreciated in API version 8 and won't work on API 9+. The new solution uses the Device Admin API which seems very intrusive for a game.
I looked through the UnityPlayer definition in eclipse and found a function called setWakeLock(boolean), however it is private.
I made a custom android Activity. In it, I access a protected UnityPlayer function setWakeLock(boolean)
and calls it in the onPause
function.
I admit this is less than ideal, but it does seem to work with no side effects. I've submitted a bug report to Unity, so hopefully this work around will not be required for long.
public class UnityPlayerWithLockscreen extends UnityPlayerNativeActivity {
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
//Provides access to the private UnityPlayer.setWakeLock(boolean) method.
public void setWakeLock(boolean useWakelock) {
Method setWakeLockMethod;
//Use Reflection to get the setWakeLock(boolean) method from the UnityPlayer class
setWakeLockMethod = mUnityPlayer.getClass().getDeclaredMethod("setWakeLock");
//Set the method to me accessible
setWakeLockMethod.setAccessible(true);
//Invoke the method with our argument
setWakeLockMethod.invoke(mUnityPlayer, useWakelock);
}
@Override
protected void onPause()
{
super.onPause();
//Force unity to release the wakelock
setWakeLock(false);
}
}
Then you need to set this activity as the main activity in the AndroidManifest file:
<?xml version="1.0" encoding="utf-8"?>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".UnityPlayerWithLockscreen"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
This solution also doesn't require any C# scripts or C# <-> Java interop.
Again, I know this is sort of a hacky solution, but it seems to work on several devices regardless of API level with no side effects. Hopefully this gets fixed by Unity soon and will no longer require an ugly fix.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With