Overriding the Power Button in Android

Override Power button just like Home button

Phew. This is quite a contended question, with a great deal of commentary behind it.

Let me begin by rephrasing your question a bit. If I understand clearly, you'd like to disable all physical buttons on the device for the duration of your activity. This is inclusive of the power button, which you detect by handling the ACTION_SCREEN_OFF intent. Your current (successful) workaround for this scenario is to broadcast an ACTION_SCREEN_ON, kicking the screen back to life when it's turned off, provided the host implements this correctly.

You'd now like to go the extra mile, by rendering this action unnecessary, if (and only if) you are able to catch and handle ACTION_SCREEN_OFF before it gets sent to the system. Is this possible, and if so, how?

This bears some discussion. The short version, however, is simple: this is not possible, without custom modification to your firmware or the core of the Android operating system, for a limited number of devices.

The Android system, as far as is documented, defines this as a broadcast action. Following the publish-subscribe pattern of message propagation, this message will notify all concerned parties of this action. Because this message is sent by the system, because the message stack is managed by the system, and because the message is also received by the system, your code simply isn't injected in the right place to block the reception of this message.

Furthermore, for some devices, this will be a physical switch that has no programmatic interrupt whatsoever. At best, the Android system can hope to handle for the event when it happens, which is precisely why this broadcast message is something of a special case in the service stack. To the best of my knowledge and based upon the sparse documentation on this scenario, this is why it's not an out-of-the-box, supported feature, before we consider any of the possible vectors for abuse.

Your best recourse is actually a much simpler one, if you have the ability to modify the physical hardware for the device in question: restrict access to, mangle, or otherwise disable the physical power button. In many scenarios this is undesirable, but this works in situations where your Android device is being used, for example, as a point-of-sale or a public service machine. If this is unworkable, placing physical restrictions on access to the power button may be all that's required, handling for the remainder of cases (for example, spot attempts to toggle the screen) by sending ACTION_SCREEN_ON.

Just remember, this strategy isn't foolproof. Do this competently and document the procedure well, lest you become fodder for the next 2600 exposé.

Best of luck with your application.

Android: Overriding the power button in a Fragment

You can use this to prevent screen from locking

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

While using in fragment

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

Use a BroadcastReceiver and listen for the android.intent.action.SCREEN_OFF or Intent.ACTION_SCREEN_OFF which is sent when power button is pressed (and screen is on). What i think is that overriding the power button is not possible , because of security issues.

Overriding the power button in Android

I found the answer and this can be done by using the AlarmManager with the PowerManager

@Override
public void onReceive(Context context, Intent intent) {
if ((intent.getAction().equals(Intent.ACTION_SCREEN_OFF))) {

PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "TEST");
wakeLock.acquire();

AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent inten = new Intent(context,NewActivity.class);
PendingIntent pi = PendingIntent.getActivity(context, 0, inten, 0);
alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 100, pi);
}
}

// Finish your WakeLock HERE. call this method after U put the activity in front or when u exit from the new activity.
public void finishWakeLocker(){
if (wakeLock != null)
wakeLock.release();
}

Here first the screen goes off and then I'm waking it by using the AlarmManager. I couldn't stop the screen going to off state by overriding the Power button controls. I'm just waking up the device as soon as it goes to sleep state.

Android power button override and disable while application runing

This is not possible, for security reasons. HOME and POWER buttons are two things you will not be able to directly override without system-grade permissions. After all, the user wouldn't like your app to take control of their device, would they? ;-)

You should plan the functionality in such a way that a wakelock or

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

is enough :-)

EDIT:

There are tutorials such as the one uday linked, but the effects are generally unreliable and work only on some devices. I have developed an app like that and trust me, you do not want to have to debug this ;-)

How to Override Power Button In Android Device

You download the Android source code, modify what it shows on the power menu, compile your own version of Android based on your modified code, package that as a custom ROM, and install that ROM on your Android device.

There is no means for an ordinary Android SDK app to affect the power menu.

I cannot rule out the possibility of modifying the power menu on rooted devices (e.g., Xposed framework), though.

How to override double or even 3 times clicking Power button or even Volume UP/DOWN keys in Android Using a service in the background?

Since nobody tried to solve the question or maybe couldn't even understand the question, fortunately after many hours of searching the web I found this awesome website that solves exactly my problem and wanted to post it here too.

Problems which are solved now :

  1. My Application always runs in the background even if it is killed/destroyed or removed from the System Tray.
  2. The service always listens to the POWER_BUTTON when clicked.
  3. The SDK supports this since it uses only BroadCast Receivers and Services.

I am just writing down the steps in case the link may not work or be removed in future:

1.First we will create a broadcast receiver which can listen and process android screen on / off broadcast event as below.

ScreenOnOffReceiver.java

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class ScreenOnOffReceiver extends BroadcastReceiver {

private final static String SCREEN_TOGGLE_TAG = "SCREEN_TOGGLE_TAG";

@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(Intent.ACTION_SCREEN_OFF.equals(action))
{
Log.d(SCREEN_TOGGLE_TAG, "Screen is turn off.");
}else if(Intent.ACTION_SCREEN_ON.equals(action))
{
Log.d(SCREEN_TOGGLE_TAG, "Screen is turn on.");
}}
}

2. Register And Unregister ScreenOnOffReceiver In Activity.

Now we will create an activity and register ScreenOnOffReceiver in it’s onCreate() method, and unregister the receiver in it’s onDestroy() method as below.

