5

ブロードキャストレシーバーとサービスを使用して、ユーザーが画面をオンまたはオフにしたときにリッスンし、そこからアクティビティを起動するカスタムロック画面アプリを作成しました。このアクティビティは、ロック画面を完全に置き換えることになっています。これを行うために、私のアプリはAndroidストックロックを無効にして、私のアプリが新しいロック画面として機能できるようにすることになっています。

代わりに、アプリケーションが最初にインストールされた後、サービスが最初に開始された場合、アプリケーションは機能しているように見えます。また、ユーザーが最初に電話の画面をオフにしてから再びオンにすると、私のアプリが上に表示され、私のアプリで電話のロックを解除できます。しかし、Android OS内で、ユーザーが次に画面をオフにしてから再びオンにしたときにホームボタンを押すと、アプリケーションに戻されるのではなく、アプリケーションが開いた状態でストックロック解除画面に移動します。それが上にあるべきとき。

これが私のコードです:

私のサービス:

public class MyService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {

        super.onCreate();
        Log.d("MyService","Service STARTED");
        final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        final BroadcastReceiver mReceiver = new ScreenReceiver();
        registerReceiver(mReceiver, filter);
    }
}

私の放送受信機:

public class ScreenReceiver extends BroadcastReceiver {

public static ArrayList<String> runningApplications = new ArrayList<String>();
private Context ctext;
public static boolean screenIsLocked;
public static KeyguardManager keyguardManager;
public static KeyguardLock lock;

@Override
public void onReceive(final Context context, final Intent intent) {
    ctext = context;
    keyguardManager = (KeyguardManager)ctext.getSystemService(Activity.KEYGUARD_SERVICE);
    lock = keyguardManager.newKeyguardLock(Context.KEYGUARD_SERVICE);
    lock.disableKeyguard();


    if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
        screenIsLocked = true;
        Log.d("ScreenReceiver", "False");

        Intent intenti = new Intent();
        intenti.setClass(context, starterActivity.class);
        intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intenti);


    } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
        screenIsLocked = false;
        Log.d("ScreenReceiver", "True");

                    Intent intenti = new Intent();
                    intenti.setClass(context, starterActivity.class);
                    intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(intenti);
    }
}

開始された私のアクティビティは基本的に空でfinish();、押されたときに呼び出すロック解除ボタンが1つだけです。

4

2 に答える 2

4

キーガード関連のロジックの動作は、デバイスによって異なります。これは、ロックスクリーンが多くの場合、デバイス メーカーによってカスタムメイドされている (つまり在庫がない) ためです。使用するキーガード ロジックを尊重するものもあれば、そうでないものもあります。

また、キーガードを制御する新しい方法は、ウィンドウ フラグを使用することです。

// inside activity
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);

これで問題が解決するわけではありませんが、デバイスにはまだこれに関する発言権があります。

たとえば、私の経験から、Galaxy Nexus はキーガードの上にアクティビティのウィンドウを表示しますが、それを閉じることはありません (Google ブランドのデバイスはフラグを尊重する必要があると思います)。したがって、アクティビティで [戻る] ボタンを押すと、標準のロック画面を取得 --- HTC One X は非表示部分を適切に処理しているようですが、アクティビティ ウィンドウにより、標準のロック画面が期待どおりに非表示になります。

すべてのデバイスを強制的に適切に動作させる方法が見つかりませんでした。Android API は、カスタム ロック画面を作成できるようにするためのものではありません (少なくとも現時点では)。ストアにあるものを見てください - それらはすべて、十分に安定していないというまったく同じ問題を抱えています。

Dianne Hackbornがこの Google Groups answerで述べているように、この点に関してあなたができることはすべてハックなので、時々壊れることを期待してください.

于 2012-07-25T19:31:42.197 に答える
2

あなたのコードをコンパイルしようとしましたが、あなたが話していたのと同じエラーが発生しました。私はそれを修正して動作させようとしましたが、ついに問題が発生しました!!!

public class ScreenReceiver extends BroadcastReceiver {

    public static ArrayList<String> runningApplications = new ArrayList<String>();
    private Context ctext;
    public static boolean screenIsLocked;
    public static KeyguardManager keyguardManager;
    public static KeyguardLock lock;

    @Override
    public void onReceive(final Context context, final Intent intent) {
        ctext = context;
        keyguardManager = (KeyguardManager)ctext.getSystemService(Activity.KEYGUARD_SERVICE);
        lock = keyguardManager.newKeyguardLock(Context.KEYGUARD_SERVICE);
        lock.disableKeyguard();


        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            screenIsLocked = true;
            Log.d("ScreenReceiver", "False");

            Intent intenti = new Intent();
            intenti.setClass(context, starterActivity.class);
            intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(intenti);


        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            screenIsLocked = false;
            Log.d("ScreenReceiver", "True");

                        Intent intenti = new Intent();
                        intenti.setClass(context, starterActivity.class);
                        intenti.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        intenti.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        context.startActivity(intenti);
        }
    }

放送受信機クラスへのこの変更により、問題を克服することができました

試してみて、問題があれば教えてください。

編集:問題はfinish()メソッドにあると思います....Androidはメモリが必要なときにアプリをダンプします...Androidfinish()がアプリを破棄するのを助けていると思います(これがあなたの問題がランダムに発生する理由かもしれません)

于 2012-07-21T17:30:04.573 に答える