36

Вопрос по android – Переопределить кнопку питания, как кнопка «Домой»

Ну, я делаю что-то, в чем я хочу отключить все жесткие кнопки устройства. Жесткие кнопки, такие как Power, Home, Volume up, Volume down, Search, Back. Я успешно переопределил почти все ...

Почему вы, люди, всегда думаете о неправильном использовании технологий? Я не могу понять

от Azhar Shaikh

Вы не можете сделать это со стандартным Android. Также есть много вопросов относительно этого на<code>Stackoverflow.com</code>Что вы ожидаете здесь, на вашем сейчас?

от Luksprog

Таким образом, вы можете похитить чей-то телефон?

от Bill

рутованное или некорневое устройство?

от Morrison Chang

@MorrisonChang не-root

от Azhar Shaikh

6 ответов

2

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

        return true;
    }

    return super.dispatchKeyEvent(event);
}

Вы пробовали приведенный выше код, где мы можем обработать событие Power Key. Также посмотрите на этоССЫЛКА НА САЙТ который обработал событие нажатия кнопки питания.

50

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

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

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

Это вызывает некоторое обсуждение. Короткая версия, однако, проста:this is not possible, without custom modification to your firmware or the core of the Android operating system, for a limited number of devices.

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

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

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

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

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

8

Напротив на все ответы .. Проверьте это:


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

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

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

1

Я знаю, что это слишком поздно, но может быть полезно для других разработчиков в будущем. ПротестированоAndroid N . Reference from https://stackoverflow.com/a/15828592/1065357

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

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

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

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

и декларация в Манифесте как,

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

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

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

Похожие вопросы