Android.Intent.Action.Screen_On Doesn't Work as a Receiver Intent Filter

android.intent.action.SCREEN_ON doesn't work as a receiver intent filter

Following sage advice from CommonsWare
I have elected to try to remove the
long-living Service and use different
techniques.

Actually, I believe my advice was more of a light blue... :-)

But I still need to detect the screen
off and on events.

There are certain events that Android does not want to start up new processes for, so the device does not get too slow from all sorts of stuff all having to run at once. ACTION_SCREEN_ON is one of those. See this previous question for light blue advice on that topic.

So, you need to ask yourself, "Self, do I really need to get control on those events?". The core Android team would like it if your answer was "no".

How to launch an app when the screen unlocks?

To listen to screen on/off, your app should run by time and register Broadcast receiver to OS programmatically.

ScreenOnOffService.java

public class ScreenOnOffService extends Service {

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

public void onCreate() {
super.onCreate();
Log.i("ScreenOnOffService", "onCreate: ");
IntentFilter intentFilter = new IntentFilter();
// intentFilter.addAction("android.intent.action.SCREEN_OFF");
intentFilter.addAction("android.intent.action.SCREEN_ON");
registerReceiver(ScreenOnReceiver.newInstance(), intentFilter);
}

public void onDestroy() {
super.onDestroy();
Log.i("ScreenOnOffService", "onDestroy: ");
unregisterReceiver(ScreenOnReceiver.newInstance());
// startService(new Intent(this,ScreenOnOffService.class));
}

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

}

ScreenOnReceiver.java

public class ScreenOnReceiver extends BroadcastReceiver {

public static final String TAG = "ScreenOn";
public static volatile ScreenOnReceiver screenOn;

public static ScreenOnReceiver newInstance() {
if (screenOn == null) {
screenOn = new ScreenOnReceiver();
}
return screenOn;
}

@Override
public void onReceive(Context context, Intent intent) {
Log.i("hieuN", "intent: " + intent.getAction());
// do work. start activity.

}
}

Start service in activity

Intent service = new Intent(this, ScreenOnOffService.class);
startService(service);

Not able to get actions to fire USER_PRESENT or SCREEN_ON Android Emulator

From the "android.intent.action.SCREEN_ON" docs, "You cannot receive this through components declared in manifests, only by explicitly registering for it with

Context#registerReceiver(BroadcastReceiver, IntentFilter).

Example of registering explicitly:

myReceiver = new MyReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(myReceiver, filter);

Why isn't my Screen On/Off BroadcastReceiver working?

You can do this by trying dynamic calling of broadcast like below

public class YourActivity extends Activity {

//Create broadcast object
BroadcastReceiver mBroadcast = new BroadcastReceiver() {
//When Event is published, onReceive method is called
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.i("[BroadcastReceiver]", "MyReceiver");

if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.d("[BroadcastReceiver]", "Screen ON");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.d("[BroadcastReceiver]", "Screen OFF");
}

}
};

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

registerReceiver(mBroadcast, new IntentFilter(Intent.ACTION_SCREEN_ON));
registerReceiver(mBroadcast, new IntentFilter(Intent.ACTION_SCREEN_OFF));
}
}

Running a receiver even if the app is not open

You have registered the receiver in the manifest. So don't register and unregister it in the MainActivity. That's the problem. So once the app is killed, onDestroy() gets called and your receiver is unregistered and will no longer listen.

Declaring the the receiver in the manifest means that your app will always listen to broadcasts. And that's exactly what you want. So remove the register/unregister part from the MainActivity.

UPDATE: It seems that SCREEN_ON and SCREEN_OFF can't be registered via the manifest. This might possibly be for a security reason. So in this case you have to register this via code. But the problem here is that, once you quit the app, onDestroy() is called and you are no longer listening. If you are app really need this feature, you have to create a service and have that run constantly in the the background. You can use that to listen to the broadcast.

Android - how to receive broadcast intents ACTION_SCREEN_ON/OFF?

