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
@Android Display /Res/Viewable in Webview
Cordova - Error: Failed to Fetch Platform Android
Embed Activity Feed of a Public Facebook Page Without Forcing User to Login/Allow
Pass Arraylist Data into Soap Web Service in Android
Configuration on Demand Is Not Supported by the Current Version of the Android Gradle Plugin
How to Show Popupwindow at Special Location
Manually Adding Aar with Dependency Pom/Iml File
How to Retrieve More Than 1000 Rows from Parse.Com
Firebase Token Authentication Error
Sdcard Content Exist But Cant See Them
Android Home Screen Widget (Icon, Label - Style)
Ios/Android Cross Platform Development
Finding the Dominant Color of an Image in an Android @Drawable
How to Read Properties Defined in Local.Properties in Build.Gradle