Accepting Android volume rocker input across a range of states - android

I have an app that will generally be the sole app for which a device (Android 4.2 and up) is used. It needs to be able to accept input from the volume rockers in the following scenarios:
app is in foreground
app is in background
lock screen or keyguard has been engaged
screen has been switched off (ie idle mode).
(1) is easily solved by listening for KeyDown events in the Activity
(2) can be partially solved by listening for android.media.VOLUME_CHANGED_ACTION (yes I know it's not public API, but it works all devices I have managed to test it on and I can't find an alternate). But on my Nexus 5 (Android 6.0), on first press of the rocker it displays the volume dialog for a short duration and requires a second press to pass the rocker event to my app. I haven't managed to pin down for which version of Android this started occurring, but I'd like to work how how to ensure the first event is passed to my app for all Android versions.
(3) can be mitigated by using WindowManager FLAG_DISMISS_KEYGUARD and FLAG_SHOW_WHEN_LOCKED to avoid lock screen and keyguard
(4) can be partially mitigated by using WindowManager FLAG_KEEP_SCREEN_ON to ignore display timeouts when app is in foreground. But unfortunately it is a common event for the user to accidentally manually power the screen off, and even using a WAKE_LOCK doesn't allow the volume rocker events to be received via android.media.VOLUME_CHANGED_ACTION when the screen is idle.
So the questions are:
How do I ensure that the first press of the volume rocker is passed to my app, rather than being captured and consumed by the volume dialog?
How can I receive volume rocker events when the screen is idle?

Related

Mute (or disable) phone calls while app is running

Is it possible to mute the phone while my app is active? Or to even disable the phone call screen?
My use case is following:
I have a music player in my app and it's a fitness app, so the user does eventually not want to be disturbed. So I want to allow him to activate a "do not disturb" mode, which disables incoming call notifications, at least the sound.
What I need is following:
Bluetooth must work, because of the headphones, so plane mode would not even be a manual workaround
Can this somehow be achieved?

Check volume button usage when screen is off

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

Is it possible to get a device to wake up from sleep (screen dark) by detecting a touch to the screen?

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.

How to detect backlight is on?

My application requires resource and drains a battery when it is working. So, I want to know the way that user is not available on the phone.
Is there a way to use the built in power save mode on the blackberry to where if the screen dims to suspend the application works active and when the user wakes the device back up with a keypress or trackball movement to resume the application works active?
Thanks in advance.
Is there a way to use the built in
power save mode on the blackberry to
where if the screen dims to suspend
the application works active and when
the user wakes the device back up with
a keypress or trackball movement to
resume the application works active?
This happens automatically, with no code changes required. Unless something is holding a WakeLock, the CPU will turn off sometime after the screen goes dark. The CPU will turn back on when the user presses the power button.

How to prevent volume keys and camera key from waking up phone in Android?

I have an activity that I want to show up when the phone goes to sleep. However, the phone wakes up when I press the volume buttons or the camera button.
I tried using the dispatchKeyEvent(KeyEvent event) method, but it doesn't prevent the phone from waking up.
How else can I disable that functionality?
Thanks,
I heard that waking behaviour is defined on framework level - in policy.jar or somewhere else. So your issue will require modifying system itself. Check also http://forum.samdroid.net/f42/disable-every-button-wake-up-2124/

Categories

Resources