How to know when exactly does the device get locked in Android? - android

I'm trying to implement a system level lock screen from a third-party/device-owner MDM app in Android.
I tried looking up on the internet for ways for third-party apps to implement system level lock-screen but from the information that I was able to gather there doesn't seem to be a standard way to implement the same.
The approach we are currently using for the same is to use the (system) overlay permission and showing up the overlay when the boot completes (BOOT_COMPLETED system broadcast intent) and when the device gets locked.
To know when the device gets locked, there were two approaches that we mainly found for the same.
Use a background service, add an invisible overlay, listen to key events until we find a key event related to the power button
Use a background service, register a receiver for SCREEN_OFF event there, and wait for the same.
In both the approaches, we need to use a background service which could potentially drain out battery... By any chance, is there any event/broadcast intent that we could listen to, to make this more efficient overall for the given use case?

Related

How to detect when Android device was last used?

My app needs to know when the user last interacted with the phone, or when the device screen went off. Answers to similar questions suggested:
registering a SCREEN_OFF/DEVICE_IDLE_MODE_CHANGED broadcast receiver in manifest.
Problem: won't work since it's a protected broadcast
dynamically registering and unregistering SCREEN_OFF/DEVICE_IDLE_MODE_CHANGED when an app component is live
Problem: I can't or don't want to keep the app or service running since I need to know SCREEN_OFF 24x7.
Using ActivityManager or UsageStats
Problem: Gives details only for particular packages so to be able to figure out when the app was last used, will have to iterate over a list and make many function calls. And even after that, I am not sure if this covers the case when no app is used but only a quick device unlock and relock action.
Is there a way to reliably know in the background when the user last used their device without keeping a service running?

scroll android programmatically in all applications

I created a background service on android and I have two buttons which appear on the top of the screen all the time. I want to use these two buttons like scroll down and scroll up. But these two buttons should work on any kind of applications like Instagram, Facebook, Twitter and so. So, it means it should work in all applications that use scrolling.
I search a week on internet but I could not find any solutions.
This is not possible, sorry. Something like this would require your Service to have access to the Views of the applications and this would be a huge security breach, because you could read values from them and so on.
You could achieve this with a custom button code broadcast (so basically your buttons would act as physical buttons on the device) but this would most probably require you to have system-level permissions and some level of cooperation with the OEMs.
Android Activity class has a method called dispatchKeyEvent(), which could let you simulate the key input (with some limitations) but this is not present in the Service class.
Sadly this is not something you can do in Android. Typically you should not be able to touch views with a background service, the point of a background service is that you do some work in it (for example upload files to your web server or get some data). You CAN send a signal from a service once you're finished doing work to tell an app that something needs to happen, however the app needs to be specifically coded to respond to this broadcasted event.
If you wanted to do this with an app that you have developed, that can be achieved by using the onReceive method of say a BroadcastReceiver, however you cannot specifically define the behaviour of other apps as this would represent a security breach in Android.

Android: How to catch 2 times short volume-up button push or long hold?

I would like to run predefined service in my app if I do two short volume up pushes (or one long hold).
It should works also if phone has locked screen or another app is in foreground.
Thanks for any advice or example how can i do it.
The official Broadcast Receiver for volume changes only gets triggered when the state changes from volume to/from silent to/from vibrate. So perhaps, it could detect a long volume up hold under some circumstances, but I don't know. That Broadcast Receiver is not granular at all.
I've seen non-rooted apps on Google Play that detect the volume keys at a more granular level, but I believe those apps are making use of undocumented functionality (of which I do not know about).
If you're making your own rom as your username might imply, detecting those keys would be much easier to do. Is that the case? Are you making your own rom? Will the app you're making have root access?

What's the right way to interact with Chromecast from an Android Notification?

I'm trying to figure out the right way to add Chromecast buttons (pause, play, etc) to an Android Notification. I've set up a custom notification that sends PendingIntents to a ChromecastService. That service is trying to interact with a class I built called ChromecastAdapter. The ChromecastAdapter implements MediaRouteAdapter and contains all the listeners and state that go along with casting. However, all this state is gone as soon as I exit the application. So, my ChromecastService doesn't end up having access to the Chromecast once my app is gone.
It seems to me that the only way to get this to work is refactor all the Chromecast state into a Service that implements MediaRouteAdapter. I really don't want to do this since I'm pretty happy with the way things are now.
Since these interactive Notifications are required by Google, I feel like there has to be a standard way of interacting with a cast from a Notification. Am I on the right track here? Do I have to place all my Chromecast interactions behind a Service?
What the behavior should be depends on the type of app and the requirements of the app. If your app is "gone" (in the sense that the Application instance is gone), then the question that you should ask yourself is whether you would want to keep a notification mechanism to stay around; there are apps that when they are killed, the receiver also gets closed and user is sent back to the home screen on the chromecast device, in which case there is no reason to keep a notification around.
On the other hand, there are apps that based on their requirements, you would want to let the cast device continue what it was doing (for example play the video) even if the mobile app is gone. In those cases, you may want to have a notification mechanism in place for "bringing up" the app. To achieve that, you need to maintain certain amount of information/state/objects in a service, enough to be able to establish a connection again and "join" the running app. In addition, your "service" needs to be aware of the status of the app on your receiver so if that app is killed (say, someone else starts casting a different app to the device), it can be notified and exit.

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

Categories

Resources