How can I tell if the screen is on in android? - android

In Android 2.2 (Level 7) the function PowerManager.IsScreenOn() returns a boolean that is true if the screen is turned on and false if the screen is turned off. I am developing code for Android 1.5 (Level 3). How do I accomplish the same task in older versions of Android?
I do not want to turn the screen on or off in my code. I just want to know what it is.

There's a better way than using BroadcastReceivers:
// If you use API20 or more:
DisplayManager dm = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
for (Display display : dm.getDisplays()) {
if (display.getState() != Display.STATE_OFF) {
return true;
}
}
return false;
// If you use less than API20:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
if (powerManager.isScreenOn()){ return true; }
Note that Display.getState() can also return STATE_DOZE and STATE_DOZE_SUSPEND which means that the screen is on in an special way. More info on Display.getState() and his return values here: http://developer.android.com/reference/android/view/Display.html#getState()
Also note that although official documentation recommends using isInteractive() instead of isScreenOn(), if you really want to know the status of the screen, Display.getState() is a better option because of the 'special' conditions that sets the screen on while the device is not interactive.

This is how you should do it:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
boolean result= VERSION.SDK_INT>=VERSION_CODES.KITKAT_WATCH&&powerManager.isInteractive()||VERSION.SDK_INT<VERSION_CODES.KITKAT_WATCH&&powerManager.isScreenOn();
return result;

I'm using the following function:
public boolean isInteractive() {
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH
? powerManager.isInteractive()
: powerManager.isScreenOn();
}

You can accomplish this by setting up broadcast receivers for ACTION_SCREEN_ON and ACTION_SCREEN_OFF.

I'm posting this because on a HUAWAI Prism II Android 4.1.1 (API 16) device the game I'm working on had the following annoying behavior:
I'm displaying my main menu which has some animation in a SurfaceView and plays a sound once in a while.
The device goes idle, dims, and then goes dark.
It calls onDestroy on my Activity, and then while the screen is off creates my Activity again, calling onCreate!
So the problem is my animations and sounds are playing while the screen is off. What I really want to happen is for my animation loop to not run at all if the screen is off. Broadcast receivers don't work because I can't store the state from the last time the screen went off. I thought about some hacks involving static booleans but it just seemed like a kluge that may not work and have horrible edge cases. The screen is already off when my Activity is created again, so I won't get an event through the broadcast receiver that my screen is off.
I solved this using both a broadcast receiver and the code listed above.
In my onCreate, I create the broadcast receiver. This will control my animation loop when the screen turns on and off.
if (mScreenReceiver == null) {
mScreenIntentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
mScreenIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
mScreenReceiver = new ScreenReceiver();
registerReceiver(mScreenReceiver, mScreenIntentFilter);
}
public class ScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
controlAnimLoop(false, false, true);
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
controlAnimLoop(false, false, false);
}
}
}
In my controlAnimLoop, I check isScreenOn, which is this code:
private boolean isScreenOn() {
if (android.os.Build.VERSION.SDK_INT >= 20) {
// I'm counting
// STATE_DOZE, STATE_OFF, STATE_DOZE_SUSPENDED
// all as "OFF"
DisplayManager dm = (DisplayManager) getSystemService(Context.DISPLAY_SERVICE);
for (Display display : dm.getDisplays ()) {
if (display.getState () == Display.STATE_ON ||
display.getState () == Display.STATE_UNKNOWN) {
return true;
}
}
return false;
}
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
return powerManager.isScreenOn();
}

MainActivity.Java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_HEADSET_PLUG);
filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(new MyReceiver(), filter);
}
}
MyReciever.Java
public class MyReceiver extends BroadcastReceiver {
MainActivity mActivity;
#Override
public void onReceive(Context arg0, Intent arg1) {
mActivity = (MainActivity) arg0;
TextView tv = (TextView)mActivity.findViewById(R.id.textView1);
if(arg1.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
tv.setText("Headset Plugin ");
} else if(arg1.getAction().equals(Intent.ACTION_POWER_CONNECTED)) {
tv.setText("Power Connected ");
} else if(arg1.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)) {
tv.setText("Power Disconnected ");
} else if(arg1.getAction().equals(Intent.ACTION_SCREEN_ON)) {
tv.setText("Screen ON ");
} else if(arg1.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
tv.setText("Screen OFF ");
}
}
}

Related

Screen Lock from receiver

