我正在使用Unity构建一个Android应用程序,它正在顺利进行。但是,我遇到了一个与屏幕超时和锁屏无关的奇怪问题。
应该发生什么
发生了什么
备注
我怀疑这是由于在屏幕超时时Unity不放弃的唤醒锁定引起的。这会导致应用程序保持焦点,锁屏永远不会“加载”。这是一个非常严重的问题。
有谁知道解决这个问题的方法?
注意:我已经在一周多前问过this question on Unity Answers并且还没有得到任何答复。我想也许我在这里有更好的运气。
答案 0 :(得分:2)
首先,我要感谢MichaelTaylor3D's Answer指出我正确的方向。
他解决问题的方式存在一些问题,我认为我已经纠正过了:
第一个问题是使用KeyguardManager
方法来锁定屏幕。这在API版本8中已经过折旧,不适用于API 9+。新解决方案使用Device Admin API,这似乎对游戏非常具有侵扰性。
我查看了eclipse中的UnityPlayer定义并找到了一个名为setWakeLock(boolean)的函数,但它是私有的。
我做了一个自定义的android Activity。在其中,我访问受保护的UnityPlayer函数setWakeLock(boolean)
并在onPause
函数中调用它。
我承认这不太理想,但似乎没有任何副作用。我已经向Unity提交了一份错误报告,所以希望这项工作不会长期存在。
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);
}
}
然后,您需要将此活动设置为AndroidManifest文件中的主要活动:
<?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>
此解决方案也不需要任何C#脚本或C#&lt; - &gt; Java互操作。
同样,我知道这是一种hacky解决方案,但它似乎适用于多种设备,无论API级别如何,都没有副作用。希望这很快就会被Unity修复,不再需要一个难看的修复。
答案 1 :(得分:0)
我没有Unity的任何经验,但尝试使用此http://developer.android.com/reference/android/os/PowerManager.WakeLock.html
用isHeld()来判断团结是否正在以某种方式强制唤醒锁;并尝试在您的活动中覆盖它
编辑:我在下载时使用唤醒锁,这使得屏幕变黑但没有锁定设备,所以可能就是这样,所以尝试释放它,这可能会产生某种冲突,但总是值得一试。答案 2 :(得分:0)
这是未经测试的,但你可以试试这个,
基本上你想尝试直接访问Android SDK,Unity有一些允许你这样做的类。
尝试编写外部Java类并将其放在Plugins / Android文件夹中。
Java类方法可能是这样的:referenced from this question 确保其compiled into a .jar file
package com.yourcompany.yourgamename;
import com.unity3d.player.UnityPlayerActivity;
import android.content.Context;
import android.os.Bundle;
import android.util.Config;
import android.util.Log;
import android.app.Activity;
public class MainActivity extends UnityPlayerActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
public static void lockScreen()
{
KeyguardManager keyguardManager = (KeyguardManager)getSystemService(Activity.KEYGUARD_SERVICE);
KeyguardLock lock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
lock.reenableKeyguard();
}
}
还要确保这是在Android Manifest文件中,以便Unity加载此活动而不是主活动,并将其放在\ Plugins \ Android文件夹中:
<?xml version="1.0" encoding="utf-8"?>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
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>
然后创建一个调用外部Java类的Unity C#脚本:referenced here
public static void InvokeAndroidLockScreen()
{
#if UNITY_ANDROID
using (AndroidJavaClass cls_UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
using (AndroidJavaObject obj_Activity = cls_UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
{
obj_Activity .CallStatic("lockScreen");
}
}
#else
Debug.LogWarning("Cant invoke lockscreen on a non Android Device");
#endif
}
然后最终在活动的monobehavior中调用应用程序暂停事件的锁屏:referenced here
void OnApplicationPause(bool pauseStatus)
{
InvokeAndroidLockScreen();
}
您必须确保将以下标志设置为false
Application.runInBackground = false;
我会想,否则当设备关闭时,暂停事件不会被触发。 (默认情况下关闭)
即使这是一个解决方法,我仍然认为这是一个应该是reported to them.
的Unity Bug