好吧,我正在做一些事情,我想禁用设备的所有硬按钮。
硬按钮,如电源、主页、调高音量、调低音量、搜索、返回。
除了Power,我已经成功地覆盖了这里的几乎所有按钮。
所以我只想让你们看到,请分享一些想法,这样我就可以不受影响了。
我在DispatchKeyEvent()上
获得长按电源键事件,就像我想抓住相同的短按一样。此外,当按下电源时,我还试图通过获取SCREEN_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;
}
}
}
禁用硬件按钮.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();
}
}
唷。这是一个颇有争议的问题,背后有大量的评论。
首先,让我稍微改写一下你的问题。如果我理解清楚,您希望在活动期间禁用设备上的所有物理按钮。这包括电源按钮,您可以通过处理ACTION_SCREEN_OFF
意图来检测它。对于此方案,您当前(成功的)解决方法是广播ACTION_SCREEN_ON
,在屏幕关闭时将其踢回生机,前提是主机正确实现了此操作。
您现在希望加倍努力,使此操作变得不必要,当(并且仅当)您能够在将ACTION_SCREEN_OFF
发送到系统之前捕获并处理它。这是否可能,如果是,如何?
这需要一些讨论。然而,简短的版本很简单:对于有限数量的设备,如果不对您的固件或Android操作系统的核心进行自定义修改,这是不可能的。
据记录,Android系统将此定义为广播操作。遵循消息传播的发布-订阅模式,此消息将通知所有相关方此操作。因为此消息是由系统发送的,因为消息堆栈由系统管理,并且因为消息也由系统接收,所以您的代码根本没有注入到正确的位置来阻止此消息的接收。
此外,对于某些设备,这将是一个没有任何程序中断的物理交换机。充其量,Android系统可以希望在事件发生时处理事件,这正是为什么广播消息在服务堆栈中是一种特殊情况。据我所知,基于此场景的稀疏文档,这就是为什么在我们考虑任何可能的滥用向量之前,它不是一个现成的、受支持的功能。
如果您有能力修改相关设备的物理硬件,那么您最好的方法实际上是更简单的方法:限制访问、损坏或禁用物理电源按钮。在许多情况下,这是不可取的,但这在您的Android设备被用作销售点或公共服务机器的情况下有效。如果这不可行,则只需要对电源按钮的访问设置物理限制,通过发送<code>ACTION_screen_on<code>来处理其余情况(例如,spot尝试切换屏幕)。
请记住,这种策略并非万无一失。请胜任并记录好该过程,以免成为下一次2600次暴露的素材。
祝您的应用程序好运。
与所有的答案相反..看看这个:
@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上测试)
以下是我所做的:
(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);