I am trying to Lock and unlock the screen,
The thing I am doing it as the following
A Broadcast receiver which checking whether the screen is ON of OFF,If the Screen is ON it will Lock the screen and if OFF it will unlock the screen.
The code I am using in the Broadcast receiver is
public void onReceive(Context context, Intent intent) {
System.out.println("Entered Broadcaste Reciever........");
context1 = context;
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
// DO WHATEVER YOU NEED TO DO HERE
mShaker = new ShakeListener(context);
mShaker.setOnShakeListener(new ShakeListener.OnShakeListener () {
public void onShake()
{
PowerManager TempPowerManager = (PowerManager) context1.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock TempWakeLock = TempPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP |PowerManager.ON_AFTER_RELEASE, "TempWakeLock");
TempWakeLock.acquire();
final Vibrator vibe = (Vibrator)context1.getSystemService(Context.VIBRATOR_SERVICE);
vibe.vibrate(100);
System.out.println("LISTENING SHAKE");
}
});
}
else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
// AND DO WHATEVER YOU NEED TO DO HERE
mShaker = new ShakeListener(context);
mShaker.setOnShakeListener(new ShakeListener.OnShakeListener () {
public void onShake()
{
mDPM = (DevicePolicyManager)context1.getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName mAdminName = new ComponentName(context1,LockActivity.class);
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
context1.registerReceiver(mReceiver, filter);
System.out.println("The Device device admin enabled");
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,"onEnabled");
mDPM.lockNow();
mDPM.setMaximumTimeToLock(mAdminName,0);
intent.putExtra("force-locked", DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
// startActivityForResult(intent, 1);
}
});
}
The problem is it is starting properly and upto 5 shakes its working properly and after that it is going infinite state and device get stucked..Somebody help me to find the solution
Now, something to keep in mind, is that the order of events before the system screen turns off is:
ExampleActivity.onPause() –> ScreenReceiver.onReceive()
Which is a little unintuitive as you’d think the receiver would get hit first – and so when you play around with setting booleans, etc, be aware of this little fact, and likewise when the screen turns on the order of events is:
ExampleActivity.onResume() –> ScreenReceiver.onReceive()
#Override
protected void onPause() {
// when the screen is about to turn off
if (ScreenReceiver.wasScreenOn) {
// this is the case when onPause() is called by the system due to a screen state change
System.out.println("SCREEN TURNED OFF");
} else {
// this is when onPause() is called when the screen state has not changed
}
super.onPause();
}
#Override
protected void onResume() {
// only when screen turns on
if (!ScreenReceiver.wasScreenOn) {
// this is when onResume() is called due to a screen state change
System.out.println("SCREEN TURNED ON");
} else {
// this is when onResume() is called when the screen state has not changed
}
super.onResume();
}
Reference from here

Android perform function while lock screen

I am writing an app that when battery reach some level the wifi will automatically shut done, my app works fine while screen is on, but it not do anything when the screnn is lock.
My app is like, start activity, user click the button to start the Service, the service will register the broadcastreceiveer to get the current level of battery, and braodcastreceiver will see if battery level reach the limit and decide to shut done wifi or not
I have try use isScreenOn() to find whether screen is on or off, but this also not work
here is my code
public class BatteryMonitor extends Service {
/*declear variables*/
private BroadcastReceiver batteryReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent){
/* get battery level*/
//Check is screen is on or not
boolean isScreenOn = powermanager.isScreenOn();
//set as 90 just for test function//
if(batteryLevel<=90){
if(isScreenOn==true){
if(isCharging == true && wifimanager.isWifiEnabled()){
//not do anything
}else if(isCharging == false && wifimanager.isWifiEnabled()){
wifimanager.setWifiEnabled(false);
}
}else{
if(isCharging == true && wifimanager.isWifiEnabled()){
//not do anything
}else if(isCharging == false && wifimanager.isWifiEnabled()){
wifimanager.setWifiEnabled(false);
}
}
}
}
};
public void onStart(Intent intent, int startId) {
wifimanager = (WifiManager)this.getSystemService(Context.WIFI_SERVICE);
powermanager = (PowerManager) getSystemService(Context.POWER_SERVICE);
registerReceiver(batteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
};
#Override
public IBinder onBind(Intent i) {
// TODO Auto-generated method stub
return null;
}
}
Create a Separate class for Receiver, register it into Manifest file for Battery change action. Then it will work even when screen is off.
Broadcast Receiver
read this link.
You need to sendBroadcast when you want to send a message to Receiver, make sure that you added proper Action String , in manifest for Receiver ,

Android: Wake & unlock phone

