my app does something when the screen goes black, but I want it to only carry out that task if the screen was turned off "by itself", through a screen timeout - NOT when the user presses the power-button. Is there any way to distinguish between these two events?
ACTION_SCREEN_OFF obviously fires in both cases, and I haven't found any other intents that might match what I'm looking for.
At the lower level there's an event happening when the screen times out, take a look with "adb logcat" and you'll see it, dig from there.
Services can't directly handle button events. Perhaps you can have your Activity register a broadcast receiver to get notified when the screen is going off, and then have the Activity check the last key pressed to see if it was the power button--if it wasn't then you can send a broadcast to your service and have it run whatever you want.
That's a fun question :) Although not accurate, you can try sampling the time since the user last touch event and to the time your activity goes to pause - and see if it's fits the screen off timeout
Can you listen for a KEYCODE_POWER keyboard event? That might do what you want. (But the order in which that and ACTION_SCREEN_OFF arrive might not be guaranteed).
Related
I am trying to build an app with the ability for it to be shown over Lock Screen when the physical Power button is pressed say 2 times in quick succession or long pressed.
So far I have figured out that I need a-
1) SERVICE- I need a Service that should intercept the Power buttons pressing 2 times / long press- whether the device is locked or not
2) RECEIVER- User Broadcast Receiver to capture the broadcast intent from service and launch my main activity.
A lot of questions on SO are similar but none of them address how to do this because-
The Service cannot have methods to detect Key Events & as a result need to find some other way to figure out when Power key is being pressed. The suggested alternate is to use SCREEN ON and SCREEN OFF intents. But using them causes a problem if the service is running in background and the Screen is woken by some other app, eg an incoming call.
I have seen few apps which use Power button to start apps or activity.
1) Press It- https://play.google.com/store/apps/details?id=com.incrediapp.press.it.macro.creator.time.saver&hl=en
2) Power Button Flashlight- https://play.google.com/store/apps/details?id=com.brink.powerbuttonflashlight&hl=en
Any ideas on how to start an app/activity over the press of Power buttons?
And then show it over the lock screen.
Short answer: You can't! The system wasn't build that way.
How ever many times when someone says: "You can't" he actually mean you can't without hacking it...
So here is an idea for a hack for you:
As you mentioned, services can't listen for key events, but Activity can. So activity is your answer.
Start your activity when the screens goes off, and kill it when it comes back. Also make it transparent just in case you get out of sync and you don't want to be spotted.
Now you got an easier problem to solve, how to trigger the power button from inside your activity.
I'm writing a Kiosk app that, along with having some UI elements, also has a service that sits around in the background while the user explores other features on the device, and wish to re-launch the UI portion of the kiosk when the user has walked away. I figured that the most reliable way to do this is to listen for the screen to go dim and react to that event. However, I'm not seeing anything in the documentation about a system wide broadcast that I can listen to that the screen state has changed. Curious if I'm just overlooking it, or if it doesn't exist.
Take a look at this answer:
android.intent.action.SCREEN_OFF
FYI there is a full list of broadcast intents available in your sdk/platforms/android-xx/data/broadcast_actions.txt if you want to have a look. I found these two quickly, which led me to the answer I linked:
android.intent.action.SCREEN_OFF
android.intent.action.SCREEN_ON
I want to keep listening to long press of volume up button in background when triggered I would like to get some process done.
I am able to do this inside my application without any problem. I want to achieve the same when my application is not running - figured out service would be the best deal but I believe service can't listen to key events so what is the work around can I achieve the same in broadcast receiver? Can receiver run in background without the application running?
Can somebody help me out with this please?
Thanks!!
Android SDK doesn't intend for you to be able to do this while your app isn't running in the foreground. Maybe it is possible with the NDK or if you know how to touch the operating system with root access (but this would require the user to root their device).
I researched this quite a bit a while back and this was the best I could come up with, it relies on the fact that the screen turns off and on when the power button is pressed (I haven't seen any devices where this isn't the case). This event IS something you can receive when your app is not running.
Register a BroadcastReceiver or Service to receive intents with the following IntentFilter:
IntentFilter f = new IntentFilter();
f.addAction(Intent.ACTION_SCREEN_ON);
f.addAction(Intent.ACTION_SCREEN_OFF);
When the Intent is received use
System.currentTimeMillis()
to get the timestamp that this intent was received.
To make sure that the user really intend to trigger the event you have implemented, you need to chain multiple presses of the power button. Save the last time that the event was received with SharedPreferences.
Upon subsequent power button presses check that the current press did not occur too long after the previous one. If it did, restart the number of presses that have occurred (with SharedPreferences again).
If the current power button press received is within this maximum time frame, and the number of times that have been pressed reaches a certain amount (I use 4 as the default, 3 seems to cause unintentional triggers), then trigger your event.
Here is the code I have for the receiver:
https://github.com/eskimoapps/count_stuff/blob/master/Receiver.java
It's not very good and is from the first app I published a long time ago. If I ever get around to it I will rewrite it and put the whole thing on GitHub.
If you want to see it in action here is the store listing:
https://play.google.com/store/apps/details?id=count.stuff&hl=en
I would have listed someone else's app to avoid self-advertising, but I don't know any other apps that do this.
I have a service that detects when the display of my Android phone is turned on or off. When turned off, the service calls an activity that uses dispatchKeyEvent to detect when the volume up button has been pressed. Unfortunately, apparently the activity can't do this when the screen is off. (See this post.)
I've noticed, though, that something at some level is detecting that event, since the following LogCat message appears when I press the volume-up button when the screen is off: "CatService: Return current sInstance". The message seems to be device specific, since on a different device something different appears in the log, but I'm really only concerned about the first device.
I've done some research into CatService, but haven't found much and can't figure out how I might be able to use it, or whatever is generating the log message, to detect the volume up button press. I'd appreciate any light that anyone can shed on this.
The only way to keep detecting things like this when the screen is off is to acquire a WakeLock that will allow the screen to turn off, and still let your app function. However, this drains the battery life quite a bit, and should only be used when absolutely necessary.
In this case, you will need a PARTIAL_WAKE_LOCK.
I want to get an android device to wake up from sleep or however the state in which the phone gets after a certain amount of inactivity when the screen goes dark, by detecting a touch to the screen instead of clicking on any button.
In the documentation the only thing I have found is the FLAG_TOUCHABLE_WHEN_WAKING flag in WindowManager.LayoutParams and it says:
Window flag: When set, if the device is asleep when the touch screen
is pressed, you will receive this
first touch event. Usually the first
touch event is consumed by the system
since the user can not see what they
are pressing on.
I thought that meant that if the device's screen is turned off and that flag is set for an Activity then it will wake up to the touch (which is what I want it to do). Am I misunderstanding the purpose of this flag? Are there additional implementation details I'm ignoring? Is there some other way?
Am I misunderstanding the purpose of this flag?
AFAIK, yes. There is a slice of time between when the screen turns off and when the device falls asleep. During this time, if the user touches the screen someplace where the window has this flag, the screen turns on again and the inactivity timer is reset.
I can find no other use of this flag in the Android source code.
Is there some other way?
No. If the device is asleep, touch screen events are not registered.