/// <summary> /// Initializes the SDK using the given configuration. The scanner can be used separately, but /// the resolving beacon actions cannot be done unless the SDK is initialized. /// If background task is enabled, this method check if there are updates for the /// background task filters available and updates them if so. /// </summary> public async Task InitializeAsync(SdkConfiguration configuration) { Status.IsApiKeyValid = false; _logger.Debug("InitializeAsync"); Configuration = configuration; SdkEngine.Configuration = configuration; if (!IsInitialized) { await SdkEngine.InitializeAsync(); await InitializeSettingsAsync(); Status.IsApiKeyValid = ServiceManager.LayoutManager.IsLayoutValid; Scanner.StatusChanged += OnScannerStatusChanged; Scanner.BeaconEvent += OnBeaconEventAsync; } if (SdkData.BackgroundTaskEnabled) { _logger.Debug("InitializeAsync#InitializeBackgground"); await UpdateBackgroundTaskIfNeededAsync(); } if (configuration.AutoStartScanner) { StartScanner(); } }
public void TestSetup() { ServiceManager.ReadOnlyForTests = false; ServiceManager.Clear(); SdkConfiguration = new SdkConfiguration() {ApiKey = "1234567890"}; ServiceManager.ApiConnction = new MockApiConnection() { MockSettings = "{\"revision\":0,\"settings\":{\"scanner.backgroundWaitTime\":120000, \"scanner.exitTimeoutMillis\":123, \"network.historyUploadInterval\":321}}", Configuration = SdkConfiguration, ValidApiKey = "1234567890" }; ServiceManager.SettingsManager = new SettingsManager(); ServiceManager.StorageService = new StorageService(); ServiceManager.ReadOnlyForTests = true; }
/// <summary> /// Registers the BLE advertisement watcher background task. /// </summary> /// <param name="configuration">Configuration for the new registration.</param> /// <returns>The registration result.</returns> private async Task <BackgroundTaskRegistrationResult> RegisterAdvertisementWatcherBackgroundTaskAsync(SdkConfiguration configuration) { BackgroundTaskRegistrationResult result = new BackgroundTaskRegistrationResult() { Success = false, Exception = null }; if (BackgroundTaskRegistered(AdvertisementClass)) { // Already registered Logger.Debug("BackgroundTaskManager.RegisterAdvertisementWatcherBackgroundTask(): Already registered"); result.Success = true; } else { BackgroundTaskBuilder backgroundTaskBuilder = new BackgroundTaskBuilder(); backgroundTaskBuilder.Name = AdvertisementClass + Guid.NewGuid(); backgroundTaskBuilder.TaskEntryPoint = configuration.BackgroundAdvertisementClassName; BluetoothLEAdvertisementWatcherTrigger advertisementWatcherTrigger = new BluetoothLEAdvertisementWatcherTrigger(); // This filter includes all Sensorberg beacons var pattern = BeaconFactory.UuidToAdvertisementBytePattern(configuration.BackgroundBeaconUuidSpace, configuration.ManufacturerId, configuration.BeaconCode); advertisementWatcherTrigger.AdvertisementFilter.BytePatterns.Add(pattern); ILayoutManager layoutManager = ServiceManager.LayoutManager; AppSettings = await ServiceManager.SettingsManager.GetSettings(); // Using MaxSamplingInterval as SamplingInterval ensures that we get an event only // when entering or exiting from the range of the beacon advertisementWatcherTrigger.SignalStrengthFilter.SamplingInterval = advertisementWatcherTrigger.MaxSamplingInterval; if (AppSettings.RssiEnterThreshold != null && AppSettings.RssiEnterThreshold.Value >= -128 && AppSettings.RssiEnterThreshold.Value <= 127) { advertisementWatcherTrigger.SignalStrengthFilter.InRangeThresholdInDBm = AppSettings.RssiEnterThreshold; } else { advertisementWatcherTrigger.SignalStrengthFilter.InRangeThresholdInDBm = Constants.DefaultBackgroundScannerEnterThreshold; } advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = SignalStrengthFilterOutOfRangeThresholdInDBm; advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(AppSettings.BeaconExitTimeout); IBackgroundTrigger trigger = advertisementWatcherTrigger; backgroundTaskBuilder.SetTrigger(trigger); try { BackgroundTaskRegistration backgroundTaskRegistration = backgroundTaskBuilder.Register(); backgroundTaskRegistration.Completed += OnAdvertisementWatcherBackgroundTaskCompleted; backgroundTaskRegistration.Progress += OnAdvertisementWatcherBackgroundTaskProgress; result.Success = true; } catch (Exception ex) { result.Exception = ex; Logger.Error("BackgroundTaskManager.RegisterAdvertisementWatcherBackgroundTask(): Failed to register: ", ex); if (ex.Message.Contains("0x800710DF)")) { await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => await new MessageDialog("Activate Bluetooth for the app").ShowAsync()); } } if (result.Success) { // Check if there was a pending filter update if (SdkData.BackgroundFilterUpdateRequired) { string upToDateHash = LayoutManager.CreateHashOfBeaconId1SInLayout(layoutManager.Layout); if (!string.IsNullOrEmpty(upToDateHash) && SdkData.LayoutBeaconId1Hash.Equals(upToDateHash)) { // Background filter updated successfully SdkData.BackgroundFilterUpdateRequired = false; BackgroundFiltersUpdated?.Invoke(this, null); } } else if (string.IsNullOrEmpty(SdkData.LayoutBeaconId1Hash)) { // This is the first time the background task is registered with valid layout => // set the hash string upToDateHash = LayoutManager.CreateHashOfBeaconId1SInLayout(layoutManager.Layout); if (!string.IsNullOrEmpty(upToDateHash)) { SdkData.LayoutBeaconId1Hash = upToDateHash; } } } } //Load last events from background await LoadBackgroundActions(); return(result); }
/// <summary> /// Register background tasks, by the given configuration. /// </summary> /// <param name="configuration">Configuration for the new registration.</param> public async Task <BackgroundTaskRegistrationResult> RegisterBackgroundTaskAsync(SdkConfiguration configuration) { BackgroundTaskRegistrationResult result = new BackgroundTaskRegistrationResult() { Success = IsBackgroundTaskRegistered, Exception = null }; if (!result.Success) { // Prompt user to accept the request BackgroundAccessStatus backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync(); if (backgroundAccessStatus == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity || backgroundAccessStatus == BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity) { result = RegisterTimedBackgroundTask(configuration.BackgroundTimerClassName); if (result.Success) { result = await RegisterAdvertisementWatcherBackgroundTaskAsync(configuration); } } if (result.Success) { Logger.Debug("BackgroundTaskManager.RegisterBackgroundTask(): Registration successful"); } } else { Logger.Debug("BackgroundTaskManager.RegisterBackgroundTask(): Already registered"); } return(result); }
/// <summary> /// Renew the registrations of the background taks. /// </summary> /// <param name="configuration">Configuration for the new registration.</param> public async Task <BackgroundTaskRegistrationResult> UpdateBackgroundTaskAsync(SdkConfiguration configuration) { UnregisterBackgroundTask(); return(await RegisterBackgroundTaskAsync(configuration)); }
/// <summary> /// Registers the BLE advertisement watcher background task. /// </summary> /// <param name="configuration">Configuration for the new registration.</param> /// <returns>The registration result.</returns> private async Task<BackgroundTaskRegistrationResult> RegisterAdvertisementWatcherBackgroundTaskAsync(SdkConfiguration configuration) { BackgroundTaskRegistrationResult result = new BackgroundTaskRegistrationResult() { Success = false, Exception = null }; if (BackgroundTaskRegistered(AdvertisementClass)) { // Already registered Logger.Debug("BackgroundTaskManager.RegisterAdvertisementWatcherBackgroundTask(): Already registered"); result.Success = true; } else { BackgroundTaskBuilder backgroundTaskBuilder = new BackgroundTaskBuilder(); backgroundTaskBuilder.Name = AdvertisementClass + Guid.NewGuid(); backgroundTaskBuilder.TaskEntryPoint = configuration.BackgroundAdvertisementClassName; BluetoothLEAdvertisementWatcherTrigger advertisementWatcherTrigger = new BluetoothLEAdvertisementWatcherTrigger(); // This filter includes all Sensorberg beacons var pattern = BeaconFactory.UuidToAdvertisementBytePattern(configuration.BackgroundBeaconUuidSpace, configuration.ManufacturerId, configuration.BeaconCode); advertisementWatcherTrigger.AdvertisementFilter.BytePatterns.Add(pattern); ILayoutManager layoutManager = ServiceManager.LayoutManager; AppSettings = await ServiceManager.SettingsManager.GetSettings(); // Using MaxSamplingInterval as SamplingInterval ensures that we get an event only // when entering or exiting from the range of the beacon advertisementWatcherTrigger.SignalStrengthFilter.SamplingInterval = advertisementWatcherTrigger.MaxSamplingInterval; if (AppSettings.RssiEnterThreshold != null && AppSettings.RssiEnterThreshold.Value >= -128 && AppSettings.RssiEnterThreshold.Value <= 127) { advertisementWatcherTrigger.SignalStrengthFilter.InRangeThresholdInDBm = AppSettings.RssiEnterThreshold; } else { advertisementWatcherTrigger.SignalStrengthFilter.InRangeThresholdInDBm = Constants.DefaultBackgroundScannerEnterThreshold; } advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeThresholdInDBm = SignalStrengthFilterOutOfRangeThresholdInDBm; advertisementWatcherTrigger.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(AppSettings.BeaconExitTimeout); IBackgroundTrigger trigger = advertisementWatcherTrigger; backgroundTaskBuilder.SetTrigger(trigger); try { BackgroundTaskRegistration backgroundTaskRegistration = backgroundTaskBuilder.Register(); backgroundTaskRegistration.Completed += OnAdvertisementWatcherBackgroundTaskCompleted; backgroundTaskRegistration.Progress += OnAdvertisementWatcherBackgroundTaskProgress; result.Success = true; } catch (Exception ex) { result.Exception = ex; Logger.Error("BackgroundTaskManager.RegisterAdvertisementWatcherBackgroundTask(): Failed to register: ", ex); if (ex.Message.Contains("0x800710DF)")) { await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => await new MessageDialog("Activate Bluetooth for the app").ShowAsync()); } } if (result.Success) { // Check if there was a pending filter update if (SdkData.BackgroundFilterUpdateRequired) { string upToDateHash = LayoutManager.CreateHashOfBeaconId1SInLayout(layoutManager.Layout); if (!string.IsNullOrEmpty(upToDateHash) && SdkData.LayoutBeaconId1Hash.Equals(upToDateHash)) { // Background filter updated successfully SdkData.BackgroundFilterUpdateRequired = false; BackgroundFiltersUpdated?.Invoke(this, null); } } else if (string.IsNullOrEmpty(SdkData.LayoutBeaconId1Hash)) { // This is the first time the background task is registered with valid layout => // set the hash string upToDateHash = LayoutManager.CreateHashOfBeaconId1SInLayout(layoutManager.Layout); if (!string.IsNullOrEmpty(upToDateHash)) { SdkData.LayoutBeaconId1Hash = upToDateHash; } } } } //Load last events from background await LoadBackgroundActions(); return result; }
/// <summary> /// Register background tasks, by the given configuration. /// </summary> /// <param name="configuration">Configuration for the new registration.</param> public async Task<BackgroundTaskRegistrationResult> RegisterBackgroundTaskAsync(SdkConfiguration configuration) { BackgroundTaskRegistrationResult result = new BackgroundTaskRegistrationResult() { Success = IsBackgroundTaskRegistered, Exception = null }; if (!result.Success) { // Prompt user to accept the request BackgroundAccessStatus backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync(); if (backgroundAccessStatus == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity || backgroundAccessStatus == BackgroundAccessStatus.AllowedWithAlwaysOnRealTimeConnectivity) { result = RegisterTimedBackgroundTask(configuration.BackgroundTimerClassName); if (result.Success) { result = await RegisterAdvertisementWatcherBackgroundTaskAsync(configuration); } } if (result.Success) { Logger.Debug("BackgroundTaskManager.RegisterBackgroundTask(): Registration successful"); } } else { Logger.Debug("BackgroundTaskManager.RegisterBackgroundTask(): Already registered"); } return result; }
/// <summary> /// Renew the registrations of the background taks. /// </summary> /// <param name="configuration">Configuration for the new registration.</param> public async Task<BackgroundTaskRegistrationResult> UpdateBackgroundTaskAsync(SdkConfiguration configuration) { UnregisterBackgroundTask(); return await RegisterBackgroundTaskAsync(configuration); }