The primary purpose of my app is to change a smart phone into a sort of smart pager (there is an associated web app, but that's not the purpose of the Android app). I use the Notification system built in to Android to handle alerting the user that they have received a page.
My problem is that the clients want:
The notification ringer to ring forever until acknowledged (easily accomplished with FLAG_INSISTENT)
An easy way to silence the ringer with 1 push of a button. It is really not always feasible due to the nature of their work to press the power button, slide to unlock, and drag down the notification bar. I need to replicate the behavior of a pager.
I need to find a way to satisfy the 2nd requirement. It looks like I can hook into keypresses if I've got an activity running, but of course, when a notification is received, the screen will probably be off. I am looking into this currently, but I was wondering if anyone had some guidance in the meantime.
Does anyone have ideas on how I could accomplish this goal? Are there alternative ways to listen for key presses, or some creative combination of flags that could get me there?
Techniques that would normally be frowned on for Market apps are completely on the table, since the phones are owned by my employer and will only be used by other employees. I just want to avoid using private or deprecated APIs to make switching phone models easier for the developer who eventually inherits this project.
Thank you to everyone for reading!
Does anyone have ideas on how I could accomplish this goal?
You'd have to hold a WakeLock, specifically a FULL_WAKE_LOCK, in order to respond to button presses. This means that battery life will be sucktastic, unless you put some time limit on that (e.g., hold the WakeLock for a minute or two, but otherwise assume the user's not near the device, so don't keep it awake).
You would also need to try to interrupt the keyguard with KeyguardManager. I have not done this so I do not know all of the details. Your "watch for the magic button" logic would have to be in the activity that appears on top of the keyguard.
Also, bear in mind that not all Android devices have physical buttons -- in fact, I would not be the least bit surprised if the whole physical button metaphor goes "poof" with Ice Cream Sandwich later this year. Hence, the button in question really should be an on-screen Button for future-proofing.
Related
I'm trying to display a view that the user must dismiss each time they unlock their phone (it's intended to be annoying). It should be able to take a small amount of keyboard input, save it, then return to the previously open activity. I tried having a BroadcastReceiver listen for ACTION_USER_PRESENT and launch my own activity, but then I found out we can no longer listen for implicit intents, or have background services launch activities.
I'm not an Android developer (just trying to build something for my phone), but I did some looking, and I see a few options:
Display a full-screen intent. I think something like scheduling a job to raise a notification whenever the phone is locked, so that the notification appears first thing when they unlock the phone.
Use SYSTEM_ALERT_WINDOW and draw my view as an overlay whenever the phone is unlocked. My only concern with this is how apps like Twilight (which I believe draws an overlay to redden the screen) might interact with it. In those cases, I'd like my overlay to appear at the very bottom.
Are either of those options viable or recommended? Any other suggestions or approaches for how I could accomplish this would be greatly appreciated too. I'm just looking for some guidance on what direction I should pursue.
I want to try to make an Android alarm app that is impossible to stop. In other words, it keeps going for a predetermined amount of time, even if the user presses the power button, tries to reduce the volume, or anything else.
It does not seem feasible to me, but since I have very little Android experience, I'd like to know if something like that is theoretically able to be done. Thanks.
This question has been addressed on SO here: Override Power button just like Home button
.
There are several answers in the link that will give you options and get you 90% of the way there, but no answer will cover all devices/scenarios. The accepted answer in the link puts it best:
The Android system, as far as is documented, defines (a physical button press) 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 (cannot be) injected in the
right place to block the reception of this message.
i am currently collecting information, if it is possible to make some kind of quickdraw-application for emergency purposes; i want to get the device to start a customized camera-intent once some certain key-combo is pressed.
I have check quite some information on the topic already, but it is still not clear to me how doable this whole idea is.
So far i figured, that it is not meant to be by android-design. My first idea was to build some kind of InputService and make it teach the hard power-button to listen for a triple-click. But the Services arent allowed to catch KeyEvents. So, the volume-button is out of the equasion aswell.
Then i came across the idea reacting on the SCREEN ON/OFF event, but 80% of the ppl say that it is not going to work, while 20% state, that they got it. But im not really sure if they really did it.
Last but not least the question, if it is possible to launch this customized-camera-intent/application out of the locked mode.
resumé: i need to check if its possible in general to launch this camera-app (that does some quick fotos for emergency purposes) while phone is in the pocket in lock-mode. Anybody got some opinion for me? thx
The solution is to setup a BroadcastReceiver that is listening for the SCREEN_ON-Event. I did this one inside a backgroundservice that was waiting for at least two SCREEN_ON-Events within a short period of time. (less than two events obviously can't work)...
The Service then dismissed the Keyguard and was able to even pass past password/gesture and run the App. Funny fact: closing the app does pop back to desktop still beeing logged in.
I did this at Android 4.2.. Sources told me that dismissing the keyguard is not working with current Android-versions no more.
I am writing a metronome app, I have the sound running from a service which I would like to keep running when the user is outside the app (browsing etc) and hasn't made a conscious effort to press the stop button.
It seems I should be using startForeground() as it's not the kind of thing you want in the background without paying attention to, and I really don't want the service to be killed at any time. Ideally I wouldn't be showing the notification while the app is in focus though. I notice that the Google Play Music app works this way, it only shows the notification when outside the app. Is anyone able to tell me how they have done this, I would find it hard to believe they wouldn't be using startForeground() after reading all the documentation stating you should be using it for this sort of app?
On the other hand, is this really desired behavior? It seems good to me, but I noticed that pretty much every other app I use with a long running service (HTC's music app, Navigation, few others) shows the notification icon at all times, whether in the app or not. I am interested in what is considered correct behavior. Any help much appreciated, thanks.
Is anyone able to tell me how they have done this
They probably call stopForeground() when one of their activities returns to the foreground, and startForeground() when they think the user has left (e.g., onUserLeaveHint()).
I am interested in what is considered correct behavior.
I do not think there is a definitive "correct behavior" in this area. It is easier to do what the other apps do and leave the Notification around, until the user indicates that they no longer want the background work to run.
Note that while you may want "to keep running when the user is outside the app", the user might not. Certain types of apps (e.g., music players) can safely assume that the user wants the audio to keep going; a metronome, IMHO, does not rise to that level. Please allow the user to configure this behavior, such as through a SharedPreference.
For this question I'm going to quote another user who got no response to their question:
I've written an Andoid app that uses the hardware Volume buttons for another purpose.
It works fine if the app is running and visible, but when I turn the
screen off or let it time out, the button clicks don't get into my
handlers.
Does anyone know if there is a way to detect these button clicks when
the screen is off?
Source: AV695's question
I'm working on an app myself that makes use of the volume buttons, but as this user also noted, the normal behavior of checking buttons with onKeyPress stops working once the screen is off. This is because the Activity gets paused on screen off.
Is there a way to keep the activity running while the screen is off, or check for the usage of the volume buttons when the screen is off? I tried using a Service for this before but it's impossible to check for the volume keys like that as noted by Commonsware.
I doubt that this is supported (without resorting to a battery-draining wakelock) at either the platform, kernel, or underlying radio firmware levels without modifications to the last to bring volume presses during sleep to the attention of the kernel.
Within the realm of reasonable system-ROM modifications, a more reasonable one might be to modify an existing open source ROM for the device to insert some custom platform level code into the handling of the power button usually used to wake up the device preparatory to unlocking it - that at least we know does get the attention of the kernel. That code could then inform the user by sound or vibration if there are unacknowledged notifications.
You could optionally wait briefly, check device orientation, or look for another key press to avoid doing this in an annoying way when the user is holding the device outside their pocket and trying to unlock it.
Or you could not use the volume key and just set a timer to wake up every 15 minutes and vibrate if there are unacknowledged notifications, avoiding the need to fumble in ones pockets.
You mention it's a custom request: if implies it's one off or low-volume, another option to consider would be that a few vendors have "bluetooth watches" out with an SDK that lets you push notifications from an android device.
If you can capture the notification when it's generated, you could push it to the user's wrist, and then let the phone go back to sleep.
You cannot intercept the key while your application is in background, but instead of listening to the KeyPress itself. You can register a ContentObserver, as described in this question.
As Chris Stratton mentioned, the only way to keep your App alive is by using battery-draining wake locks.
However, since I found myself in the same situation, I came up with another solution. Unfortunately, you'll need a rooted device as well as the Xposed framework.
With Xposed, which replaces the zygot process so you can hook yourself into any constructor and method of the system, you will be able to catch the raw KeyEvents before the system handles them.
This is done in PhoneWindowManager.interceptKeyBeforeQueueing(). By using a XC_MethodHook, you can use beforeHookedMethod() on the afore mentioned method to catch every hardware button event, even if the device is in deep sleep.
After catching events you are interested in, you can create a temporary wake lock to do your things but don't forget to release the wake lock after you finished your work.
A good example of how to accomplish this is the Xposed Torch Module.
If you, however, rely on a non rooted system, the bad news is that it's simply not possible without draining the battery...
I was also trying to implement volume button press detection in my app and I left that part to be developed later once the core part is done. I was able to detect volume key press while screen is on even when phone is locked, from a background service.
Background Video Recorder 2 (BVR2) (and possible BVR1 also, I did not try) is one of the apps that can detect volume key press even when screen is off. While trying to implement volume key detection while screen is off in my app, I installed BVR2, hoping to find how it works. To my surprise it gave my app the ablity to detect volume keys even when screen is off. My app had a ContentObserver to monitor volume changes, but was not working when screen is off. When BVR2 is active my app also could detect volume key press when screen is off. Still digging.
But BVR2 has its own trigger action, that is to record video, an action you may not want to occur just for the sake of you application detecting volume key presses.
Another app is QuickClick. This app can give your app what it lacks, the power to detect volume key presses even when screen is off, without extra unwanted actions. Just install QuickClick and do not configure any action. Create a ContentObserver to monitor for stream volume changes and you are ready. You app will now be able to detect volume key presses even when screen is off.
Please note that my app runs as a background service.
Both of the apps mentioned above are meant for other uses, but uses volume key detection to perform action. I am in no way connected to any of the apps mentioned.
If these apps, and possibly dozens others, can detect volume key press, it can be done. I request experts to find out how to do it, so that we can implement in our app without relying on another app.
If you find this answer useful, please up-vote.
I am not sure if it is as simple as this but check this android blog:
Allowing applications to play nice(r) with each other: Handling remote control buttons
It explains the usage of a broadcast receiver that receives the up/down volume controls and other music controls.
In summary you should use registerMediaButtonEventReceiver