Unity3d Android Lockscreen non affiché lorsque l'écran se déroule. (Verrouillage de réveil?)

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

Question

Je construis une application Android en utilisant Unity et elle se déroule très bien. Cependant, j'ai un problème étrange concernant la synchronisation de l'écran et l'écran de verrouillage ne s'affiche pas.

Qu'est-ce qui devrait arriver

  • L'utilisateur cesse de jouer
  • Le dépistage des temps et s'éteint
  • Plus tard, le joueur revient et remonte son téléphone
  • Lockscreen affiche, l'utilisateur peut saisir son mot de passe ou déverrouiller son téléphone
  • L'application retrouve la concentration et continue

Ce qui se passe

  • L'utilisateur cesse de jouer
  • Le dépistage des temps et s'éteint
  • Plus tard, le joueur revient et remonte son téléphone
  • Lockscreen fait NE PAS Afficher! L'application est juste au point, en contournant l'écran de verrouillage tous ensemble
  • Les utilisateurs deviennent fous que leur sécurité soit compromise :(

Remarques

  • Cela se produit, que j'utilise ou non les plugins Android
  • J'utilise Unity 4.2.0f4 (bien que les changelogs pour les versions les plus récentes n'aient rien sur ce problème)
  • Cela se produit même sur un projet Android vierge
  • J'ai testé cela sur 5 appareils différents, tous ont le même problème

Je soupçonne que cela est causé par un wakelock que l'unité n'abandonne pas lorsque l'écran se lance. Cela fait que l'application tient la mise au point et l'écran de verrouillage ne peut jamais «charger». C'est un problème assez grave.

Quelqu'un connaît-il un moyen de résoudre ce problème?

Remarque: j'ai déjà demandé Cette question sur les réponses d'unité Il y a un peu plus d'une semaine et n'a pas encore obtenu de réponses. Je pensais que j'aurais peut-être plus de chance ici.

Était-ce utile?

La solution

Je voudrais d'abord dire merci à Réponse de Michaeltaylor3d pour me pointer dans la bonne direction.

Il y a eu quelques problèmes avec la façon dont il a résolu le problème que je pense que j'ai corrigé:

Le premier problème est avec le KeyguardManager approche pour verrouiller l'écran. Cela a été déprécié dans l'API version 8 et ne fonctionnera pas sur l'API 9+. La nouvelle solution utilise l'API Admin de périphérique qui semble très intrusive pour un jeu.

J'ai examiné la définition d'UnityPlayer dans Eclipse et j'ai trouvé une fonction appelée setwakelock (boolean), mais elle est privée.

J'ai fait une activité Android personnalisée. Dans ce document, j'accédez à une fonction UnityPlayer protégée setWakeLock(boolean) et l'appelle dans le onPause fonction.

J'avoue que c'est loin d'être idéal, mais cela semble fonctionner sans effets secondaires. J'ai soumis un rapport de bogue à Unity, alors j'espère que ce travail ne sera pas requis depuis longtemps.

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

Ensuite, vous devez définir cette activité en tant qu'activité principale dans le fichier 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>

Cette solution ne nécessite pas non plus de scripts C # ou de C # <-> Java Interop.

Encore une fois, je sais que c'est une sorte de solution de pirate, mais cela semble fonctionner sur plusieurs appareils, quel que soit le niveau d'API sans effets secondaires. Espérons que cela sera bientôt corrigé par Unity et ne nécessitera plus de solution laide.

Autres conseils

Je n'ai aucune expérience de l'unité mais essayez d'utiliser cela http://developer.android.com/reference/android/os/powermanager.wakelock.html

Pour voir si l'unité forçait le wakelock d'une manière ou d'une autre avec Isheld (); Et essayez de le remplacer dans votre activité

EDIT: J'utilise Wakelock lors du téléchargement et cela rend l'écran en noir mais ne verrouille pas l'appareil, c'est probablement le cas, alors essayez de le publier, cela pourrait donner une sorte de conflit mais cela vaut toujours la peine d'essayer.

Ce n'est pas testé mais vous pouvez essayer ceci,

Fondamentalement, vous souhaitez essayer d'accéder directement au SDK Android, Unity a des classes qui vous permettent de le faire.

Essayez d'écrire une classe Java externe et placez-la dans le dossier Plugins / Android.

La méthode de la classe Java pourrait être quelque chose comme ceci: référencé de cette questionAssurez-vous que c'est compilé dans un fichier .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();  
    }
}

Assurez-vous également que cela se trouve dans le fichier Android Manifest afin qu'Unity charge cette activité au lieu de la principale et mettez-la dans le dossier 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>

Créez ensuite un script Unity C # qui invoque la classe Java externe: Référencé ici

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

}

Ensuite, dans un monobehavior actif, invoquez l'écran de verrouillage sur l'événement de pause d'application: Référencé ici

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

Vous devez vous assurer que le drapeau suivant est défini sur faux

Application.runInBackground = false;

Je pense ou bien que l'événement de pause ne sera pas déclenché lorsque l'appareil s'éteint. (C'est désactivé par défaut)

Même si c'est un travail, je pense toujours que c'est un bug d'unité qui devrait être leur a été signalé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top