Подтвердить что ты не робот

Переопределить кнопку питания так же, как кнопка "Домой"

Ну, я делаю то, в чем я хочу отключить все жесткие кнопки устройства.

Жесткие кнопки, такие как Power, Home, Volume up, Volume down, Search, Back.

Я успешно переопределил почти все кнопки здесь, кроме Power.

Итак, я просто хочу, чтобы вы, люди, увидели и, пожалуйста, поделитесь некоторыми идеями, чтобы я мог с ним справиться.

Я получаю длительное нажатие Power keyevent в onDispatchKeyEvent(), таким же образом, я хочу поймать короткий клик того же самого. Более того, при нажатии на я также пытался отключить Screen, получив Broadcast SCREEN_OFF, и мне удалось его получить, но я не смог обработать его.

Спасибо.

Затем я создал ReceiverScreen, который принимает широковещательную рассылку Screen on/off

ReceiverScreen.java

public class ReceiverScreen extends BroadcastReceiver {

    public static boolean wasScreenOn = true;

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            // do whatever you need to do here
            wasScreenOn = false;
        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            // and do whatever you need to do here
            wasScreenOn = true;
        }
    }
}

DisableHardButton.java

public class DisableHardButton extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);
    IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
    filter.addAction(Intent.ACTION_SCREEN_OFF);
    BroadcastReceiver mReceiver = new ReceiverScreen();
    registerReceiver(mReceiver, filter);
    }

@Override
    protected void onPause() {
        // when the screen is about to turn off
        if (ScreenReceiver.wasScreenOn) {
            // this is the case when onPause() is called by the system due to a screen state change
            System.out.println("SCREEN TURNED OFF");

    } else {
        // this is when onPause() is called when the screen state has not changed
    }
    super.onPause();
}

@Override
protected void onResume() {
    // only when screen turns on
    if (!ScreenReceiver.wasScreenOn) {
        // this is when onResume() is called due to a screen state change
        System.out.println("SCREEN TURNED ON");
    } else {
        // this is when onResume() is called when the screen state has not changed
    }
    super.onResume();
}
}
4b9b3361

Ответ 1

Уф. Это довольно спорный вопрос, за которым стоит большой комментарий.

Позвольте мне сначала перефразировать ваш вопрос. Если я четко понимаю, вы хотите отключить все физические кнопки на устройстве в течение всего срока действия. Это включает кнопку питания, которую вы обнаруживаете, управляя намерением ACTION_SCREEN_OFF. Ваш текущий (успешный) обходной путь для этого сценария состоит в том, чтобы транслировать ACTION_SCREEN_ON, возвращая экран назад к жизни, когда он выключен, если хост реализует это правильно.

Теперь вы хотели бы пройти лишнюю милю, если сделать это действие ненужным, если (и только если) вы сможете поймать и обработать ACTION_SCREEN_OFF, прежде чем он будет отправлен в систему. Возможно ли это, и если да, то как?

Это обсуждение. Однако короткая версия проста: это невозможно, без пользовательской модификации вашей прошивки или ядра операционной системы Android для ограниченного количества устройств.

Система Android, насколько это задокументировано, определяет это как действие . Следуя публикация-подписка шаблона распространения сообщения, это сообщение уведомит всех заинтересованных сторон об этом действии. Поскольку это сообщение отправляется системой, поскольку система сообщений управляется системой, и поскольку сообщение также принимается системой, ваш код просто не вводится в нужном месте, чтобы заблокировать прием этого сообщения.

Кроме того, для некоторых устройств это будет физический переключатель, который не имеет никакого программного прерывания. В лучшем случае система Android может надеяться обработать событие, когда это произойдет, и именно поэтому это широковещательное сообщение является чем-то особенным в стеке службы. Насколько я знаю и основанный на разреженной документации по этому сценарию, вот почему это не неотъемлемая функция, прежде чем мы рассмотрим любой из возможных векторов для злоупотреблений.

