Ejemplo n.º 1
0
        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            AndroidSensusServiceHelper serviceHelper = SensusServiceHelper.Get() as AndroidSensusServiceHelper;

            // there might be a race condition between the calling of this method and the stopping/disposal of the service helper.
            // if the service helper is stopped/disposed before the service is stopped but after this method is called (e.g., by
            // an alarm callback), the service helper will be null.
            if (serviceHelper != null)
            {
                serviceHelper.Logger.Log("Sensus service received start command (startId=" + startId + ", flags=" + flags + ").", LoggingLevel.Normal, GetType());

                // update the foreground service notification with information about loaded/running studies.
                (SensusContext.Current.Notifier as AndroidNotifier).ReissueForegroundServiceNotification();

                // if the service started but there are no protocols that should be running, then stop the app now. there is no
                // reason for the app to be running in this situation, and the user will likely be annoyed at the presence of the
                // foreground service notification.
                if (intent != null && intent.GetBooleanExtra(KEY_STOP_SERVICE_IF_NO_PROTOCOLS_SHOULD_RUN, false) && serviceHelper.RunningProtocolIds.Count == 0)
                {
                    serviceHelper.Logger.Log("Started service without running protocols. Stopping service now.", LoggingLevel.Normal, GetType());
                    Stop();
                    return(StartCommandResult.NotSticky);
                }

                // acquire wake lock before this method returns to ensure that the device does not sleep prematurely, interrupting the execution of a callback.
                serviceHelper.KeepDeviceAwakeAsync().Wait();

                Task.Run(async() =>
                {
                    try
                    {
                        // the service can be stopped without destroying the service object. in such cases,
                        // subsequent calls to start the service will not call OnCreate. therefore, it's
                        // important that any code called here is okay to call multiple times, even if the
                        // service is running. calling this when the service is running can happen because
                        // sensus receives a signal on device boot and for any callback alarms that are
                        // requested. furthermore, all calls here should be nonblocking / async so we don't
                        // tie up the UI thread.
                        await serviceHelper.StartAsync();

                        if (intent != null)
                        {
                            AndroidCallbackScheduler callbackScheduler = SensusContext.Current.CallbackScheduler as AndroidCallbackScheduler;

                            if (callbackScheduler.IsCallback(intent))
                            {
                                await callbackScheduler.RaiseCallbackAsync(intent);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        serviceHelper.Logger.Log("Exception while responding to on-start command:  " + ex.Message, LoggingLevel.Normal, GetType());
                    }
                    finally
                    {
                        serviceHelper.LetDeviceSleepAsync().Wait();
                    }
                });
            }

            // if the service is killed by the system (e.g., due to resource constraints), ask the system to restart
            // the service when possible.
            return(StartCommandResult.Sticky);
        }