Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect power button long press

Tags:

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 when trying to power off the device, I'd like to know if you can detect that event, and let or not show that dialog where appears (Restart, Shut Down, etc...)

I've tried this:

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

but it doesn't show up, also it should work as a service, I mean that the app can or not be opened to show that toast.

EDIT

This is how I put the 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     } } 

It works fine, but only when the device is unlocked, when the device is locked isn't showing anything.

Also I'm trying to figure out how to remove the dialog when the user click powerbutton I tried this :

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

But if I want to show it again, how can I do it?

like image 317
Skizo-ozᴉʞS Avatar asked Aug 21 '16 13:08

Skizo-ozᴉʞS


People also ask

What does long press mean on my phone?

Many times, touch & hold lets you take action on something on your screen. For example, to move an app icon on your home screen, touch & hold, then drag it to the new location. Sometimes touch & hold is called a "long press."


2 Answers

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:

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

service_layout:

<?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> 
like image 190
R. Zagórski Avatar answered Sep 21 '22 18:09

R. Zagórski


Go with this

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

And when you want to capture that event do this

@Override public boolean onKeyDown(int keyCode, KeyEvent event) {     if (keyCode == KeyEvent.KEYCODE_POWER) {         // this is method which detect press even of button         event.startTracking(); // Needed to track long presses         return true;     }     return super.onKeyDown(keyCode, event); }  @Override public boolean onKeyLongPress(int keyCode, KeyEvent event) {     if (keyCode == KeyEvent.KEYCODE_POWER) {         // Here we can detect long press of power button         return true;     }     return super.onKeyLongPress(keyCode, event); } 

It can be done with broadcast receiver. see this answer

like image 44
TapanHP Avatar answered Sep 25 '22 18:09

TapanHP