Ваш лучший ресурс на самом деле намного проще, если у вас есть возможность модифицировать физическое оборудование для рассматриваемого устройства: ограничить доступ, калечить или иным образом отключить физическую кнопку питания. Во многих сценариях это нежелательно, но это работает в ситуациях, когда ваше Android-устройство используется, например, в качестве точки продажи или машины общего пользования. Если это неработоспособно, размещение физических ограничений на доступ к кнопке питания может быть всем необходимым, обработка оставшихся случаев (например, попытка попыток переключения экрана) путем отправки ACTION_SCREEN_ON.

Просто помните, что эта стратегия не является надежной. Сделайте это грамотно и хорошо документируйте процедуру, чтобы вы не стали кормом для следующего 2600 exposé.

Желаем удачи в вашем приложении.

Ответ 2

В отличие от всех ответов.. Проверьте это:


@Override
public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
                Log.i("", "Dispath event power");
                Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
                sendBroadcast(closeDialog);
                return true;
        }

        return super.dispatchKeyEvent(event);
}

Что он делает:

Всякий раз, когда пользователь нажимает кнопку питания. Мы отменяем диалог до его даже увиденного!!:). Это работает для меня.. (Протестировано на заметке2)

Ответ 3

Вот что я сделал:

(1) Создайте класс приемника:

public class ScreenReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        switch (action) {
            case Intent.ACTION_SCREEN_OFF:
                BaseActivity.unlockScreen();
                break;

            case Intent.ACTION_SCREEN_ON:
                // and do whatever you need to do here
                BaseActivity.clearScreen();
        }
    }
}

(2) Два метода, которые вызывают выше, выглядят следующим образом:

public static void unlockScreen () {
    if (current == null) return;

    Log.i( Constants.TAG, "Turning on screen ... " );

    Window window = current.getWindow();
    window.addFlags( WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD );
    window.addFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED );
    window.addFlags( WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON   );
}

public static void clearScreen () {
    if (current == null) return;

    Log.i( Constants.TAG, "Clearing screen flag when on ... " );

    Window window = current.getWindow();
    window.clearFlags( WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD );
    window.clearFlags( WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED );
    window.clearFlags( WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON   );
}

private static BaseActivity current;

@Override
protected void onResume () {
    current = this;
}

(3) В основном классе активности метод onCreate() регистрирует получателя:

    IntentFilter filter = new IntentFilter( Intent.ACTION_SCREEN_ON );
    filter.addAction( Intent.ACTION_SCREEN_OFF );
    registerReceiver(new ScreenReceiver(), filter);

Ответ 4

Вы можете узнать о нажатии кнопки Power Button, но я не думаю, что вы сможете переопределить его, и вы сможете отменить диалог для отключения питания и показать что-то еще.

Вот что я пробовал,

package com.easylogs.app;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

public class CloseSystemDialogsIntentReceiver extends BroadcastReceiver {
    public void onReceive(final Context context, final Intent intent) {
        Log.i("HERE", "------------------------------------HERE");
        Toast.makeText(context, "OFFFFFFFFFFFFFFFF",Toast.LENGTH_LONG).show();
    }
}

и объявление в Manifest as,

    <receiver android:name="CloseSystemDialogsIntentReceiver">
    <intent-filter>
            <action android:name="android.intent.action.CLOSE_SYSTEM_DIALOGS" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

Ответ 5

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {

        return true;
    }

    return super.dispatchKeyEvent(event);
}

Вы пробовали код выше, где мы можем справиться с событием ключевого ключа. Также посмотрите на LINK, который обработал нажатие кнопки питания.

Ответ 6

Я знаю его слишком поздно, но может быть полезен для других разработчиков в будущем. Протестировано через Android N. Ссылка из fooobar.com/questions/21963/...

 @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if(!hasFocus) {
           Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
            sendBroadcast(closeDialog);
        }
    }