Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/234.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Android中连接电源按钮?_Android - Fatal编程技术网

如何在Android中连接电源按钮?

如何在Android中连接电源按钮?,android,Android,在Android设备上,唯一的按钮是音量按钮和电源按钮,我想让应用程序对长按和短按电源按钮做出反应。如何做到这一点?您可以覆盖活动类中的公共布尔值onKeyDownint keyCode、KeyEvent事件和公共布尔值onKeyUpint keyCode、KeyEvent事件函数,并测试keyCode是否等于KeyEvent.keyCode\u幂 我还没有对此进行测试,但我假设系统会像对待主密钥一样对待它,因为您无法阻止系统接收密钥事件,您只能观察它的发生。要测试这一点,请尝试从上述函数返回T

在Android设备上,唯一的按钮是音量按钮和电源按钮,我想让应用程序对长按和短按电源按钮做出反应。如何做到这一点?

您可以覆盖活动类中的公共布尔值onKeyDownint keyCode、KeyEvent事件和公共布尔值onKeyUpint keyCode、KeyEvent事件函数,并测试keyCode是否等于KeyEvent.keyCode\u幂

我还没有对此进行测试,但我假设系统会像对待主密钥一样对待它,因为您无法阻止系统接收密钥事件,您只能观察它的发生。要测试这一点,请尝试从上述函数返回True,并查看它是否捕捉到关键事件。

关于活动添加:

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