I need to determine if a user's been idle for a certain period of time.
If they have been idle, the app logs the user out.
I've combed the web and MS site am unable to find a property which basically returns a Boolean indicating is the user is inactive.
The closest thing I've found is a property which can enable or disable theUserIdleDetectionMode. Namely:
PhoneApplicationService.UserIdleDetectionMode Property
Can anyone tell me how I can problematically detect that a user has been inactive for a period of time within a Windows Phone app?
I don't believe there is a way to detect when a user is idle. You could let the phone do that for you and log the user out when the app is tombstoned. The only problem with this approach is the time the app gets tomstoned could vary.
See, WP7 App lifecyle
So when the Deactivated event fires, you could log the user out right before the app is tombstoned.
Related
I'm implementing some basic usage statistics for the first time in an Android/iOS app using Firebase Analytics, but the docs seem a little ambiguous to me on how exactly session durations are calculated and how sessions are timed out, and the 24-hour cycle for seeing results does not help in understanding by trial-and-error.
I'm only interested in a very simple statistic for now - the time users spend in the app. What exactly happens when the app is "minimised"/"in the background" - does that count as active usage or the same as the app being closed - is not so important right now, but if you have something to add in this regard in the context of the question, please do.
From what I understand such an easy statistic should probably be available out-of-the-box with Firebase Analytics, so I'm currently not using any custom events or anything fancier than simply linking Firebase Analytics into the projects, adding the configuration files, and calling FirebaseAnalytics.getInstance(this); on Android and [FIRApp configure]; on iOS.
I'm seeing first_open, session_start and app_remove events show up in the console as expected, some aggregate session data in the dashboard, etc, and I also know there is a configurable session timeout available.
But what is unclear to me is, when exactly does a user session expire - does Firebase automatically keep it open as long as the app is open, or do I need to make sure to post some artificial "keep-alive" events to prevent user sessions from expiring while a user is still actually using the app.
Assuming the following:
I send no explicit custom events using Firebase, as this is not
explicitly required by the app.
I only touch Firebase once during a single run of the app - initialising it on startup.
The user stays in the app for a long time (let's say 2 hours - much longer than the default 30 minute session timeout), without interacting with it - e.g. reading something, watching a video, etc, none of this generates any events that Firebase can see, but the app prevents the screen from locking, the app remains in foreground.
Will that count as a single 2 hour session for the user? Will it only count as a 30 minute session since the session expires after 30 minutes and no events are generated to keep it alive? Will something else happen?
Bonus question: what happens if the user exits the app for a time shorter/longer than the session timeout?
Bonus bonus question: does something change if instead of exiting from the app, it is simply put into background?
Thanks!
Quick answer: The scenario you describe will result in a single 2-hour session.
Sessions are based on the time that an app's activity is the current activity. There is no need to send events; the period from the time an activity resumes to the time it is suspended is counted as engagement time. At the end of an hour of continuous engagement an engagement event will be logged but this does not end the session. A session expires when there is a continuous period (30 minutes by default) that none of the app's activities is the current activity.
If the user exits the app for a shorter period than the session timeout and then restarts it, the session continues. If the user exits the app for longer than the session timeout, then the session ends. No change between exiting the app and putting it in the background. If it's not the thing the user is looking at, it doesn't count as engagement for the app to be running.
I am building an Android App to control power outlets with a smartphone. The app features an Android Wear app so people can control their lights right from their wrist.
When the user wants to control a light I send a String action via the MessageApi from the smartwatch to the smartphone, which receives this action in a WearableListenerService and sends the appropriate network signal to the power outlet/gateway in an AsyncTask.
This works fine as long as the phone has not been in idle for too long. However if the phone is still on the table for too long and doze kicks in Wear actions do execute very slow or sometimes not at all. I guess this is in part intended behavior however it is not practical in my case as the user cant wait that long for his lights to turn on if he wants to enter a dark room.
I am aware that doze completely cuts the networking for everything except FCM/GCM if you are not on the doze whitelist. But even when my app is on this whitelist and the networking part works actions can take a long time to execute on the phone.
So my specific question is:
Whats the recommended way to handle this scenario, where an action from a wearable device needs to be done via network on the connected smartphone which is in doze mode?
Is there a way to exit doze for a quick amount of time to execute calculations triggered by the wearable companion app faster?
I know the AlarmManager has a new method that works even in doze mode, but will this fix the processing delay too? Firing an alarm after receiving a MessageEvent from MessagApi seems like a workaround to me.
Or maybe is an AsyncTask just the wrong way to handle background networking and thats where the delay comes from?
Actually, there are a few options that you can do to handle Doze's effects as given in Adapting your app to Doze. You may want to consider the following options:
If your app requires a persistent connection to the network to receive messages, you should use Google Cloud Messaging (GCM) if possible.
GCM is optimized to work with Doze and App Standby idle modes by means of high-priority GCM messages. GCM high-priority messages let you reliably wake your app to access the network, even if the user’s device is in Doze or the app is in App Standby mode.
To help with scheduling alarms, Android 6.0 (API level 23) introduces two new AlarmManager methods: setAndAllowWhileIdle() and setExactAndAllowWhileIdle(). With these methods, you can set alarms that will fire even if the device is in Doze.
However, please note that with these methods, neither setAndAllowWhileIdle() nor setExactAndAllowWhileIdle() can fire alarms more than once per 9 minutes, per app.
Please try going through Optimizing for Doze and App Standby for a more detailed information or discussion.
In addition to these given documentations, the same options in handling Doze were also given and discussed in Diving into Doze Mode for Developers which might also help.
I think the title says it all !
I've read that in Windows Phone "all application lifecycle events enforce a limit of 10 seconds for an application to complete any tasks."
Does anyone knows why is it 10 seconds ? Why not more ? Why not less ? Is it really 10 seconds ?
Thanks in advance !
If you are referring to this quote on the MSDN:
The Closing Event
The Closing event is raised when the user navigates
backwards past the first page of an app. In this case, the app is
terminated and no state is saved. In the Closing event handler, your
app can save data that should persist across instances. There is a
limit of 10 seconds for an app to complete all application and page
navigation events. If this limit is exceeded, the application is
terminated. For this reason, it is a good idea to save persistent
state throughout the lifetime of the application and avoid having to
do large amounts of file I/O in the Closing event handler.
This is scoped to the Closing of the application. In other words: the user want to leave your app in way he won't be able to go back to it. (backwards beyond the first page of the app)
In this case all that app should do is save state it really needs the next time an dpass control as quickly as possible in order to have a decent user experience (speed!) Apparently Microsoft decided that 10 seconds is the most that a user should be bothered by the clossing of an app.
From the same page:
Remember that all application lifecycle events enforce a limit of 10 seconds for an application to complete any tasks.
Note that the 10 second limit is imposed on lifecycle events.
In general: an app should be responsive. What you should/could do, is save state as soon as state that should be persisted has been changed and/or as soon as a page navigation kicks in. That way you do not have to save all state when closing the app.
Can I use GeoCoordinateWatcher in Application_Launching to check that the phone location service is enabled or disabled? Does this affect performance?
Regards,
Panache
Don't!
Let the app launch and then decide.
You need your app to function even if the location service is disabled.
There is no time guarantee in confirming the location service is running so if you wait you may go over your allowed start up time.
Or are you just asking how to use a GeoCoordinateWatcher?
Edit:
If you want to only display this once, then just keep track of if you've displayed the prompt/message.
Also be aware that due to settings being changed while your app is tombstoned just performing the check on application launch does not guarantee that it will always be correct.
e.g.
location service disabled when app
started
App displays prompt
User presses start (app tombstoned)
uses changes settings to enable location service
user uses back button to reactivate app
app restarted (If doesn't RE-check if service enabled then would be wrong)
Please let me know how do I run the app under current logged in user from the service.
To give you background, I have a VB.NET Windows service whose sole functionality is to run a Winform App at a specified time. Apart from that it also sets a system wakeup timer so that the system can be woken up at the specified time, if it goes into standby/sleep, to run the app. This service has to cater to XP/Vista/Win7 desktops on our network. This service won't run on servers and laptops.
The Winform App shows a UI for the user to provide some inputs. If the user does not provide the input within 15 minutes, then it defaults the value and then goes into system tray icon. The user can click on the icon and change the values later (within in a specified time frame and that too only twice).
There is absolutely no interaction between the service and the winform app apart from the service starting the app. It also monitors if the app has been killed by the user/crashed. If it has been killed/crashed, then a new instance is run after 30 mins from previous run.
If there is no user logged on, then also I want the app to be run at the specified time. As I said before, the app has a default timer. So if some user has just logged off from the system, then defaults would be set by the winform app.
Now coming to why I am stuck with this design - I cannot use TaskScheduler because it has been disabled on all machines and security team is not willing to change it. TaskScheduler had the option to wakeup the machine from sleep and other things. So basically I ended up creating a service which is acting like task scheduler.
Currently when I run the app.exe via process.start() within the service, its running under SYSTEM account as the service is also running under LOCAL SYSTEM. So basically I am not getting any UI. Is there anyway to run it under the current logged in user? I am not worried about multiple user login as we wont be running it on servers and switch user is not enabled on our desktops. Even if somebody has done a remote login via mstsc, then also I need the run the app and show the UI to the user.
Please let me know how do I run the app under current logged in user from the service.
Thanks
askids
There were some additional comments that I posted. But I somehow cannot see it :(
Coming back to the original question. I was able to figure it out after several trial and errors. I will put it in detail.
With Vista and above, services run in isolation from other user sessions. They run in session 0. User sessions run in 1 and above. So basically you need to emulate the process as current logged in user.
Use WTSEnumerateSessions and
get of sessions. Check if the sesion
state is active. This will be
current logged on user session. If
there are no active sessions, it
means there is no logged on user. In
my case, there will be only 1 logged
on user. So I need not figure out
the active session (like others may
need to do).
Use WTSQueryUserToken to get the user token in the active session.
Create a primary user token using DuplicateTokenEx
Create an environment using CreateEnvironmentBlock
Use the information above in the CreateProcessAsUser
The reason why it was working in XP and not in Vista was because it looks like the startup default information is different. After I set wShowWindow flag of the startupinfo structure, the GUI would start appearing.
Dim StartupInfo As New STARTUPINFO()
StartupInfo.cb = Marshal.SizeOf(StartupInfo)
StartupInfo.dwFlags = STARTF_USESHOWWINDOW
StartupInfo.wShowWindow = WINDOW_STATUS.SW_SHOWNORMAL
One more additional info. I was trying to set the default desktop using
StartupInfo.lpDesktop = "WinSta0\\Default"
because of which the application would crash upon launch. So I commented it out.
I still have one final issue. The launched app is not in focus. The GUI appears, but in background. But I am thinking, it will once again have to do with some parameters like above. Once I figure it out, I will add in the details.