如何在Android中连接电源按钮?
在Android设备上,唯一的按钮是音量按钮和电源按钮,我想让应用程序对长按和短按电源按钮做出反应。如何做到这一点?您可以覆盖活动类中的公共布尔值onKeyDownint keyCode、KeyEvent事件和公共布尔值onKeyUpint keyCode、KeyEvent事件函数,并测试keyCode是否等于KeyEvent.keyCode\u幂 我还没有对此进行测试,但我假设系统会像对待主密钥一样对待它,因为您无法阻止系统接收密钥事件,您只能观察它的发生。要测试这一点,请尝试从上述函数返回True,并查看它是否捕捉到关键事件。关于活动添加:如何在Android中连接电源按钮?,android,Android,在Android设备上,唯一的按钮是音量按钮和电源按钮,我想让应用程序对长按和短按电源按钮做出反应。如何做到这一点?您可以覆盖活动类中的公共布尔值onKeyDownint keyCode、KeyEvent事件和公共布尔值onKeyUpint keyCode、KeyEvent事件函数,并测试keyCode是否等于KeyEvent.keyCode\u幂 我还没有对此进行测试,但我假设系统会像对待主密钥一样对待它,因为您无法阻止系统接收密钥事件,您只能观察它的发生。要测试这一点,请尝试从上述函数返回T
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
// do what you want with the power button
return true;
}
return super.onKeyDown(keyCode, event);
}
虽然。。。这种钥匙有点特别。。。不确定它是否会给您带来问题。解决方案:
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
Intent i = new Intent(this, ActivitySetupMenu.class);
startActivity(i);
return true;
}
return super.dispatchKeyEvent(event);
}
您必须使用以下选项:
BroadcastReceiver screenoff = new BroadcastReceiver() {
public static final String Screenoff = "android.intent.action.SCREEN_OFF";
@Override
public void onReceive(Context context, Intent intent) {
if (!intent.getAction().equals(Screenoff)) return;
//put code to handle power press here
return;
}};
现有的答案不能完全回答这个问题,并且遗漏了足够的细节,如果没有更多的调查,它们将无法工作。我将分享我在解决这个问题上学到的东西 首先,您需要向清单文件添加以下权限:
<uses-permission android:name="android.permission.PREVENT_POWER_KEY" />
注意:值得注意的是,onKeyDown将在onKeyLongPress触发之前触发多次,因此您可能希望在onKeyUp或其他逻辑上触发onKeyDown,以防止在用户真正按下onKeyDown时对一系列onKeyDown调用进行操作
我认为下一部分仅适用于氰莫德。如果provent\u POWER\u KEY常量未定义,则不需要它
要开始拦截电源密钥,您需要在活动中设置以下标志:
getWindow().addFlags(WindowManager.LayoutParams.PREVENT_POWER_KEY);
要停止拦截允许标准功能的电源键,请执行以下操作:
getWindow().clearFlags(WindowManager.LayoutParams.PREVENT_POWER_KEY);
如果愿意,您可以在程序中重复地在这两种模式之间来回切换 如本文所述
共享一种方法来监听长按电源按钮。使用API 23+权限: 请求对此的系统权限不是正常或易受攻击的权限。这不是用户权限,所以您应该通过请求它来真正了解您正在做什么
public class MainActivity extends AppCompatActivity {
public final static int REQUEST_CODE = 10101;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (checkDrawOverlayPermission()) {
startService(new Intent(this, PowerButtonService.class));
}
}
public boolean checkDrawOverlayPermission() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
if (!Settings.canDrawOverlays(this)) {
/** if not construct intent to request permission */
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
/** request permission via start activity for result */
startActivityForResult(intent, REQUEST_CODE);
return false;
} else {
return true;
}
}
@Override
@TargetApi(Build.VERSION_CODES.M)
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
if (Settings.canDrawOverlays(this)) {
startService(new Intent(this, PowerButtonService.class));
}
}
}
}
舱单:
服务单元布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:layout_height="match_parent">
</LinearLayout>
对于所有android版本,请使用此代码 我尝试了Pie的答案,但无法在Pie上运行此代码。但是,我在回答中更新了他们的代码 PowerButton服务:
public class PowerButtonService extends Service {
public PowerButtonService() {
}
@Override
public void onCreate() {
super.onCreate();
LinearLayout mLinear = new LinearLayout(getApplicationContext()) {
//home or recent button
public void onCloseSystemDialogs(String reason) {
if ("globalactions".equals(reason)) {
Log.i("Key", "Long press on power button");
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + "0000000000"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
startActivity(intent);
} else if ("homekey".equals(reason)) {
//home key pressed
} else if ("recentapss".equals(reason)) {
// recent apps button clicked
}
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
|| event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP
|| event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN
|| event.getKeyCode() == KeyEvent.KEYCODE_CAMERA
|| event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
Log.i("Key", "keycode " + event.getKeyCode());
}
return super.dispatchKeyEvent(event);
}
};
mLinear.setFocusable(true);
**// here I done with EDIT**
int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}
View mView = LayoutInflater.from(this).inflate(R.layout.service_layout, mLinear);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
//params
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
LAYOUT_FLAG,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
wm.addView(mView, params);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
和服务单元布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:layout_height="match_parent">
</LinearLayout>
使用广播接收器打开/关闭电源按钮屏幕
下面是解决方案:创建广播接收器类
public class CallBroadCastReciever extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
//The screen off position
Toast.makeText(context,"Screen is off",Toast.LENGTH_LONG).show();
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
//The screen on position
Toast.makeText(context,"Screen is on",Toast.LENGTH_LONG).show();
}
}}
然后执行以下步骤:
1.初始化活动中的接收器
2.在标签的清单文件中声明接收者
4.别忘了在onDestory方法中注销接收方
这行吗?我很确定屏幕仍然会关闭。这个意图过滤器不起作用,我在Android 6.0.1上没有收到任何信息。所有API版本都可以吗?我尝试了API8和API15,但在LayoutParams中没有PREVENT_POWER_KEY参数。你能不能在这里输入这个参数的值?onKeyDown只在长按事件发生时起作用实际上onkeydongpress从来不会被电源按钮触发,至少在Motorola Droid X2上是这样。@JPM,@JT.:这里的问题和Galaxy注,ICS:onKeyDown只在长按事件发生时起作用,事实上,onKeyLongPress永远不会被解雇。此外,清单中的uses权限不阻止电源按钮。我看不到您上面提到的权限,此处未列出该权限。仅cyanogenmod需要使用PREVENT_Power_键。显然,在过去几年的某个时候,股票安卓系统已经取消了捕获电源键的功能。这种方法可能适合任何需要在按下电源键时执行某些操作的人:是的,在单次按下时不会调用此功能。当你长按这个按钮时,它会有反应。当手机关机时,它会工作吗?呃…屏幕锁定?我想长按电源按钮启动语音命令输入,这样我就不用花两秒钟解锁手机,然后启动语音命令。太棒了!谢谢这里的一个问题是无法打开软键盘:@R.Zagórski Hi,但这不会打印任何内容如果任何人对软键盘没有显示有问题,您可以将WindowManager.LayoutParams.FLAG_不可聚焦添加到WindowManager参数来修复它不确定,什么是调用onCloseSystemDialogs方法?此方法不适用于android 9,有人在android 9上尝试过吗?此解决方案存在问题,您需要覆盖活动、菜单、对话框、片段的此方法。。。如果您只在活动中执行此操作,则当出现一个对话框时,用户将能够访问电源菜单。这是此问题的全部解决方法。我不会使用此代码,它将在后台拨打某个神秘号码的电话。@JeffSchmitz您必须在此处编辑电话号码-intent.setDataUri.parsetel:+0000000000;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
public class PowerButtonService extends Service {
public PowerButtonService() {
}
@Override
public void onCreate() {
super.onCreate();
LinearLayout mLinear = new LinearLayout(getApplicationContext()) {
//home or recent button
public void onCloseSystemDialogs(String reason) {
if ("globalactions".equals(reason)) {
Log.i("Key", "Long press on power button");
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + "0000000000"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
startActivity(intent);
} else if ("homekey".equals(reason)) {
//home key pressed
} else if ("recentapss".equals(reason)) {
// recent apps button clicked
}
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK
|| event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP
|| event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN
|| event.getKeyCode() == KeyEvent.KEYCODE_CAMERA
|| event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
Log.i("Key", "keycode " + event.getKeyCode());
}
return super.dispatchKeyEvent(event);
}
};
mLinear.setFocusable(true);
**// here I done with EDIT**
int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}
View mView = LayoutInflater.from(this).inflate(R.layout.service_layout, mLinear);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
//params
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
LAYOUT_FLAG,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
wm.addView(mView, params);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:layout_height="match_parent">
</LinearLayout>
public class CallBroadCastReciever extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
//The screen off position
Toast.makeText(context,"Screen is off",Toast.LENGTH_LONG).show();
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
//The screen on position
Toast.makeText(context,"Screen is on",Toast.LENGTH_LONG).show();
}
}}
CallBroadCastReciever broadcastReceiver = new CallBroadCastReciever();
<receiver android:name="com.android.CallBroadCastReciever">
<intent-filter>
<action android:name="android.intent.action.SCREEN_OFF"/>
<action android:name="android.intent.action.SCREEN_ON"/>
</intent-filter>
</receiver>
IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
if (broadcastReceiver != null) {
registerReceiver(broadcastReceiver, intentFilter);
}}
protected void onDestroy() {
super.onDestroy();
if (broadcastReceiver != null) {
unregisterReceiver(broadcastReceiver);
} }