我正在使用Unity构建一个Android应用程序,并且情况非常好。但是,我遇到了一个奇怪的问题,该问题与屏幕的计时有关,而锁屏未显示。

应该发生什么

  • 用户停止播放
  • 屏幕时间关闭
  • 后来,玩家返回并打开手机
  • 锁屏显示,用户可以输入密码或以其他方式解锁手机
  • 应用程序重新集中并继续

怎么了

  • 用户停止播放
  • 屏幕时间关闭
  • 后来,玩家返回并打开手机
  • 锁屏会 不是 节目!该应用是正确的焦点,绕过锁屏
  • 用户对他们的安全性受到损害感到生气:(

笔记

  • 无论我是否使用Android插件,都会发生这种情况
  • 我正在使用Unity 4.2.0F4(尽管最新版本的更改程序对此问题一无所有)
  • 它甚至发生在一个空白的Android项目上
  • 我已经在5种不同的设备上测试了此问题,所有设备都有相同的问题

我怀疑这是由一个Wakelock造成的,该Wakelock在屏幕时间出版时不会放弃团结。这会导致该应用保持焦点,而锁屏永远不会“负载”。这是一个非常严重的问题。

有人知道有什么方法可以解决这个问题吗?

注意:我已经问过 这个关于团结答案的问题 一周前,还没有得到任何回应。我以为也许我会在这里运气好。

有帮助吗?

解决方案

首先,我想感谢 Michaeltaylor3d的答案 指向我指向正确的方向。

他解决了我认为我已纠正的问题的方式存在一些问题:

第一个问题是 KeyguardManager 锁定屏幕的方法。这是在API版本8中贬值的,无法在API 9+上使用。新解决方案使用设备管理API,这对于游戏来说似乎非常侵入性。

我浏览了Eclipse中的UnityPlayer定义,并找到了一个称为SetWakelock(布尔值)的函数,但是它是私人的。

我进行了定制的Android活动。在其中,我访问受保护的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#<-> Java Interop。

同样,我知道这是一种刺激的解决方案,但是无论API级别如何,它似乎都可以在几个设备上使用。希望这很快就会结合起来,并且将不再需要丑陋的修复。

其他提示

我没有Unity的任何经验,但请尝试使用 http://developer.android.com/reference/android/os/powermanager.wakelock.html

看看Unity是否在以某种方式强迫Wakelock();并尝试在您的活动中覆盖它

编辑:下载时我正在使用Wakelock,这使屏幕变黑,但不锁定设备,因此可能是这种情况,因此请尝试发布它,这可能会带来某种冲突,但总是值得一试。

这是未经测试的,但您可以尝试一下,

基本上,您想尝试直接访问Android SDK,Unity有一些允许您执行此操作的类。

尝试编写外部Java类并将其放在插件/Android文件夹中。

Java类方法可能是这样的: 从这个问题引用确保其 编译成.jar文件

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清单文件中,以便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#脚本: 在这里引用

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

}

最后,在一个活动的单声言中调用应用程序暂停事件上的锁屏: 在这里引用

void OnApplicationPause(bool pauseStatus)
{
     InvokeAndroidLockScreen();
}

您必须确保将以下标志设置为false

Application.runInBackground = false;

我会认为,否则暂停事件不会在设备关闭时会触发。 (默认情况下这是不合适的)

即使这是一个工作,我仍然认为这是一个统一的错误 向他们报告。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top