像主页按钮一样覆盖电源按钮

Moh*_*ikh 35 android overriding home-button

好吧,我正在做一些我想要禁用设备的所有硬按钮的东西.

电源,家庭,音量增大,音量减小,搜索,返回等硬按钮.

我已经成功覆盖几乎所有的按钮,在这里除了电源.

所以我只是希望你们有人看到并请分享一些想法,这样我就能把它拿走.

我正在进行长按 Power keyevent onDispatchKeyEvent(),就像我想抓住同样的短按一样.此外压迫力的时候我还试图阻止屏幕关闭通过获取BroadcastSCREEN_OFF,我成功地接受它,但我不能处理它.

谢谢.

然后,我创建了一个ReceiverScreen,它接收/关闭Screen的广播

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
}
}
Run Code Online (Sandbox Code Playgroud)

MrG*_*mez 52

唷.这是一个非常有争议的问题,背后有很多评论.

首先让我重新提一下你的问题.如果我理解清楚,您希望在活动期间禁用设备上的所有物理按钮.这包括电源按钮,您可以通过处理ACTION_SCREEN_OFF意图来检测该按钮.此方案的当前(成功)解决方法是广播ACTION_SCREEN_ON,在屏幕关闭时将其恢复生命,前提是主机正确实现此功能.

你现在想通过渲染这个动作来加倍努力,如果(并且只有)你能够ACTION_SCREEN_OFF在它被发送到系统之前捕获和处理.这是可能的,如果是的话,怎么样?

这有一些讨论.然而,简短版本很简单:如果没有对固件或Android操作系统的核心进行自定义修改,对于数量有限的设备,这是不可能的.

据记载,Android系统将此定义为广播操作.遵循消息传播的发布 - 订阅模式,此消息将通知所有相关方此操作.因为此消息是由系统发送的,因为消息堆栈由系统管理,并且因为系统也接收到消息,所以您的代码不会在正确的位置注入以阻止接收此消息.

此外,对于某些设备,这将是一个没有编程中断的物理交换机.充其量,Android系统可以希望在事件发生时处理事件,这正是为什么这个广播消息是服务栈中的特殊情况.据我所知并基于此场景的稀疏文档,这就是为什么在我们考虑任何可能的滥用向量之前,它不是一个开箱即用的支持功能.

如果您能够修改相关设备的物理硬件,则最好的办法实际上是一个更简单的方法:限制访问,修改或禁用物理电源按钮.在许多情况下,这是不可取的,但这适用于使用Android设备的情况,例如,作为销售点或公共服务机器.如果这是不可行的,那么对访问电源按钮的物理限制可能就是所需要的,通过发送处理剩余的情况(例如,点击尝试切换屏幕)ACTION_SCREEN_ON.

请记住,这种策略并非万无一失.做得很好并且记录好这个程序,以免你成为下一个2600曝光的素材.

祝你的应用好运.


ama*_*Bit 9

与所有答案相反..检查出来:


@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);
}
Run Code Online (Sandbox Code Playgroud)

它能做什么:

每当用户按下电源按钮时.我们甚至在看到之前取消了对话!:).这对我有用..(测试2)


Sil*_*ria 5

这是我所做的:

(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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

(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;
}
Run Code Online (Sandbox Code Playgroud)

(3)在主要活动类onCreate()方法中注册接收者:

    IntentFilter filter = new IntentFilter( Intent.ACTION_SCREEN_ON );
    filter.addAction( Intent.ACTION_SCREEN_OFF );
    registerReceiver(new ScreenReceiver(), filter);
Run Code Online (Sandbox Code Playgroud)