检测电源键长按

新手上路,请多包涵

我一直在 Stackoverflow 上阅读一些帖子,但没有找到好的解决方案,我想知道是否可以检测用户在尝试关闭设备电源时长按电源按钮的时间,我想知道您是否可以检测到该事件,并允许或不显示出现的对话框(重启、关机等)

我试过这个:

 @Override
public boolean dispatchKeyEvent(KeyEvent event) {
        Toast.makeText(MainActivity.this, event.getKeyCode(), Toast.LENGTH_SHORT).show();
    return true;
}

但它没有出现,它也应该作为一项服务工作,我的意思是可以打开或不打开该应用程序以显示该吐司。

编辑

这就是我放置 onCloseSystemDialog 的方式

//home or recent button
public void onCloseSystemDialogs(String reason) {
    if ("globalactions".equals(reason)) {
        Toast.makeText(PowerButtonService.this, "yaps", Toast.LENGTH_SHORT).show();
        Intent i= new Intent(getBaseContext(), Demo.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getApplication().startActivity(i);
    //} else if ("homekey".equals(reason)) {
        //home key pressed
    //} else if ("recentapss".equals(reason)) {
        // recent apps button clicked
    }
}

它工作正常,但只有当设备解锁时,当设备锁定时不显示任何内容。

我也想弄清楚如何在用户单击电源按钮时删除对话框我试过这个:

 getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);

但是如果我想再次展示它,我该怎么办呢?

原文由 Skizo-ozᴉʞS 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 740
2 个回答

分享我的方法来做你想实现的事情。

基本上,它的作用是

  1. 请求系统权限以 绘制叠加层(这不是正常或易受攻击的权限)。这不是用户许可,因此您应该通过请求真正知道自己在做什么。
    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));
               }
           }
       }
   }

  1. 启动服务并添加一个特殊的视图 WindowManager

  2. ViewonCloseSystemDialogs 方法中等待一个动作。

    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");
                   } else if ("homekey".equals(reason)) {
                       //home key pressed
                   } else if ("recentapps".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);

           View mView = LayoutInflater.from(this).inflate(R.layout.service_layout, mLinear);
           WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);

           //params
          final WindowManager.LayoutParams params;
   if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {

       params = new WindowManager.LayoutParams(
               100,
               100,
               WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
               WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                       | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                       | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
               PixelFormat.TRANSLUCENT);
   } else {
       params = new WindowManager.LayoutParams(
               100,
               100,
               WindowManager.LayoutParams.TYPE_PHONE,
               WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                       | WindowManager.LayoutParams.FLAG_FULLSCREEN
                       | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                       | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
               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"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="powerbuttonpress">

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <service
            android:name=".PowerButtonService"
            android:enabled="true"
            android:exported="true">
        </service>

    </application>

</manifest>

服务布局:

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

原文由 R. Zagórski 发布,翻译遵循 CC BY-SA 4.0 许可协议

我看到很多答案试图连接到电源按钮。但是,监听关机事件不是更容易吗?我不确定这是否符合您的需要,但看起来是这样。

只需将 Broadcastreceiver 注册到以下 操作

 <receiver android:name=".ShutdownReceiver">
    <intent-filter>
        <action android:name="android.intent.action.ACTION_SHUTDOWN" />
        <action android:name="android.intent.action.QUICKBOOT_POWEROFF" />
    </intent-filter>
</receiver>

不要忘记添加以下权限:

<uses-permission android:name="android.permission.DEVICE_POWER" />

原文由 Robin Dijkhof 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