I believe that those actions can only be received by receivers registered in Java code (via registerReceiver()) rather than through receivers registered in the manifest.

Android broadcast receiver doesn't receive ACTION_SCREEN_ON

It's work for me on Android 4.0.4

BroadcastReceiver receiver = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {
if (intent == null)
return;
//do something you need when broadcast received

}
};
IntentFilter filter = new IntentFilter()
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);

context.registerReceiver(receiver, filter);

As for register receiver with action Intent.ACTION_SCREEN_ON and Intent.ACTION_SCREEN_OFF in Manifest.xml it don't help because Android code in PowerManagerService.java following:

...
mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
...

Implicit Broadcast Reciever isn't calling

From docs:

ACTION_BATTERY_CHANGED
Broadcast Action: This is a sticky broadcast containing the charging state, level, and other information about the battery. See BatteryManager for documentation on the contents of the Intent.

You cannot receive this through components declared in manifests, only by explicitly registering for it with Context.registerReceiver(). See ACTION_BATTERY_LOW, ACTION_BATTERY_OKAY, ACTION_POWER_CONNECTED, and ACTION_POWER_DISCONNECTED for distinct battery-related broadcasts that are sent and can be received through manifest receivers

So, you cannot use this BroadcastReceiver decalred in Manifest, only registering explicitly from your context.

Also, your power connection BroadcastReceiver seems correct. Try to separate it into another BroadcastReceiver, maybe action ACTION_BATTERY_CHANGED is interfering with other actions.

This is my declared BroadcastReceiver which I use and it's working in my app.

<receiver android:name=".PowerConnectionBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
</intent-filter>
</receiver>

PowerConnectionBroadcastReceiver

public class PowerConnectionBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "PowerRcvr";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_POWER_CONNECTED)) {
Log.d(TAG, "Device is charging");
} else if (action.equals(Intent.ACTION_POWER_DISCONNECTED)) {
Log.d(TAG, "Device is NOT charging");
} else {
Log.d(TAG, "Unable to check if device is charging or not");
}
}
}

NOTE: This code is working on Android 8 with targetSdkVersion 25 or lower.

In targetSdkVersion 26 or higher most of BroadcastReceivers doesn't work through Manifest due to background limitations. Here are documentation (thanks to Pawel) about that. So your IntentFilters wont work. To keep it working you can download your targetSdkVersion to 25 or lower.

Why my BroadcastReceiver doesn't work?

I solved!

"unlike other broad casted intents, for Intent.ACTION_SCREEN_OFF and Intent.ACTION_SCREEN_ON you CANNOT declare them in your Android Manifest! I’m not sure exactly why, but they must be registered in an IntentFilter in your JAVA code"

http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/

Manifest

    <receiver android:name=".Broadcast" >
<intent-filter>
<action android:name="android.intent.action.TIME_SET" />

</intent-filter>
</receiver>

Main Activity Class

public class MainActivity extends Activity {

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

// INITIALIZE RECEIVER
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new Broadcast();
registerReceiver(mReceiver, filter);

}

}

My broadcast receiver

public class Broadcast extends BroadcastReceiver {

public static String TAG = "BROADCAST";

@Override
public void onReceive(Context context, Intent intent) {

if (intent.getAction().equals(Intent.ACTION_TIME_CHANGED))
{
Log.d(TAG, "BROADCAST Cambio di orario");
Toast.makeText(context, "BROADCAST Cambio di orario", Toast.LENGTH_LONG).show();
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
// DO WHATEVER YOU NEED TO DO HERE
Log.d(TAG, "BROADCAST Screen OFF");
Toast.makeText(context, "Screen OFF", Toast.LENGTH_LONG).show();
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
// AND DO WHATEVER YOU NEED TO DO HERE
Log.d(TAG, "BROADCAST Screen ON");
Toast.makeText(context, "BROADCAST Screen ON", Toast.LENGTH_LONG).show();
}
}

}



Related Topics



Leave a reply



Submit