How to hook into the Power button in Android?

2020-01-22 12:30发布

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

标签: android
9条回答
smile是对你的礼貌
2楼-- · 2020-01-22 12:32

Use Broadcast receiver for power button (Screen On/Off)event

here is solution: create broadcast receiver class

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

then follow below steps: 1. Initialize receiver in activity

CallBroadCastReciever broadcastReceiver = new CallBroadCastReciever();

2.Declare receiver in manifest file in tag

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

3.For send action and data from activity to receiver put below code in onCreate() or onStrat() method

IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_SCREEN_OFF);

if (broadcastReceiver != null) {
    registerReceiver(broadcastReceiver, intentFilter);
}}

4.Don't forget to unregister receiver in onDestory() method

 protected void onDestroy() {
        super.onDestroy();
 if (broadcastReceiver != null) {
                unregisterReceiver(broadcastReceiver);
             } }
查看更多
Summer. ? 凉城
3楼-- · 2020-01-22 12:33

The existing answers don't completely answer the question and leave out enough details that they won't work without more investigation. I'll share what I've learned solving this.

First you need to add the following permission to your manifest file:

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

To handle short and long presses add the following overrides to your activity class:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_POWER) {
        // Do something here...
        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) {
        // Do something here...
        return true;
    }
    return super.onKeyLongPress(keyCode, event);
}

Note: It is worth noting that onKeyDown() will fire multiple times before onKeyLongPress does so you may want to trigger on onKeyUp() instead or other logic to prevent acting upon a series of onKeyDown() calls when the user is really holding it down.

I think this next part is for Cyanogenmod only. If the PREVENT_POWER_KEY constant is undefined then you should not need it.

To start intercepting the power key you need to set the following flag from your activity:

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

To stop intercepting the power key (allowing standard functionality):

getWindow().clearFlags(WindowManager.LayoutParams.PREVENT_POWER_KEY);

You can switch back and forth between the two modes repeatedly in your program if you wish.

查看更多
Bombasti
4楼-- · 2020-01-22 12:33

For all android versions use this code.

I tried R. Zagórski's answer, but I am not able to run this code on Pie. However, I have updated their code in my answer.

PowerButtonService:

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:" + "9690008019"));
                    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;
    }
}

and service_layout:

<?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>
查看更多
对你真心纯属浪费
5楼-- · 2020-01-22 12:38

you have to use this:

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;

}};
查看更多
家丑人穷心不美
6楼-- · 2020-01-22 12:48

On you activity add:

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

Though... this kind of keys are somehow special... not sure if it can give problems to you.

查看更多
在下西门庆
7楼-- · 2020-01-22 12:50

Solution:

@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);
}
查看更多
登录 后发表回答