ScreenOnOffActivity.java

import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.dev2qa.example.R;
import com.dev2qa.example.broadcast.receiver.ScreenOnOffReceiver;

public class ScreenOnOffActivity extends AppCompatActivity {

private ScreenOnOffReceiver screenOnOffReceiver = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_on_off);

setTitle("dev2qa.com - Keep BroadcastReceiver Running After App Exit.");

// Create an IntentFilter instance.
IntentFilter intentFilter = new IntentFilter();

// Add network connectivity change action.
intentFilter.addAction("android.intent.action.SCREEN_ON");
intentFilter.addAction("android.intent.action.SCREEN_OFF");

// Set broadcast receiver priority.
intentFilter.setPriority(100);

// Create a network change broadcast receiver.
screenOnOffReceiver = new ScreenOnOffReceiver();

// Register the broadcast receiver with the intent filter object.
registerReceiver(screenOnOffReceiver, intentFilter);

Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "onCreate: screenOnOffReceiver is registered.");

}

@Override
protected void onDestroy() {
super.onDestroy();

// Unregister screenOnOffReceiver when destroy.
if(screenOnOffReceiver!=null)
{
unregisterReceiver(screenOnOffReceiver);
Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "onDestroy: screenOnOffReceiver is unregistered.");
}
}
}

Run Above Activity In Below Steps.

  1. Start the activity, there is a log message which said the broadcast receiver has been registered in the activity’s onCreate() method.
  2. Press the power button to turn off screen.
  3. Press the power button again to turn on screen.
  4. You can see log data in android monitor console for above steps.
  5. Type the back menu to exit the activity. You can see the broadcast receiver is unregistered in the activity’s onDestroy() method also.
  6. Press the power button to execute step 2 , 3 again, but there is not any log data printed in the android monitor console.

Runnindg Activity

3. Register And Unregister Broadcast Receiver In Android Background Service

When you register the broadcast receiver in activity, it will be stopped after the activity exit.

To resolve this problem, we will create an android service object, and register and unregister the broadcast receiver in the service object.

Because the android service object will still run at the background after the activity exit, so the broadcast receiver will still run also after the android app exit.

3.1 Create Android Service Class.

3.1.1 Create A Java Class That Extends android.app.Service.

ScreenOnOffBackgroundService.java

import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import ScreenOnOffReceiver;

public class ScreenOnOffBackgroundService extends Service {

private ScreenOnOffReceiver screenOnOffReceiver = null;

@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onCreate() {
super.onCreate();

// Create an IntentFilter instance.
IntentFilter intentFilter = new IntentFilter();

// Add network connectivity change action.
intentFilter.addAction("android.intent.action.SCREEN_ON");
intentFilter.addAction("android.intent.action.SCREEN_OFF");

// Set broadcast receiver priority.
intentFilter.setPriority(100);

// Create a network change broadcast receiver.
screenOnOffReceiver = new ScreenOnOffReceiver();

// Register the broadcast receiver with the intent filter object.
registerReceiver(screenOnOffReceiver, intentFilter);

Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "Service onCreate: screenOnOffReceiver is registered.");
}

@Override
public void onDestroy() {
super.onDestroy();

// Unregister screenOnOffReceiver when destroy.
if(screenOnOffReceiver!=null)
{
unregisterReceiver(screenOnOffReceiver);
Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "Service onDestroy: screenOnOffReceiver is unregistered.");
}
}
}

3.1.2 Add Service Xml Tag In AndroidManifest.xml File.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="put your own package">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<activity android:name=".broadcast.activity.ScreenOnOffActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service android:enabled="true" android:name=".broadcast.service.ScreenOnOffBackgroundService" />
</application>

</manifest>

3.1.3 Change Activity Java Code To Below.

Please notice the java code that start the service object.

Intent backgroundService = new Intent(getApplicationContext(), ScreenOnOffBackgroundService.class);
startService(backgroundService);

ScreenOnOffActivity.java

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.dev2qa.example.R;
import com.dev2qa.example.broadcast.receiver.ScreenOnOffReceiver;
import com.dev2qa.example.broadcast.service.ScreenOnOffBackgroundService;

public class ScreenOnOffActivity extends AppCompatActivity {

private ScreenOnOffReceiver screenOnOffReceiver = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_on_off);

setTitle("dev2qa.com - Keep BroadcastReceiver Running After App Exit.");

Intent backgroundService = new Intent(getApplicationContext(), ScreenOnOffBackgroundService.class);
startService(backgroundService);

Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "Activity onCreate");
}

@Override
protected void onDestroy() {
super.onDestroy();
Log.d(ScreenOnOffReceiver.SCREEN_TOGGLE_TAG, "Activity onDestroy");
}
}

Run the example again, you can see below picture. From the logcat output, we can see the broadcast receiver still running after the android app exit.

Android Keep Broadcast Receiver GIF

(source: dev2qa.com)

Disable or override Power button onClick method

i don't think you can capture the event of clicking on the power button.

the events of the screen occur after they have occurred.

you might be able to capture the power button if the device is rooted (or if the app is a system app), but i'm not sure how.

the only thing that is close to what you want (that i know) is to listen to the event of screen being turned off, and then cause the screen to be turned on ,which (according to what i remember, might be wrong on this) requires the permission "DEVICE_POWER" .



Related Topics



Leave a reply



Submit