Der Unity3D-Android-Sperrbildschirm wird nicht angezeigt, wenn der Bildschirm abläuft.(Wakelock?)

StackOverflow https://stackoverflow.com/questions/19846822

Frage

Ich erstelle eine Android-App mit Unity und sie kommt sehr gut voran.Allerdings habe ich ein merkwürdiges Problem mit der Zeitüberschreitung des Bildschirms und der Tatsache, dass der Sperrbildschirm nicht angezeigt wird.

Was soll passieren

  • Der Benutzer hört auf zu spielen
  • Der Bildschirm läuft ab und schaltet sich aus
  • Später kehrt der Spieler zurück und schaltet sein Telefon wieder ein
  • Auf dem Sperrbildschirm wird angezeigt, dass der Benutzer sein Passwort eingeben oder sein Telefon auf andere Weise entsperren kann
  • Die App erhält den Fokus wieder und fährt fort

Was passiert

  • Der Benutzer hört auf zu spielen
  • Der Bildschirm läuft ab und schaltet sich aus
  • Später kehrt der Spieler zurück und schaltet sein Telefon wieder ein
  • Lockscreen funktioniert NICHT zeigen!Die App ist direkt im Fokus und umgeht den Sperrbildschirm insgesamt
  • Benutzer werden wütend, weil ihre Sicherheit gefährdet ist :(

Anmerkungen

  • Dies geschieht unabhängig davon, ob ich Android-Plugins verwende oder nicht
  • Ich verwende Unity 4.2.0f4 (obwohl die Änderungsprotokolle für die neueren Versionen nichts zu diesem Problem enthalten)
  • Es passiert sogar bei einem leeren Android-Projekt
  • Ich habe das auf 5 verschiedenen Geräten getestet, alle haben das gleiche Problem

Ich vermute, dass dies durch einen Wakelock verursacht wird, den Unity nicht aufgibt, wenn der Bildschirm abläuft.Dies führt dazu, dass die App den Fokus behält und der Sperrbildschirm nie „geladen“ wird.Das ist ein ziemlich ernstes Problem.

Kennt jemand eine Möglichkeit, dies zu beheben?

Notiz:Ich habe schon gefragt Diese Frage finden Sie auf Unity Answers vor etwas mehr als einer Woche und habe noch keine Antworten erhalten.Ich dachte, dass ich hier vielleicht mehr Glück hätte.

War es hilfreich?

Lösung

Zuerst würde ich gerne dank Michaeltaylor3ds Antwort dafür, dass ich mich in die richtige Richtung zeigte.

Es gab ein paar Probleme mit der Art und Weise, wie er das Problem löste, von dem ich glaube, dass ich korrigiert habe:

Das erste Problem ist mit dem KeyguardManager Herangehensweise zum Sperren des Bildschirms. Dies wurde in der API -Version 8 abgeschrieben und funktioniert nicht auf API 9+. Die neue Lösung verwendet die Geräte -Administrator -API, die für ein Spiel sehr aufdringlich erscheint.

Ich habe die UnityPlayer -Definition in Eclipse durchgesehen und eine Funktion namens Setwakelock (boolean) gefunden, sie ist jedoch privat.

Ich habe eine benutzerdefinierte Android -Aktivität gemacht. Darin greife ich auf eine geschützte UnityPlayer -Funktion zu setWakeLock(boolean) und nennt es in der onPause Funktion.

Ich gebe zu, dass dies weniger als ideal ist, aber es scheint ohne Nebenwirkungen zu funktionieren. Ich habe einen Fehlerbericht an Unity eingereicht, daher ist diese Arbeit hoffentlich nicht lange erforderlich.

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);     
    }
}

Dann müssen Sie diese Aktivität als Hauptaktivität in der AndroidManifest -Datei festlegen:

<?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>

Diese Lösung erfordert auch keine C# -Skripte oder C# <--> Java Interop.

Ich weiß auch hier, dass dies eine Art hackige Lösung ist, aber es scheint auf mehreren Geräten zu funktionieren, unabhängig von der API -Ebene ohne Nebenwirkungen. Hoffentlich wird dies bald von Unity behoben und benötigt keine hässliche Lösung mehr.

Andere Tipps

Ich habe keine Erfahrung mit der Einheit, sondern versuche dies zu verwenden http://developer.android.com/reference/android/os/powermanager.wakelock.html

Um zu sehen, ob die Einheit das Wakelock irgendwie mit iSheld () erzwingt; und versuchen Sie, es innerhalb Ihrer Aktivität zu überschreiben

Bearbeiten: Ich benutze Wakelock beim Herunterladen. Dadurch wird der Bildschirm schwarz, aber das Gerät nicht sperren. Dies ist also wahrscheinlich der Fall. Versuchen Sie, es zu veröffentlichen.

Dies ist ungetestet, aber Sie können es versuchen,

Grundsätzlich möchten Sie versuchen, direkt auf das Android SDK zuzugreifen. Unity verfügt über einige Klassen, die Ihnen dies ermöglichen.

Versuchen Sie, eine externe Java-Klasse zu schreiben und sie im Ordner „Plugins/Android“ abzulegen.

Die Java-Klassenmethode könnte etwa so aussehen: aus dieser Frage referenziertStellen Sie sicher, dass es so ist in eine .jar-Datei kompiliert

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();  
    }
}

Stellen Sie außerdem sicher, dass dies in der Android-Manifestdatei enthalten ist, damit Unity diese Aktivität anstelle der Hauptaktivität lädt, und legen Sie sie im Ordner \Plugins\Android ab:

<?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>

Erstellen Sie dann ein Unity C#-Skript, das die externe Java-Klasse aufruft: hier referenziert

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

}

Rufen Sie dann schließlich in einem aktiven Monoverhalten den Sperrbildschirm für das Anwendungspause-Ereignis auf: hier referenziert

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

Sie müssten sicherstellen, dass das folgende Flag auf false gesetzt ist

Application.runInBackground = false;

Ich würde denken, sonst wird das Pause-Ereignis nicht ausgelöst, wenn das Gerät ausgeschaltet wird.(Dies ist standardmäßig deaktiviert)

Auch wenn dies eine Lösung ist, denke ich immer noch, dass dies ein Unity-Fehler ist, der es sein sollte ihnen mitgeteilt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top