Detect power button long press

前端 未结 11 2293
轮回少年
轮回少年 2020-11-27 18:38

I\'ve been reading some posts here on Stackoverflow, and I didn\'t find a good solution, I\'m wondering if it\'s possible to detect when the user long press the power button

11条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-27 19:07

    Sharing my method to do what you would like to achieve.

    Basically, what it does is

    1. Asking for system permission to draw overlay (This is not a normal or vulnerable permission). This is not a user permission, so You should really know, what you are doing, by asking for it.

      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));
                  }
              }
          }
      }
      
    2. Starting a service and adds a special view to WindowManager

    3. Waiting for an action inside View's onCloseSystemDialogs method.

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

    Manifest:

    
    
    
        
    
        
            
                
                    
                    
                
            
    
            
            
    
        
    
    
    

    service_layout:

    
    
    
    
    

提交回复
热议问题