I am trying to figure out how to wake and unlock the phone with a service. I have been referring to this post but, I can't figure out why it isn't working. This is the code that I have so far:
public class WakephoneActivity extends Activity {
BroadcastReceiver mReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Log.v(TAG, "Screen OFF onReceive()");
screenOFFHandler.sendEmptyMessageDelayed(0, 2000);
}
};
}
private Handler screenOFFHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// do something
// wake up phone
// Log.i(TAG, "ake up the phone and disable keyguard");
PowerManager powerManager = (PowerManager) WakephoneActivity.this
.getSystemService(Context.POWER_SERVICE);
long l = SystemClock.uptimeMillis();
powerManager.userActivity(l, false);// false will bring the screen
// back as bright as it was, true - will dim it
}
};
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
registerReceiver(mReceiver, filter);
// Log.i(TAG, "broadcast receiver registered!");
}
}
I have added the code in the manifest as well. Any ideas?
Use this code below in your service.
PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock((PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "YourServie");
mWakeLock.acquire();
[...]
mWakeLock.release();
If you want to unlock the screen as well, register a receiver in your service that monitors if the screen is turned on/off and if it is turned off and you want to unlock the phone, start an activity with this code in onCreate:
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
this.finish();
return;
I know, this is a rather dirty, but as far as I know, there is no other way of unlocking the lockscreen (and this will only work if there are no passwords etc set, so it must be the normal "slide to unlock" screen).
And don't forget to add android.permission.WAKE_LOCK ;-)
/edit: I just saw you are already using an Activity. If you have one and don't need the service at all, just put this code into the activity.
For the service to be allways active you need to have this permission on manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Another thing you need to do is to adquire a WakeLock. Without it the service will end passed some time. You can do it like this:
getApplicationContext();
PowerManager pm = (PowerManager)getApplicationContext().getSystemService(Context.POWER_SERVICE);
WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
wl.acquire();
You might need to change PowerManager.PARTIAL_WAKE_LOCK to the one that you need. You can see info about that here.
There is WakefulBroadcastReceiver which does this for you. Example use:
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.util.Log;
public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// This is the Intent to deliver to our service.
Intent service = new Intent(context, SimpleWakefulService.class);
// Start the service, keeping the device awake while it is launching.
Log.i("SimpleWakefulReceiver", "Starting service # " + SystemClock.elapsedRealtime());
startWakefulService(context, service);
}
}
After completing the action in the service, call SimpleWakefulReceiver.completeWakefulIntent(intent) to release the wake lock.
(as #Force already gave you the details about the wakeLock, they need not be repeated here ;-)
Mind that the class is deprecated from api level 26.1.0, reference here

Android: service for gps / sensor logging

I m looking for the best practice to implement a service for logging gps- or other sensor-values periodically (every 10-60 sec). The service should deal with the standby mode, when the phone goes asleep.
Any help (pseudo-code or tutorials) is very much appreciated!
It looks like it is impossible to let the orientation sensors work constantly for hours even though the device may fall asleep (refer to http://code.google.com/p/android/issues/detail?id=3708#makechanges
As soon as the display goes off, the sensors will do alike... :(
I now implemented a wakelock (needs permission)
<uses-permission android:name="android.permission.WAKE_LOCK" />
in conjunction with a timer and a broadcastreciever that will turn the display back on again. This is of course crazy for battery life but I found no other way so far.
This is my onCreate method in the service:
#Override
public void onCreate() {
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
CONTEXT = this;
PowerManager pm = (PowerManager) CONTEXT.getSystemService(Context.POWER_SERVICE);
this.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "my tag");
mWakeLock.acquire();
Log.d(TAG, "Wakelock acquired");
// register receiver that handles screen on and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
this the onStart method of the service:
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onStart");
boolean screenOn = intent.getBooleanExtra("screen_state", false);
if (!screenOn) {
Log.d(TAG, "Screen is on");
} else {
Log.d(TAG, "Screen is off");
Timer timer = new Timer("DigitalClock");
timer.schedule(new TimerTask() {
#Override
public void run() {
Log.d(TAG,"Waiting 1 sec for switching the screen back on again...");
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
"my tag");
mWakeLock.acquire();
}
}, 1000);
mWakeLock.acquire();
}
}
and this is the BroadcastReceiver class:
public class ScreenReceiver extends BroadcastReceiver {
private boolean screenOff;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
screenOff = true;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
screenOff = false;
}
Intent i = new Intent(context, MyService.class);
i.putExtra("screen_state", screenOff);
context.startService(i);
}
}
This workaround will also do with a device UN-plugged from the debugger via USB (I first had an issue with this).
Please let me know if you have a better solution, or if there is fix in 2.3. Thanx!
Here's a link to a tutorial on how to use Android Services. LINK
Here's a link to a tutorial on how to read data from sensors. LINK

Android detect phone lock event

I want to be able to detect the phone lock event. When my app is running, if I press the red button (call end button/power button), the phone gets locked and the screen goes blank. I want to be able to detect this event, is it possible?
Alternatively you could do this:
#Override
protected void onPause()
{
super.onPause();
// If the screen is off then the device has been locked
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
boolean isScreenOn;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
isScreenOn = powerManager.isInteractive();
} else {
isScreenOn = powerManager.isScreenOn();
}
if (!isScreenOn) {
// The screen has been locked
// do stuff...
}
}
Have a Broadcast Receiver
android.intent.action.SCREEN_ON
and
android.intent.action.SCREEN_OFF
Related: Read CommonsWare's Answer Here.
Register a broadcast with IntentFilter filter.addAction(Intent.ACTION_USER_PRESENT)
works pretty well even screen is turned on/off
Koltin format of Robert's solution.
override fun onPause() {
super.onPause()
// If the screen is off then the device has been locked
val powerManager = getSystemService(POWER_SERVICE) as PowerManager
val isScreenOn: Boolean = powerManager.isInteractive
if (!isScreenOn) {
// The screen has been locked
// do stuff...
}
}
I am assuming Kitkat version is quite old already.

Categories

Resources