On an Android device, where the only buttons are the volume buttons and a power button, I want to make the app react to presses on the power button (long and short). How is
Sharing a method to listen for Power button long press. Works with API 23+ permissions:
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));
}
}
}
}
Starting a service and adds a special view to WindowManager
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 ("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);
View mView = LayoutInflater.from(this).inflate(R.layout.service_layout, mLinear);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
//params
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
100,
100,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
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: