14

Is it possible in Android API level 15 to receive a notification whenever the user does anything that keeps the device awake - in effect, whenever PowerManager.userActivity() is called?

(Bit of background: I'm working on a large Android app for a non-mobile device with a fixed power supply. When the user interacts with the screen, keyboard, etc. I need to send a "stay awake" signal to another, connected device.)

Mark Whitaker
  • 8,049
  • 8
  • 44
  • 66
  • Is a rooted option acceptable? – Randy Dec 12 '13 at 19:29
  • 1
    I ask because if the device is rooted then yes, you can. If not, there is no good way. See my similar question: http://stackoverflow.com/questions/18882331/android-inactivity-activity-regardless-of-top-app I ended up having to use an accessibility service which the user has to manually enable and it doesn't detect ALL user interaction. So it's not an optimal situation. See this if you are rooted: https://source.android.com/devices/tech/input/getevent.html – Randy Dec 12 '13 at 20:26

2 Answers2

6

Well if its your own Activity then you can always use onUserInteraction() and onUserLeaveHint() methods.

An alternative way is to listen for all touch events from a Service using techniques mentioned here: Creating a system overlay window (always on top)

Community
  • 1
  • 1
M-WaJeEh
  • 16,562
  • 9
  • 59
  • 93
  • That's almost perfect, except as noted in [this answer](http://stackoverflow.com/a/14829365/440921) it doesn't work when the user interacts with a dialog. The app I'm currently working on makes extensive use of dialog fragments so this doesn't work for me, but as a general solution it's pretty good. I need something a little more low level. :) – Mark Whitaker Dec 17 '13 at 07:57
  • I think all you need is a base fragment from which you extend all your Fragments. In you base fragment just write `onUserInteraction()` which in turn calls `getActivity().onUserInteraction()`. Now from each of your extended Fragment just insert `onUserInteraction()` calls whenever you think user has interacted. This is similar to having `Log` calls in your code. – M-WaJeEh Dec 17 '13 at 09:04
  • There's no `onUserInteraction()` in `Fragment`. :( – Mark Whitaker Dec 17 '13 at 09:09
  • No I mean write your own `onUserInteraction()` in your `Fragment` (name it whatever you want), from where just call your `Activity's` `onUserInteraction()` where you have written your logic to keep other device awake. – M-WaJeEh Dec 17 '13 at 09:10
  • Ah, OK. Unfortunately that's not really "receiving a notification" as the question asked for. Unfortunately this application is far too complex for that to be a satisfactory solution. – Mark Whitaker Dec 17 '13 at 09:18
  • If you look at the source code of `Activity` then its doing the same thing. It calling `onUserInteraction()` from appropriate places. Its calling it from `dispatchKeyEvent()`, `dispatchKeyShortcutEvent()`, `dispatchTouchEvent()` when `ACTION_DOWN`, `dispatchTrackballEvent()` and so on... It has nothing to do with application being big or complex IMHO. – M-WaJeEh Dec 17 '13 at 09:25
  • 1
    I belive this is a good solution. @Mark Whitaker please explain why this is not satisfactory for you? I don't think that complexity of the app could be the issue here. The solution provided by M-WaJeEh is fully scallable. But maybe we all got it wrong..? We need more explanation then. – Kristopher Dec 18 '13 at 11:46
  • Firstly, trust me, the application is massive. Whatever you're thinking of, it's way bigger than that. It's not a mobile app: it's embedded software running on a device the size of your sofa. LOTS of fragments, LOTS of dialog fragments etc., not all with a shared base class. Secondly, adding touch handling to a dialog fragment doesn't handle a touch on a popup window - we use those too. As with most problems, I can certainly keep throwing code at it until it's fixed or I can look for a more elegant, future-proof solution. Still hoping the latter may exist: otherwise I'll accept this. :) – Mark Whitaker Dec 18 '13 at 14:23
  • @MarkWhitaker Whole point is that it doesn't matter on size of Application. If you have lots of `DialogFragment` why they all can't be extended from same base? Also `Activity` has been handled, `DialogFragment` is done. Write one for `PopupWindow` as well. If still you are not happy then there is another way. Just run a service that quietly listen for touch events using hacks mentioned all over stackoverflow. E.g this should work: http://stackoverflow.com/q/6714020/1112882 – M-WaJeEh Dec 18 '13 at 14:35
1

Wouldn't it be enought to trigger your signal on android.intent.action.ACTION_SCREEN_ON (when the screen is ON) or android.intent.action.USER_PRESENT broadcast? Read more here: http://developer.android.com/reference/android/content/Intent.html#ACTION_USER_PRESENT

Kristopher
  • 8,450
  • 11
  • 42
  • 74
  • I don't think so. If I'm reading the documentation correctly, those are only sent a) when the screen comes on and b) when the user is past the keyguard respectively. On my device the screen never goes off and there is no keyguard. I just need to keep sending "stay awake" messages whenever the user interacts. – Mark Whitaker Oct 17 '13 at 13:28
  • If there's no way to let the android devices sleep when unactive then I would use front cameras in order to detect user's activity. – Kristopher Oct 17 '13 at 13:43
  • Think you've misunderstood this one. I didn't say the device can't go to sleep, I said that while it's active it has to keep another device active. Plus there's no front camera. (As I said, it's a "non-mobile device with a fixed power supply" - clearly not a phone!) – Mark Whitaker Oct 17 '13 at 13:50
  • 1
    I haven't worked on this myself, but I guess this link talks about something similar. http://stackoverflow.com/questions/6714020/how-can-a-service-listen-for-touch-gestures-events – Kumar Bibek Dec 11 '13 at 09:02