Unity3D Android Lockscreenは、スクリーンがタイムを出しても表示されません。 (ウェイクロック?)

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

質問

Unityを使用してAndroidアプリを構築していますが、非常によく登場しています。しかし、私は画面のタイミングとロックスクリーンが表示されないという奇妙な問題を抱えています。

何が起こるべきか

  • ユーザーは再生を停止します
  • スクリーンタイムアウトとオフになります
  • 後で、プレーヤーが戻って電話を元に戻します
  • lockscreenショー、ユーザーはパスワードを入力したり、電話のロックを解除したりできます
  • アプリはフォーカスを取り戻し、継続します

何が起こっている

  • ユーザーは再生を停止します
  • スクリーンタイムアウトとオフになります
  • 後で、プレーヤーが戻って電話を元に戻します
  • ロックスクリーンはそうします いいえ 見せる!アプリは焦点を合わせており、ロックスクリーンをすべて一緒にバイパスします
  • ユーザーは自分のセキュリティが損なわれていることに腹を立てます:(

ノート

  • これは、私がAndroidプラグインを使用しているかどうかに関係なく起こります
  • 私はUnity 4.2.0F4を使用しています(ただし、最近のバージョンのChangelogsにはこの問題については何もありません)
  • 空白のAndroidプロジェクトでも発生します
  • これを5つの異なるデバイスでテストしましたが、すべて同じ問題があります

これは、画面がタイムになるときに団結があきらめないワークロックによって引き起こされると思われます。これにより、アプリがフォーカスを保持し、ロックスクリーンが「ロード」することはありません。これはかなり深刻な問題です。

これを修正する方法を知っている人はいますか?

注:私はすでに尋ねました Unity Answersに関するこの質問 1週間ほど前に、まだ返事を得ていません。ここで運が良くなると思ったでしょう。

役に立ちましたか?

解決

最初に感謝したいと思います MichaelTaylor3Dの答え 私を正しい方向に向けてください。

私が修正したと思う問題を彼が解決した方法には、いくつかの問題がありました。

最初の問題は次のとおりです KeyguardManager 画面をロックするためのアプローチ。これはAPIバージョン8で減価償却され、API 9+では動作しません。新しいソリューションは、ゲームに非常に邪魔に思われるデバイス管理APIを使用します。

EclipseのUnityPlayerの定義を調べて、Setwakelock(Boolean)と呼ばれる関数を見つけましたが、プライベートです。

カスタム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がIsheld()で何らかの形で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がメインのアクティビティの代わりにこのアクティビティをロードし、プラグイン 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();
}

次のフラグが虚偽に設定されていることを確認する必要があります

Application.runInBackground = false;

デバイスがオフになったときに、一時停止イベントがトリガーされないと思います。 (これはデフォルトでオフです)

たとえこれが回避的であっても、私はまだこれが統一されたバグだと思います 彼らに報告されました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top