From 519e93b737777e613b0fde5ab1a2739f0a616cba Mon Sep 17 00:00:00 2001 From: Erkki Silvola Date: Wed, 3 Apr 2019 11:52:34 +0300 Subject: [PATCH] docs updated, iOS demos updated to swift 5, watchOS sdk updated --- .../project.pbxproj | 4 +- .../project.pbxproj | 4 +- .../docs/html/BDBleApiImpl_8java_source.html | 128 ++--- .../PolarAccelerometerData_8java_source.html | 2 +- .../PolarBleApiDefaultImpl_8java_source.html | 4 +- .../docs/html/PolarBleApi_8java_source.html | 41 +- ...r_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html | 46 +- ...lar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.js | 1 + ...1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html | 171 +++--- ...r_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.js | 2 +- ...i_1_1PolarBleApi_1_1RecordingInterval.html | 12 +- ...k_1_1api_1_1PolarBleApi_1_1SampleType.html | 6 +- polar-sdk-android/docs/html/functions.html | 7 +- .../docs/html/functions_func.html | 7 +- ...i_1_1PolarBleApi_1_1PolarBleApiLogger.html | 2 +- polar-sdk-android/docs/html/navtreeindex0.js | 103 ++-- .../docs/API Default Implementation.html | 10 +- polar-sdk-ios/docs/API.html | 10 +- .../docs/Classes/PolarBleApiDefaultImpl.html | 10 +- polar-sdk-ios/docs/Enums/Features.html | 10 +- polar-sdk-ios/docs/Enums/SampleType.html | 10 +- .../docs/Extensions/PolarBleApiImpl.html | 530 ------------------ polar-sdk-ios/docs/Other Enums.html | 10 +- polar-sdk-ios/docs/Other Extensions.html | 214 ------- polar-sdk-ios/docs/Other Typealiases.html | 10 +- polar-sdk-ios/docs/PolarErrors.html | 10 +- polar-sdk-ios/docs/Protocols/PolarBleApi.html | 37 +- .../PolarBleApiDeviceFeaturesObserver.html | 10 +- .../PolarBleApiDeviceHrObserver.html | 10 +- .../PolarBleApiDeviceInfoObserver.html | 10 +- .../docs/Protocols/PolarBleApiLogger.html | 10 +- .../docs/Protocols/PolarBleApiObserver.html | 10 +- .../PolarBleApiPowerStateObserver.html | 10 +- .../docs/Structs/PolarSensorSetting.html | 10 +- .../PolarSensorSetting/SettingType.html | 10 +- .../Documents/API Default Implementation.html | 10 +- .../Contents/Resources/Documents/API.html | 10 +- .../Classes/PolarBleApiDefaultImpl.html | 10 +- .../Resources/Documents/Enums/Features.html | 10 +- .../Resources/Documents/Enums/SampleType.html | 10 +- .../Documents/Extensions/PolarBleApiImpl.html | 530 ------------------ .../Resources/Documents/Other Enums.html | 10 +- .../Resources/Documents/Other Extensions.html | 214 ------- .../Documents/Other Typealiases.html | 10 +- .../Resources/Documents/PolarErrors.html | 10 +- .../Documents/Protocols/PolarBleApi.html | 37 +- .../PolarBleApiDeviceFeaturesObserver.html | 10 +- .../PolarBleApiDeviceHrObserver.html | 10 +- .../PolarBleApiDeviceInfoObserver.html | 10 +- .../Protocols/PolarBleApiLogger.html | 10 +- .../Protocols/PolarBleApiObserver.html | 10 +- .../PolarBleApiPowerStateObserver.html | 10 +- .../Documents/Structs/PolarSensorSetting.html | 10 +- .../PolarSensorSetting/SettingType.html | 10 +- .../Contents/Resources/Documents/index.html | 10 +- .../Contents/Resources/Documents/search.json | 2 +- .../.docset/Contents/Resources/docSet.dsidx | Bin 49152 -> 36864 bytes polar-sdk-ios/docs/docsets/.tgz | Bin 74874 -> 70105 bytes polar-sdk-ios/docs/index.html | 10 +- polar-sdk-ios/docs/search.json | 2 +- polar-sdk-ios/docs/undocumented.json | 2 +- 61 files changed, 375 insertions(+), 2073 deletions(-) delete mode 100644 polar-sdk-ios/docs/Extensions/PolarBleApiImpl.html delete mode 100644 polar-sdk-ios/docs/Other Extensions.html delete mode 100644 polar-sdk-ios/docs/docsets/.docset/Contents/Resources/Documents/Extensions/PolarBleApiImpl.html delete mode 100644 polar-sdk-ios/docs/docsets/.docset/Contents/Resources/Documents/Other Extensions.html diff --git a/demos/iOS-Demos/PolarSDK-Broadcast-Demo/PolarSDK-Broadcast-Demo.xcodeproj/project.pbxproj b/demos/iOS-Demos/PolarSDK-Broadcast-Demo/PolarSDK-Broadcast-Demo.xcodeproj/project.pbxproj index 2cc15d90..210a471d 100644 --- a/demos/iOS-Demos/PolarSDK-Broadcast-Demo/PolarSDK-Broadcast-Demo.xcodeproj/project.pbxproj +++ b/demos/iOS-Demos/PolarSDK-Broadcast-Demo/PolarSDK-Broadcast-Demo.xcodeproj/project.pbxproj @@ -346,7 +346,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = "com.polar.PolarSDK-Broadcast-Demo"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -370,7 +370,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = "com.polar.PolarSDK-Broadcast-Demo"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/demos/iOS-Demos/PolarSDK-Exercise-Demo/PolarSDK-Exercise-Demo.xcodeproj/project.pbxproj b/demos/iOS-Demos/PolarSDK-Exercise-Demo/PolarSDK-Exercise-Demo.xcodeproj/project.pbxproj index afa25f85..8f1cf4fa 100644 --- a/demos/iOS-Demos/PolarSDK-Exercise-Demo/PolarSDK-Exercise-Demo.xcodeproj/project.pbxproj +++ b/demos/iOS-Demos/PolarSDK-Exercise-Demo/PolarSDK-Exercise-Demo.xcodeproj/project.pbxproj @@ -341,7 +341,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = "com.polar.PolarSDK-Exercise-Demo"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -365,7 +365,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = "com.polar.PolarSDK-Exercise-Demo"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/polar-sdk-android/docs/html/BDBleApiImpl_8java_source.html b/polar-sdk-android/docs/html/BDBleApiImpl_8java_source.html index 9d431896..16cf7cf9 100644 --- a/polar-sdk-android/docs/html/BDBleApiImpl_8java_source.html +++ b/polar-sdk-android/docs/html/BDBleApiImpl_8java_source.html @@ -66,112 +66,112 @@
BDBleApiImpl.java
-Go to the documentation of this file.
1 // Copyright © 2019 Polar Electro Oy. All rights reserved.
2 package polar.com.sdk.impl;
3 
4 import android.annotation.SuppressLint;
5 import android.bluetooth.le.ScanFilter;
6 import android.content.Context;
7 import android.os.Build;
8 import android.os.ParcelUuid;
9 import android.support.annotation.Nullable;
10 import android.util.Log;
11 import android.util.Pair;
12 
13 import com.androidcommunications.polar.api.ble.BleDeviceListener;
14 import com.androidcommunications.polar.api.ble.BleLogger;
15 import com.androidcommunications.polar.api.ble.exceptions.BleDisconnected;
16 import com.androidcommunications.polar.api.ble.model.BleDeviceSession;
17 import com.androidcommunications.polar.api.ble.model.advertisement.BleAdvertisementContent;
18 import com.androidcommunications.polar.api.ble.model.advertisement.BlePolarHrAdvertisement;
19 import com.androidcommunications.polar.api.ble.model.gatt.BleGattBase;
20 import com.androidcommunications.polar.api.ble.model.gatt.client.BleBattClient;
21 import com.androidcommunications.polar.api.ble.model.gatt.client.BleDisClient;
22 import com.androidcommunications.polar.api.ble.model.gatt.client.BleHrClient;
23 import com.androidcommunications.polar.api.ble.model.gatt.client.BlePMDClient;
24 import com.androidcommunications.polar.api.ble.model.gatt.client.psftp.BlePsFtpClient;
25 import com.androidcommunications.polar.api.ble.model.gatt.client.psftp.BlePsFtpUtils;
26 import com.androidcommunications.polar.common.ble.BleUtils;
27 import com.androidcommunications.polar.enpoints.ble.bluedroid.host.BDDeviceListenerImpl;
28 
29 import org.reactivestreams.Publisher;
30 
31 import java.io.ByteArrayOutputStream;
32 import java.text.SimpleDateFormat;
33 import java.util.ArrayList;
34 import java.util.Calendar;
35 import java.util.Collections;
36 import java.util.Comparator;
37 import java.util.Date;
38 import java.util.HashMap;
39 import java.util.HashSet;
40 import java.util.List;
41 import java.util.Locale;
42 import java.util.Map;
43 import java.util.Observable;
44 import java.util.Set;
45 import java.util.UUID;
46 import java.util.concurrent.TimeUnit;
47 import java.util.concurrent.atomic.AtomicInteger;
48 
49 import fi.polar.remote.representation.protobuf.ExerciseSamples;
50 import fi.polar.remote.representation.protobuf.Types;
51 import io.reactivex.Completable;
52 import io.reactivex.CompletableSource;
53 import io.reactivex.Flowable;
54 import io.reactivex.Scheduler;
55 import io.reactivex.Single;
56 import io.reactivex.SingleSource;
57 import io.reactivex.android.schedulers.AndroidSchedulers;
58 import io.reactivex.disposables.Disposable;
59 import io.reactivex.functions.Action;
60 import io.reactivex.functions.BiFunction;
61 import io.reactivex.functions.Consumer;
62 import io.reactivex.functions.Function;
63 import io.reactivex.functions.Predicate;
64 import io.reactivex.schedulers.Timed;
65 import polar.com.sdk.api.PolarBleApi;
83 import protocol.PftpNotification;
84 import protocol.PftpRequest;
85 import protocol.PftpResponse;
86 
90 public class BDBleApiImpl extends PolarBleApi {
91  private final static String TAG = BDBleApiImpl.class.getSimpleName();
92  private BleDeviceListener listener;
93  private Map<String,Disposable> connectSubscriptions = new HashMap<>();
94  private Scheduler scheduler;
97  private static final int ANDROID_VERSION_O = 26;
98 
99  @SuppressLint({"NewApi", "CheckResult"})
100  public BDBleApiImpl(final Context context, int features) {
101  super(features);
102  List<Class<? extends BleGattBase>> clients = new ArrayList<>();
103  if((this.features & PolarBleApi.FEATURE_HR)!=0){
104  clients.add(BleHrClient.class);
105  }
106  if((this.features & PolarBleApi.FEATURE_DEVICE_INFO)!=0){
107  clients.add(BleDisClient.class);
108  }
109  if((this.features & PolarBleApi.FEATURE_BATTERY_INFO)!=0){
110  clients.add(BleBattClient.class);
111  }
112  if((this.features & PolarBleApi.FEATURE_POLAR_SENSOR_STREAMING)!=0){
113  clients.add(BlePMDClient.class);
114  }
115  if((this.features & PolarBleApi.FEATURE_POLAR_FILE_TRANSFER)!=0){
116  clients.add(BlePsFtpClient.class);
117  }
118  listener = new BDDeviceListenerImpl(context, clients);
119  BleDeviceListener.BleSearchPreFilter filter = new BleDeviceListener.BleSearchPreFilter() {
120  @Override
121  public boolean process(BleAdvertisementContent content) {
122  return content.getPolarDeviceId().length() != 0 && !content.getPolarDeviceType().equals("mobile");
123  }
124  };
125  listener.setScanPreFilter(filter);
126  scheduler = AndroidSchedulers.from(context.getMainLooper());
127  listener.monitorDeviceSessionState(null).observeOn(scheduler).subscribe(
128  new Consumer<Pair<BleDeviceSession, BleDeviceSession.DeviceSessionState>>() {
129  @Override
130  public void accept(Pair<BleDeviceSession, BleDeviceSession.DeviceSessionState> pair) throws Exception {
131  PolarDeviceInfo info = new PolarDeviceInfo(pair.first.getPolarDeviceId(),
132  pair.first.getRssi(),pair.first.getName(),true);
133  switch (pair.second){
134  case SESSION_OPEN:
135  if(callback!=null){
137  }
138  setupDevice(pair.first);
139  break;
140  case SESSION_CLOSED:
141  if( callback != null ) {
142  if (pair.first.getPreviousState() == BleDeviceSession.DeviceSessionState.SESSION_OPEN ||
143  pair.first.getPreviousState() == BleDeviceSession.DeviceSessionState.SESSION_CLOSING){
145  }
146  }
147  break;
148  case SESSION_OPENING:
149  if(callback != null){
151  }
152  break;
153  }
154  }
155  },
156  new Consumer<Throwable>() {
157  @Override
158  public void accept(Throwable throwable) throws Exception {
159  logError(throwable.getMessage());
160  }
161  },
162  new Action() {
163  @Override
164  public void run() throws Exception {
165 
166  }
167  }
168  );
169  listener.monitorBleState().observeOn(scheduler).subscribe(
170  new Consumer<Boolean>() {
171  @Override
172  public void accept(Boolean aBoolean) throws Exception {
173  if(callback != null){
174  callback.blePowerStateChanged(aBoolean);
175  }
176  }
177  },
178  new Consumer<Throwable>() {
179  @Override
180  public void accept(Throwable throwable) throws Exception {
181  logError(throwable.getMessage());
182  }
183  },
184  new Action() {
185  @Override
186  public void run() throws Exception {
187 
188  }
189  }
190  );
191  BleLogger.setLoggerInterface(new BleLogger.BleLoggerInterface() {
192  @Override
193  public void d(String tag, String msg) {
194  log(tag+"/"+msg);
195  }
196 
197  @Override
198  public void e(String tag, String msg) {
199  logError(tag+"/"+msg);
200  }
201 
202  @Override
203  public void w(String tag, String msg) {
204  }
205 
206  @Override
207  public void i(String tag, String msg) {
208  }
209  });
210  }
211 
212  @SuppressLint("NewApi")
213  private void enableAndroidScanFilter() {
214  if (Build.VERSION.SDK_INT >= ANDROID_VERSION_O) {
215  List<ScanFilter> filter = new ArrayList<>();
216  filter.add(new ScanFilter.Builder().setServiceUuid(
217  ParcelUuid.fromString(BleHrClient.HR_SERVICE.toString())).build());
218  filter.add(new ScanFilter.Builder().setServiceUuid(
219  ParcelUuid.fromString(BlePsFtpUtils.RFC77_PFTP_SERVICE.toString())).build());
220  listener.setScanFilters(filter);
221  }
222  }
223 
224  @Override
225  public void shutDown() {
226  listener.shutDown();
227  }
228 
229  @Override
230  public boolean isFeatureReady(final String deviceId, int feature) {
231  try {
232  switch (feature) {
234  return sessionPsFtpClientReady(deviceId) != null;
236  return sessionPmdClientReady(deviceId) != null;
237  }
238  } catch (Throwable ignored) {
239  }
240  return false;
241  }
242 
243  @Override
245  this.callback = callback;
247  }
248 
249  @Override
250  public void setApiLogger(@Nullable PolarBleApiLogger logger) {
251  this.logger = logger;
252  }
253 
254  @Override
255  public void setAutomaticReconnection(boolean disable) {
256  listener.setAutomaticReconnection(disable);
257  }
258 
259  @Override
260  public Completable setLocalTime(String identifier, Date local) {
261  try {
262  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
263  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
264  PftpRequest.PbPFtpSetLocalTimeParams.Builder builder = PftpRequest.PbPFtpSetLocalTimeParams.newBuilder();
265  Calendar cal = Calendar.getInstance();
266  cal.setTime(local);
267  Types.PbDate date = Types.PbDate.newBuilder()
268  .setYear(cal.get(Calendar.YEAR))
269  .setMonth(cal.get(Calendar.MONTH) + 1)
270  .setDay(cal.get(Calendar.DAY_OF_MONTH)).build();
271  Types.PbTime time = Types.PbTime.newBuilder()
272  .setHour(cal.get(Calendar.HOUR))
273  .setMinute(cal.get(Calendar.MINUTE))
274  .setSeconds(cal.get(Calendar.SECOND))
275  .setMillis(cal.get(Calendar.MILLISECOND)).build();
276  builder.setDate(date).setTime(time).setTzOffset(cal.get(Calendar.ZONE_OFFSET));
277  return client.query(PftpRequest.PbPFtpQuery.SET_LOCAL_TIME_VALUE,builder.build().toByteArray()).toObservable().ignoreElements();
278  } catch (Throwable error){
279  return Completable.error(error);
280  }
281  }
282 
283  @Override
284  public Single<PolarSensorSetting> requestAccSettings(String identifier) {
285  return querySettings(identifier,BlePMDClient.PmdMeasurementType.ACC);
286  }
287 
288  @Override
289  public Single<PolarSensorSetting> requestEcgSettings(String identifier) {
290  return querySettings(identifier,BlePMDClient.PmdMeasurementType.ECG);
291  }
292 
293  @Override
294  public Single<PolarSensorSetting> requestPpgSettings(String identifier) {
295  return querySettings(identifier,BlePMDClient.PmdMeasurementType.PPG);
296  }
297 
298  @Override
299  public Single<PolarSensorSetting> requestBiozSettings(final String identifier){
300  return querySettings(identifier,BlePMDClient.PmdMeasurementType.BIOZ);
301  }
302 
303  private Single<PolarSensorSetting> querySettings(final String identifier, final BlePMDClient.PmdMeasurementType type) {
304  try {
305  final BleDeviceSession session = sessionPmdClientReady(identifier);
306  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
307  return client.querySettings(type).map(new Function<BlePMDClient.PmdSetting, PolarSensorSetting>() {
308  @Override
309  public PolarSensorSetting apply(BlePMDClient.PmdSetting setting) throws Exception {
310  return new PolarSensorSetting(setting.settings, type);
311  }
312  });
313  } catch (Throwable e){
314  return Single.error(e);
315  }
316  }
317 
318  @Override
319  public void backgroundEntered() {
321  }
322 
323  @Override
324  public void foregroundEntered() {
325  listener.setScanFilters(null);
326  }
327 
328  @Override
329  public Completable autoConnectToPolarDevice(final int rssiLimit, final int timeout, final TimeUnit unit, final String polarDeviceType) {
330  final long[] start = {0};
331  return listener.search(false).filter(new Predicate<BleDeviceSession>() {
332  @Override
333  public boolean test(BleDeviceSession bleDeviceSession) throws Exception {
334  if( bleDeviceSession.getMedianRssi() >= rssiLimit &&
335  bleDeviceSession.getPolarDeviceId().length() != 0 &&
336  bleDeviceSession.isConnectableAdvertisement() &&
337  (polarDeviceType == null || polarDeviceType.equals(bleDeviceSession.getPolarDeviceType())) ) {
338  if(start[0] == 0){
339  start[0] = System.currentTimeMillis();
340  }
341  return true;
342  }
343  return false;
344  }
345  }).timestamp().takeUntil(new Predicate<Timed<BleDeviceSession>>() {
346  @Override
347  public boolean test(Timed<BleDeviceSession> bleDeviceSessionTimed) throws Exception {
348  long diff = bleDeviceSessionTimed.time(TimeUnit.MILLISECONDS) - start[0];
349  return (diff >= unit.toMillis(timeout));
350  }
351  }).reduce(new HashSet<BleDeviceSession>(), new BiFunction<Set<BleDeviceSession>, Timed<BleDeviceSession>, Set<BleDeviceSession>>() {
352  @Override
353  public Set<BleDeviceSession> apply(Set<BleDeviceSession> objects, Timed<BleDeviceSession> bleDeviceSessionTimed) throws Exception {
354  objects.add(bleDeviceSessionTimed.value());
355  return objects;
356  }
357  }).doOnSuccess(new Consumer<Set<BleDeviceSession>>() {
358  @Override
359  public void accept(Set<BleDeviceSession> set) throws Exception {
360  List<BleDeviceSession> list = new ArrayList<>(set);
361  Collections.sort(list, new Comparator<BleDeviceSession>() {
362  @Override
363  public int compare(BleDeviceSession o1, BleDeviceSession o2) {
364  return o1.getRssi() > o2.getRssi() ? -1 : 1;
365  }
366  });
367  listener.openSessionDirect(list.get(0));
368  log("auto connect search complete");
369  }
370  }).toObservable().ignoreElements();
371  }
372 
373  @Override
374  public Completable autoConnectToPolarDevice(final int rssiLimit, final String polarDeviceType) {
375  return autoConnectToPolarDevice(rssiLimit, 2, TimeUnit.SECONDS, polarDeviceType);
376  }
377 
378  @Override
379  public void connectToPolarDevice(final String identifier) {
380  BleDeviceSession session = sessionByDeviceId(identifier);
381  if( session == null || session.getSessionState() == BleDeviceSession.DeviceSessionState.SESSION_CLOSED ){
382  if( connectSubscriptions.containsKey(identifier) ){
383  connectSubscriptions.get(identifier).dispose();
384  }
385  connectSubscriptions.put(identifier,listener.search(false).filter(new Predicate<BleDeviceSession>() {
386  @Override
387  public boolean test(BleDeviceSession bleDeviceSession) throws Exception {
388  return bleDeviceSession.getPolarDeviceId().equals(identifier);
389  }
390  }).take(1).observeOn(scheduler).subscribe(
391  new Consumer<BleDeviceSession>() {
392  @Override
393  public void accept(BleDeviceSession bleDeviceSession) throws Exception {
394  listener.openSessionDirect(bleDeviceSession);
395  }
396  },
397  new Consumer<Throwable>() {
398  @Override
399  public void accept(Throwable throwable) throws Exception {
400  logError(throwable.getMessage());
401  }
402  },
403  new Action() {
404  @Override
405  public void run() throws Exception {
406  log("connect search complete");
407  }
408  }
409  ));
410  }
411  }
412 
413  @Override
414  public void disconnectFromPolarDevice(String identifier) {
415  BleDeviceSession session = sessionByDeviceId(identifier);
416  if( session != null ){
417  if( session.getSessionState() == BleDeviceSession.DeviceSessionState.SESSION_OPEN ||
418  session.getSessionState() == BleDeviceSession.DeviceSessionState.SESSION_OPENING ||
419  session.getSessionState() == BleDeviceSession.DeviceSessionState.SESSION_OPEN_PARK ) {
420  listener.closeSessionDirect(session);
421  }
422  }
423  if (connectSubscriptions.containsKey(identifier)){
424  connectSubscriptions.get(identifier).dispose();
425  connectSubscriptions.remove(identifier);
426  }
427  }
428 
429  @Override
430  public Completable startRecording(String identifier, String exerciseId, RecordingInterval interval, SampleType type) {
431  try {
432  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
433  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
434  if(session.getPolarDeviceType().equals("H10")) {
435  Types.PbSampleType t = type == SampleType.HR ?
436  Types.PbSampleType.SAMPLE_TYPE_HEART_RATE :
437  Types.PbSampleType.SAMPLE_TYPE_RR_INTERVAL;
438  Types.PbDuration duration = Types.PbDuration.newBuilder().setSeconds(interval.getValue()).build();
439  PftpRequest.PbPFtpRequestStartRecordingParams params = PftpRequest.PbPFtpRequestStartRecordingParams.newBuilder().
440  setSampleDataIdentifier(exerciseId).setSampleType(t).setRecordingInterval(duration).build();
441  return client.query(PftpRequest.PbPFtpQuery.REQUEST_START_RECORDING_VALUE, params.toByteArray()).toObservable().ignoreElements().onErrorResumeNext(new Function<Throwable, CompletableSource>() {
442  @Override
443  public CompletableSource apply(Throwable throwable) throws Exception {
444  return Completable.error(throwable);
445  }
446  });
447  }
448  return Completable.error(new PolarOperationNotSupported());
449  } catch (Throwable error){
450  return Completable.error(error);
451  }
452  }
453 
454  @Override
455  public Completable stopRecording(String identifier) {
456  try {
457  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
458  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
459  if(session.getPolarDeviceType().equals("H10")) {
460  return client.query(PftpRequest.PbPFtpQuery.REQUEST_STOP_RECORDING_VALUE, null).toObservable().ignoreElements().onErrorResumeNext(new Function<Throwable, CompletableSource>() {
461  @Override
462  public CompletableSource apply(Throwable throwable) throws Exception {
463  return Completable.error(handleError(throwable));
464  }
465  });
466  }
467  return Completable.error(new PolarOperationNotSupported());
468  } catch (Throwable error){
469  return Completable.error(error);
470  }
471  }
472 
473  @Override
474  public Single<Pair<Boolean,String>> requestRecordingStatus(String identifier) {
475  try {
476  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
477  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
478  if(session.getPolarDeviceType().equals("H10")) {
479  return client.query(PftpRequest.PbPFtpQuery.REQUEST_RECORDING_STATUS_VALUE, null).map(new Function<ByteArrayOutputStream, Pair<Boolean,String>>() {
480  @Override
481  public Pair<Boolean,String> apply(ByteArrayOutputStream byteArrayOutputStream) throws Exception {
482  PftpResponse.PbRequestRecordingStatusResult result = PftpResponse.PbRequestRecordingStatusResult.parseFrom(byteArrayOutputStream.toByteArray());
483  return new Pair<>(result.getRecordingOn(),result.hasSampleDataIdentifier() ? result.getSampleDataIdentifier() : "");
484  }
485  }).onErrorResumeNext(new Function<Throwable, SingleSource<? extends Pair<Boolean, String>>>() {
486  @Override
487  public SingleSource<? extends Pair<Boolean, String>> apply(Throwable throwable) throws Exception {
488  return Single.error(handleError(throwable));
489  }
490  });
491  }
492  return Single.error(new PolarOperationNotSupported());
493  } catch (Throwable error){
494  return Single.error(error);
495  }
496  }
497 
498  @Override
499  public Flowable<PolarExerciseEntry> listExercises(String identifier) {
500  try{
501  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
502  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
503  switch (session.getPolarDeviceType()) {
504  case "OH1":
505  return fetchRecursively(client, "/U/0/", new FetchRecursiveCondition() {
506  @Override
507  public boolean include(String entry) {
508  return entry.matches("^([0-9]{8})(\\/)") ||
509  entry.matches("^([0-9]{6})(\\/)") ||
510  entry.equals("E/") ||
511  entry.equals("SAMPLES.BPB") ||
512  entry.equals("00/");
513  }
514  }).map(new Function<String, PolarExerciseEntry>() {
515  @Override
516  public PolarExerciseEntry apply(String p) throws Exception {
517  String components[] = p.split("/");
518  SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd HHmmss", Locale.getDefault());
519  Date date = format.parse(components[3] + " " + components[5]);
520  return new PolarExerciseEntry(p, date, components[3] + components[5]);
521  }
522  }).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarExerciseEntry>>() {
523  @Override
524  public Publisher<? extends PolarExerciseEntry> apply(Throwable throwable) throws Exception {
525  return Flowable.error(handleError(throwable));
526  }
527  });
528  case "H10":
529  return fetchRecursively(client, "/", new FetchRecursiveCondition() {
530  @Override
531  public boolean include(String entry) {
532  return entry.endsWith("/") || entry.equals("SAMPLES.BPB");
533  }
534  }).map(new Function<String, PolarExerciseEntry>() {
535  @Override
536  public PolarExerciseEntry apply(String p) throws Exception {
537  String components[] = p.split("/");
538  return new PolarExerciseEntry(p, new Date(), components[1]);
539  }
540  }).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarExerciseEntry>>() {
541  @Override
542  public Publisher<? extends PolarExerciseEntry> apply(Throwable throwable) throws Exception {
543  return Flowable.error(handleError(throwable));
544  }
545  });
546  default:
547  return Flowable.error(new PolarOperationNotSupported());
548  }
549  } catch (Throwable error){
550  return Flowable.error(error);
551  }
552  }
553 
554  @Override
555  public Single<PolarExerciseData> fetchExercise(String identifier, PolarExerciseEntry entry) {
556  try{
557  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
558  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
559  protocol.PftpRequest.PbPFtpOperation.Builder builder = protocol.PftpRequest.PbPFtpOperation.newBuilder();
560  builder.setCommand(PftpRequest.PbPFtpOperation.Command.GET);
561  builder.setPath(entry.path);
562  if(session.getPolarDeviceType().equals("OH1") || session.getPolarDeviceType().equals("H10")) {
563  return client.request(builder.build().toByteArray()).map(new Function<ByteArrayOutputStream, PolarExerciseData>() {
564  @Override
565  public PolarExerciseData apply(ByteArrayOutputStream byteArrayOutputStream) throws Exception {
566  ExerciseSamples.PbExerciseSamples samples = ExerciseSamples.PbExerciseSamples.parseFrom(byteArrayOutputStream.toByteArray());
567  return new PolarExerciseData(samples.getRecordingInterval().getSeconds(), samples.getHeartRateSamplesList());
568  }
569  }).onErrorResumeNext(new Function<Throwable, SingleSource<? extends PolarExerciseData>>() {
570  @Override
571  public SingleSource<? extends PolarExerciseData> apply(Throwable throwable) throws Exception {
572  return Single.error(handleError(throwable));
573  }
574  });
575  }
576  return Single.error(new PolarOperationNotSupported());
577  } catch (Throwable error){
578  return Single.error(error);
579  }
580  }
581 
582  @Override
583  public Completable removeExercise(String identifier, PolarExerciseEntry entry) {
584  try{
585  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
586  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
587  if(session.getPolarDeviceType().equals("OH1")){
588  protocol.PftpRequest.PbPFtpOperation.Builder builder = protocol.PftpRequest.PbPFtpOperation.newBuilder();
589  builder.setCommand(PftpRequest.PbPFtpOperation.Command.GET);
590  final String components[] = entry.path.split("/");
591  final String exerciseParent = "/U/0/" + components[3] + "/E/";
592  builder.setPath(exerciseParent);
593  return client.request(builder.build().toByteArray()).flatMap(new Function<ByteArrayOutputStream, SingleSource<?>>() {
594  @Override
595  public SingleSource<?> apply(ByteArrayOutputStream byteArrayOutputStream) throws Exception {
596  PftpResponse.PbPFtpDirectory directory = PftpResponse.PbPFtpDirectory.parseFrom(byteArrayOutputStream.toByteArray());
597  protocol.PftpRequest.PbPFtpOperation.Builder removeBuilder = protocol.PftpRequest.PbPFtpOperation.newBuilder();
598  removeBuilder.setCommand(PftpRequest.PbPFtpOperation.Command.REMOVE);
599  if( directory.getEntriesCount() <= 1 ){
600  // remove entire directory
601  removeBuilder.setPath("/U/0/" + components[3] + "/");
602  } else {
603  // remove only exercise
604  removeBuilder.setPath("/U/0/" + components[3] + "/E/" + components[5] + "/");
605  }
606  return client.request(removeBuilder.build().toByteArray());
607  }
608  }).toObservable().ignoreElements().onErrorResumeNext(new Function<Throwable, CompletableSource>() {
609  @Override
610  public CompletableSource apply(Throwable throwable) throws Exception {
611  return Completable.error(handleError(throwable));
612  }
613  });
614  } else if(session.getPolarDeviceType().equals("H10")){
615  protocol.PftpRequest.PbPFtpOperation.Builder builder = protocol.PftpRequest.PbPFtpOperation.newBuilder();
616  builder.setCommand(PftpRequest.PbPFtpOperation.Command.REMOVE);
617  builder.setPath(entry.path);
618  return client.request(builder.build().toByteArray()).toObservable().ignoreElements().onErrorResumeNext(new Function<Throwable, CompletableSource>() {
619  @Override
620  public CompletableSource apply(Throwable throwable) throws Exception {
621  return Completable.error(handleError(throwable));
622  }
623  });
624  }
625  return Completable.error(new PolarOperationNotSupported());
626  } catch (Throwable error){
627  return Completable.error(error);
628  }
629  }
630 
631  @Override
632  public Flowable<PolarDeviceInfo> searchForPolarDevice() {
633  return listener.search(false).filter(new Predicate<BleDeviceSession>() {
634  @Override
635  public boolean test(BleDeviceSession bleDeviceSession) throws Exception {
636  return bleDeviceSession.getAdvertisementContent().getPolarDeviceId().length() != 0;
637  }
638  }).distinct().map(new Function<BleDeviceSession, PolarDeviceInfo>() {
639  @Override
640  public PolarDeviceInfo apply(BleDeviceSession bleDeviceSession) throws Exception {
641  return new PolarDeviceInfo(bleDeviceSession.getPolarDeviceId(),bleDeviceSession.getRssi(),bleDeviceSession.getName(), bleDeviceSession.isConnectableAdvertisement());
642  }
643  });
644  }
645 
646  @Override
647  public Flowable<PolarHrBroadcastData> startListenForPolarHrBroadcasts(final Set<String> deviceIds) {
648  // set filter to null, NOTE this disables reconnection in background
649  return listener.search(false).filter(new Predicate<BleDeviceSession>() {
650  @Override
651  public boolean test(BleDeviceSession bleDeviceSession) throws Exception {
652  return (deviceIds == null || deviceIds.contains(bleDeviceSession.getPolarDeviceId())) &&
653  bleDeviceSession.getAdvertisementContent().getPolarHrAdvertisement().isPresent();
654  }
655  }).map(new Function<BleDeviceSession, PolarHrBroadcastData>() {
656  @Override
657  public PolarHrBroadcastData apply(BleDeviceSession bleDeviceSession) throws Exception {
658  BlePolarHrAdvertisement advertisement = bleDeviceSession.getBlePolarHrAdvertisement();
659  return new PolarHrBroadcastData( new PolarDeviceInfo(bleDeviceSession.getPolarDeviceId(),
660  bleDeviceSession.getRssi(), bleDeviceSession.getName(), bleDeviceSession.isConnectableAdvertisement()),
661  advertisement.getHrForDisplay(), advertisement.getBatteryStatus() != 0);
662  }
663  });
664  }
665 
666  @Override
667  public Flowable<PolarEcgData> startEcgStreaming(String identifier,
668  PolarSensorSetting setting) {
669  try {
670  final BleDeviceSession session = sessionPmdClientReady(identifier);
671  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
672  return client.startMeasurement(BlePMDClient.PmdMeasurementType.ECG, setting.map2PmdSettings()).andThen(
673  client.monitorEcgNotifications(true).map(new Function<BlePMDClient.EcgData, PolarEcgData>() {
674  @Override
675  public PolarEcgData apply(BlePMDClient.EcgData ecgData) throws Exception {
676  List<Integer> samples = new ArrayList<>();
677  for( BlePMDClient.EcgData.EcgSample s : ecgData.ecgSamples ){
678  samples.add(s.microVolts);
679  }
680  return new PolarEcgData(samples,ecgData.timeStamp);
681  }
682  }).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarEcgData>>() {
683  @Override
684  public Publisher<? extends PolarEcgData> apply(Throwable throwable) throws Exception {
685  return Flowable.error(handleError(throwable));
686  }
687  }).doFinally(new Action() {
688  @Override
689  public void run() throws Exception {
690  stopPmdStreaming(session,client, BlePMDClient.PmdMeasurementType.ECG);
691  }
692  }));
693  } catch (Throwable t){
694  return Flowable.error(t);
695  }
696  }
697 
698  @Override
699  public Flowable<PolarAccelerometerData> startAccStreaming(String identifier,
700  PolarSensorSetting setting) {
701  try {
702  final BleDeviceSession session = sessionPmdClientReady(identifier);
703  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
704  return client.startMeasurement(BlePMDClient.PmdMeasurementType.ACC, setting.map2PmdSettings()).andThen(
705  client.monitorAccNotifications(true).map(new Function<BlePMDClient.AccData, PolarAccelerometerData>() {
706  @Override
707  public PolarAccelerometerData apply(BlePMDClient.AccData accData) throws Exception {
708  List<PolarAccelerometerData.PolarAccelerometerSample> samples = new ArrayList<>();
709  for( BlePMDClient.AccData.AccSample s : accData.accSamples ){
710  samples.add(new PolarAccelerometerData.PolarAccelerometerSample(s.x,s.y,s.z));
711  }
712  return new PolarAccelerometerData(samples,accData.timeStamp);
713  }
714  }).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarAccelerometerData>>() {
715  @Override
716  public Publisher<? extends PolarAccelerometerData> apply(Throwable throwable) throws Exception {
717  return Flowable.error(handleError(throwable));
718  }
719  }).doFinally(new Action() {
720  @Override
721  public void run() throws Exception {
722  stopPmdStreaming(session,client, BlePMDClient.PmdMeasurementType.ACC);
723  }
724  }));
725  } catch (Throwable t){
726  return Flowable.error(t);
727  }
728  }
729 
730  @Override
731  public Flowable<PolarOhrPPGData> startOhrPPGStreaming(String identifier,
732  PolarSensorSetting setting) {
733  try {
734  final BleDeviceSession session = sessionPmdClientReady(identifier);
735  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
736  return client.startMeasurement(BlePMDClient.PmdMeasurementType.PPG, setting.map2PmdSettings()).andThen(
737  client.monitorPpgNotifications(true).map(new Function<BlePMDClient.PpgData, PolarOhrPPGData>() {
738  @Override
739  public PolarOhrPPGData apply(BlePMDClient.PpgData ppgData) throws Exception {
740  List<PolarOhrPPGData.PolarOhrPPGSample> samples = new ArrayList<>();
741  for( BlePMDClient.PpgData.PpgSample s : ppgData.ppgSamples ){
742  samples.add(new PolarOhrPPGData.PolarOhrPPGSample(s.ppg0,s.ppg1,s.ppg2,s.ambient));
743  }
744  return new PolarOhrPPGData(samples,ppgData.timeStamp);
745  }
746  }).doFinally(new Action() {
747  @Override
748  public void run() throws Exception {
749  stopPmdStreaming(session,client, BlePMDClient.PmdMeasurementType.PPG);
750  }
751  })).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarOhrPPGData>>() {
752  @Override
753  public Publisher<? extends PolarOhrPPGData> apply(Throwable throwable) throws Exception {
754  return Flowable.error(handleError(throwable));
755  }
756  });
757  } catch (Throwable t){
758  return Flowable.error(t);
759  }
760  }
761 
762  @Override
763  public Flowable<PolarOhrPPIData> startOhrPPIStreaming(String identifier) {
764  try {
765  final BleDeviceSession session = sessionPmdClientReady(identifier);
766  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
767  return client.startMeasurement(BlePMDClient.PmdMeasurementType.PPI, new BlePMDClient.PmdSetting(new HashMap<BlePMDClient.PmdSetting.PmdSettingType, Integer>())).andThen(
768  client.monitorPpiNotifications(true).map(new Function<BlePMDClient.PpiData, PolarOhrPPIData>() {
769  @Override
770  public PolarOhrPPIData apply(BlePMDClient.PpiData ppiData) throws Exception {
771  List<PolarOhrPPIData.PolarOhrPPISample> samples = new ArrayList<>();
772  for(BlePMDClient.PpiData.PPSample ppSample : ppiData.ppSamples){
773  samples.add(new PolarOhrPPIData.PolarOhrPPISample(ppSample.ppInMs,
774  ppSample.ppErrorEstimate,
775  ppSample.hr,
776  ppSample.blockerBit != 0,
777  ppSample.skinContactStatus != 0,
778  ppSample.skinContactSupported != 0));
779  }
780  return new PolarOhrPPIData(ppiData.timestamp,samples);
781  }
782  }).doFinally(new Action() {
783  @Override
784  public void run() throws Exception {
785  stopPmdStreaming(session,client, BlePMDClient.PmdMeasurementType.PPI);
786  }
787  })).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarOhrPPIData>>() {
788  @Override
789  public Publisher<? extends PolarOhrPPIData> apply(Throwable throwable) throws Exception {
790  return Flowable.error(handleError(throwable));
791  }
792  });
793  } catch (Throwable t){
794  return Flowable.error(t);
795  }
796  }
797 
798  @Override
799  public Flowable<PolarBiozData> startBiozStreaming(final String identifier, PolarSensorSetting setting){
800  try {
801  final BleDeviceSession session = sessionPmdClientReady(identifier);
802  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
803  return client.startMeasurement(BlePMDClient.PmdMeasurementType.BIOZ, setting.map2PmdSettings()).andThen(
804  client.monitorBiozNotifications(true).map(new Function<BlePMDClient.BiozData, PolarBiozData>() {
805  @Override
806  public PolarBiozData apply(BlePMDClient.BiozData biozData) throws Exception {
807  return new PolarBiozData(biozData.timeStamp,biozData.samples);
808  }
809  }).doFinally(new Action() {
810  @Override
811  public void run() throws Exception {
812  stopPmdStreaming(session,client, BlePMDClient.PmdMeasurementType.PPG);
813  }
814  })).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarBiozData>>() {
815  @Override
816  public Publisher<? extends PolarBiozData> apply(Throwable throwable) throws Exception {
817  return Flowable.error(handleError(throwable));
818  }
819  });
820  } catch (Throwable t){
821  return Flowable.error(t);
822  }
823  }
824 
825  private BleDeviceSession sessionByDeviceId(final String deviceId) {
826  for ( BleDeviceSession session : listener.deviceSessions() ){
827  if( session.getAdvertisementContent().getPolarDeviceId().equals(deviceId) ){
828  return session;
829  }
830  }
831  return null;
832  }
833 
834  private BleDeviceSession sessionServiceReady(final String identifier, UUID service) throws Throwable {
835  BleDeviceSession session = sessionByDeviceId(identifier);
836  if(session != null){
837  if(session.getSessionState() == BleDeviceSession.DeviceSessionState.SESSION_OPEN) {
838  BleGattBase client = session.fetchClient(service);
839  if (client.isServiceDiscovered()) {
840  return session;
841  }
842  throw new PolarServiceNotAvailable();
843  }
844  throw new PolarDeviceDisconnected();
845  }
846  throw new PolarDeviceNotFound();
847  }
848 
849  public BleDeviceSession sessionPmdClientReady(final String identifier) throws Throwable {
850  BleDeviceSession session = sessionServiceReady(identifier, BlePMDClient.PMD_SERVICE);
851  BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
852  final AtomicInteger pair = client.getNotificationAtomicInteger(BlePMDClient.PMD_CP);
853  final AtomicInteger pairData = client.getNotificationAtomicInteger(BlePMDClient.PMD_DATA);
854  if (pair != null && pairData != null &&
855  pair.get() == BleGattBase.ATT_SUCCESS &&
856  pairData.get() == BleGattBase.ATT_SUCCESS) {
857  return session;
858  }
859  throw new PolarNotificationNotEnabled();
860  }
861 
862  private BleDeviceSession sessionPsFtpClientReady(final String identifier) throws Throwable {
863  BleDeviceSession session = sessionServiceReady(identifier, BlePsFtpUtils.RFC77_PFTP_SERVICE);
864  BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
865  final AtomicInteger pair = client.getNotificationAtomicInteger(BlePsFtpUtils.RFC77_PFTP_MTU_CHARACTERISTIC);
866  if (pair != null && pair.get() == BleGattBase.ATT_SUCCESS ) {
867  return session;
868  }
869  throw new PolarNotificationNotEnabled();
870  }
871 
872  @SuppressLint("CheckResult")
873  private void stopPmdStreaming(BleDeviceSession session, BlePMDClient client, BlePMDClient.PmdMeasurementType type) {
874  if( session.getSessionState() == BleDeviceSession.DeviceSessionState.SESSION_OPEN ){
875  // stop streaming
876  client.stopMeasurement(type).subscribe(
877  new Action() {
878  @Override
879  public void run() throws Exception {
880 
881  }
882  },
883  new Consumer<Throwable>() {
884  @Override
885  public void accept(Throwable throwable) throws Exception {
886  logError("failed to stop pmd stream: " + throwable.getLocalizedMessage());
887  }
888  }
889  );
890  }
891  }
892 
893  @SuppressLint("CheckResult")
894  private void setupDevice(final BleDeviceSession session){
895  final String deviceId = session.getPolarDeviceId();
896  session.monitorServicesDiscovered(true).observeOn(scheduler).toFlowable().flatMapIterable(
897  new Function<List<UUID>, Iterable<UUID>>() {
898  @Override
899  public Iterable<UUID> apply(List<UUID> uuids) throws Exception {
900  return uuids;
901  }
902  }
903  ).flatMap(new Function<UUID, Publisher<?>>() {
904  @Override
905  public Publisher<?> apply(UUID uuid) throws Exception {
906  if(session.fetchClient(uuid) != null) {
907  if (uuid.equals(BleHrClient.HR_SERVICE)) {
908  if (callback != null) {
909  callback.hrFeatureReady(deviceId);
910  }
911  final BleHrClient client = (BleHrClient) session.fetchClient(BleHrClient.HR_SERVICE);
912  client.observeHrNotifications(true).observeOn(scheduler).subscribe(
913  new Consumer<BleHrClient.HrNotificationData>() {
914  @Override
915  public void accept(BleHrClient.HrNotificationData hrNotificationData) throws Exception {
916  if (callback != null) {
918  new PolarHrData(hrNotificationData.hrValue,
919  hrNotificationData.rrs,
920  hrNotificationData.sensorContact,
921  hrNotificationData.sensorContactSupported,
922  hrNotificationData.rrPresent));
923  }
924  }
925  },
926  new Consumer<Throwable>() {
927  @Override
928  public void accept(Throwable throwable) throws Exception {
929  logError(throwable.getMessage());
930  }
931  },
932  new Action() {
933  @Override
934  public void run() throws Exception {
935 
936  }
937  }
938  );
939  } else if (uuid.equals(BleBattClient.BATTERY_SERVICE)) {
940  BleBattClient client = (BleBattClient) session.fetchClient(BleBattClient.BATTERY_SERVICE);
941  return client.waitBatteryLevelUpdate(true).observeOn(scheduler).doOnSuccess(new Consumer<Integer>() {
942  @Override
943  public void accept(Integer integer) throws Exception {
944  if (callback != null) {
945  callback.batteryLevelReceived(deviceId, integer);
946  }
947  }
948  }).toFlowable();
949  } else if (uuid.equals(BlePMDClient.PMD_SERVICE)) {
950  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
951  return client.waitNotificationEnabled(BlePMDClient.PMD_CP, true).
952  concatWith(client.waitNotificationEnabled(BlePMDClient.PMD_DATA, true)).andThen(client.readFeature(true).doOnSuccess(new Consumer<BlePMDClient.PmdFeature>() {
953  @Override
954  public void accept(BlePMDClient.PmdFeature pmdFeature) {
955  if (callback != null) {
956  if (pmdFeature.ecgSupported) {
957  callback.ecgFeatureReady(deviceId);
958  }
959  if (pmdFeature.accSupported) {
961  }
962  if (pmdFeature.ppgSupported) {
963  callback.ppgFeatureReady(deviceId);
964  }
965  if (pmdFeature.ppiSupported) {
966  callback.ppiFeatureReady(deviceId);
967  }
968  if (pmdFeature.bioZSupported) {
969  callback.biozFeatureReady(deviceId);
970  }
971  }
972  }
973  })).toFlowable();
974  } else if (uuid.equals(BleDisClient.DIS_SERVICE)) {
975  BleDisClient client = (BleDisClient) session.fetchClient(BleDisClient.DIS_SERVICE);
976  return client.observeDisInfo(true).takeUntil(new Predicate<HashMap<UUID, String>>() {
977  @Override
978  public boolean test(HashMap<UUID, String> map) throws Exception {
979  return map.containsKey(BleDisClient.SOFTWARE_REVISION_STRING);
980  }
981  }).observeOn(scheduler).doOnNext(new Consumer<HashMap<UUID, String>>() {
982  @Override
983  public void accept(HashMap<UUID, String> uuidStringHashMap) throws Exception {
984  if (callback != null && uuidStringHashMap.containsKey(BleDisClient.SOFTWARE_REVISION_STRING)) {
985  callback.fwInformationReceived(deviceId, uuidStringHashMap.get(BleDisClient.SOFTWARE_REVISION_STRING));
986  }
987  }
988  });
989  } else if (uuid.equals(BlePsFtpUtils.RFC77_PFTP_SERVICE)) {
990  BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
991  return client.waitPsFtpClientReady(true).observeOn(scheduler).doOnComplete(new Action() {
992  @Override
993  public void run() throws Exception {
994  if (callback != null &&
995  (session.getPolarDeviceType().equals("OH1") || session.getPolarDeviceType().equals("H10"))) {
996  callback.polarFtpFeatureReady(deviceId);
997  }
998  }
999  }).toFlowable();
1000  }
1001  }
1002  return Flowable.empty();
1003  }
1004  }).subscribe(
1005  new Consumer<Object>() {
1006  @Override
1007  public void accept(Object o) throws Exception {
1008 
1009  }
1010  },
1011  new Consumer<Throwable>() {
1012  @Override
1013  public void accept(Throwable throwable) throws Exception {
1014  logError(throwable.getMessage());
1015  }
1016  },
1017  new Action() {
1018  @Override
1019  public void run() throws Exception {
1020  log("complete");
1021  }
1022  });
1023  }
1024 
1025  private Exception handleError(Throwable throwable) {
1026  if( throwable instanceof BleDisconnected ){
1027  return new PolarDeviceDisconnected();
1028  } else {
1029  return new Exception("Unknown Error: " + throwable.getLocalizedMessage());
1030  }
1031  }
1032 
1033  interface FetchRecursiveCondition {
1034  boolean include(String entry);
1035  }
1036 
1037  private Flowable<String> fetchRecursively(final BlePsFtpClient client, final String path, final FetchRecursiveCondition condition) {
1038  protocol.PftpRequest.PbPFtpOperation.Builder builder = protocol.PftpRequest.PbPFtpOperation.newBuilder();
1039  builder.setCommand(PftpRequest.PbPFtpOperation.Command.GET);
1040  builder.setPath(path);
1041  return client.request(builder.build().toByteArray()).toFlowable().flatMap(new Function<ByteArrayOutputStream, Publisher<String>>() {
1042  @Override
1043  public Publisher<String> apply(ByteArrayOutputStream byteArrayOutputStream) throws Exception {
1044  PftpResponse.PbPFtpDirectory dir = PftpResponse.PbPFtpDirectory.parseFrom(byteArrayOutputStream.toByteArray());
1045  Set<String> entrys = new HashSet<>();
1046  for( int i=0; i < dir.getEntriesCount(); ++i ){
1047  PftpResponse.PbPFtpEntry entry = dir.getEntries(i);
1048  if( condition.include(entry.getName()) ){
1049  BleUtils.validate(entrys.add(path + entry.getName()),"duplicate entry");
1050  }
1051  }
1052  if(entrys.size()!=0) {
1053  return Flowable.fromIterable(entrys).flatMap(new Function<String, Publisher<String>>() {
1054  @Override
1055  public Publisher<String> apply(String s) {
1056  if (s.endsWith("/")) {
1057  return fetchRecursively(client, s, condition);
1058  } else {
1059  return Flowable.just(s);
1060  }
1061  }
1062  });
1063  }
1064  return Flowable.empty();
1065  }
1066  });
1067  }
1068 
1069  @SuppressLint("CheckResult")
1070  private void sendNotification(BlePsFtpClient client, int notification){
1071  client.sendNotification(notification,null).subscribe(
1072  new Action() {
1073  @Override
1074  public void run() throws Exception {
1075  }
1076  },
1077  new Consumer<Throwable>() {
1078  @Override
1079  public void accept(Throwable throwable) throws Exception {
1080  logError("failed to send notification: " + throwable.getLocalizedMessage());
1081  }
1082  }
1083  );
1084  }
1085 
1086  private void log(final String message) {
1087  if(logger != null){
1088  logger.message("" + message);
1089  }
1090  }
1091 
1092  private void logError(final String message) {
1093  if(logger != null){
1094  logger.message("Error: "+message);
1095  }
1096  }
1097 }
-
void log(final String message)
-
Flowable< PolarDeviceInfo > searchForPolarDevice()
- -
static final int ANDROID_VERSION_O
-
Single< PolarExerciseData > fetchExercise(String identifier, PolarExerciseEntry entry)
- -
Completable startRecording(String identifier, String exerciseId, RecordingInterval interval, SampleType type)
+Go to the documentation of this file.
1 // Copyright © 2019 Polar Electro Oy. All rights reserved.
2 package polar.com.sdk.impl;
3 
4 import android.annotation.SuppressLint;
5 import android.bluetooth.le.ScanFilter;
6 import android.content.Context;
7 import android.os.Build;
8 import android.os.ParcelUuid;
9 import android.support.annotation.Nullable;
10 import android.util.Log;
11 import android.util.Pair;
12 
13 import com.androidcommunications.polar.api.ble.BleDeviceListener;
14 import com.androidcommunications.polar.api.ble.BleLogger;
15 import com.androidcommunications.polar.api.ble.exceptions.BleDisconnected;
16 import com.androidcommunications.polar.api.ble.model.BleDeviceSession;
17 import com.androidcommunications.polar.api.ble.model.advertisement.BleAdvertisementContent;
18 import com.androidcommunications.polar.api.ble.model.advertisement.BlePolarHrAdvertisement;
19 import com.androidcommunications.polar.api.ble.model.gatt.BleGattBase;
20 import com.androidcommunications.polar.api.ble.model.gatt.client.BleBattClient;
21 import com.androidcommunications.polar.api.ble.model.gatt.client.BleDisClient;
22 import com.androidcommunications.polar.api.ble.model.gatt.client.BleHrClient;
23 import com.androidcommunications.polar.api.ble.model.gatt.client.BlePMDClient;
24 import com.androidcommunications.polar.api.ble.model.gatt.client.psftp.BlePsFtpClient;
25 import com.androidcommunications.polar.api.ble.model.gatt.client.psftp.BlePsFtpUtils;
26 import com.androidcommunications.polar.common.ble.BleUtils;
27 import com.androidcommunications.polar.enpoints.ble.bluedroid.host.BDDeviceListenerImpl;
28 
29 import org.reactivestreams.Publisher;
30 
31 import java.io.ByteArrayOutputStream;
32 import java.text.SimpleDateFormat;
33 import java.util.ArrayList;
34 import java.util.Calendar;
35 import java.util.Collections;
36 import java.util.Comparator;
37 import java.util.Date;
38 import java.util.HashMap;
39 import java.util.HashSet;
40 import java.util.List;
41 import java.util.Locale;
42 import java.util.Map;
43 import java.util.Observable;
44 import java.util.Set;
45 import java.util.TreeSet;
46 import java.util.UUID;
47 import java.util.concurrent.TimeUnit;
48 import java.util.concurrent.atomic.AtomicInteger;
49 
50 import fi.polar.remote.representation.protobuf.ExerciseSamples;
51 import fi.polar.remote.representation.protobuf.Types;
52 import io.reactivex.Completable;
53 import io.reactivex.CompletableSource;
54 import io.reactivex.Flowable;
55 import io.reactivex.Scheduler;
56 import io.reactivex.Single;
57 import io.reactivex.SingleSource;
58 import io.reactivex.android.schedulers.AndroidSchedulers;
59 import io.reactivex.disposables.Disposable;
60 import io.reactivex.functions.Action;
61 import io.reactivex.functions.BiFunction;
62 import io.reactivex.functions.Consumer;
63 import io.reactivex.functions.Function;
64 import io.reactivex.functions.Predicate;
65 import io.reactivex.schedulers.Timed;
66 import polar.com.sdk.api.PolarBleApi;
84 import protocol.PftpNotification;
85 import protocol.PftpRequest;
86 import protocol.PftpResponse;
87 
91 public class BDBleApiImpl extends PolarBleApi {
92  private final static String TAG = BDBleApiImpl.class.getSimpleName();
93  private BleDeviceListener listener;
94  private Map<String,Disposable> connectSubscriptions = new HashMap<>();
95  private Scheduler scheduler;
98  private static final int ANDROID_VERSION_O = 26;
99 
100  @SuppressLint({"NewApi", "CheckResult"})
101  public BDBleApiImpl(final Context context, int features) {
102  super(features);
103  Set<Class<? extends BleGattBase>> clients = new HashSet<>();
104  if((this.features & PolarBleApi.FEATURE_HR)!=0){
105  clients.add(BleHrClient.class);
106  }
107  if((this.features & PolarBleApi.FEATURE_DEVICE_INFO)!=0){
108  clients.add(BleDisClient.class);
109  }
110  if((this.features & PolarBleApi.FEATURE_BATTERY_INFO)!=0){
111  clients.add(BleBattClient.class);
112  }
113  if((this.features & PolarBleApi.FEATURE_POLAR_SENSOR_STREAMING)!=0){
114  clients.add(BlePMDClient.class);
115  }
116  if((this.features & PolarBleApi.FEATURE_POLAR_FILE_TRANSFER)!=0){
117  clients.add(BlePsFtpClient.class);
118  }
119  listener = new BDDeviceListenerImpl(context, clients);
120  BleDeviceListener.BleSearchPreFilter filter = new BleDeviceListener.BleSearchPreFilter() {
121  @Override
122  public boolean process(BleAdvertisementContent content) {
123  return content.getPolarDeviceId().length() != 0 && !content.getPolarDeviceType().equals("mobile");
124  }
125  };
126  listener.setScanPreFilter(filter);
127  scheduler = AndroidSchedulers.from(context.getMainLooper());
128  listener.monitorDeviceSessionState(null).observeOn(scheduler).subscribe(
129  new Consumer<Pair<BleDeviceSession, BleDeviceSession.DeviceSessionState>>() {
130  @Override
131  public void accept(Pair<BleDeviceSession, BleDeviceSession.DeviceSessionState> pair) throws Exception {
132  PolarDeviceInfo info = new PolarDeviceInfo(pair.first.getPolarDeviceId(),
133  pair.first.getRssi(),pair.first.getName(),true);
134  switch (pair.second){
135  case SESSION_OPEN:
136  if(callback!=null){
138  }
139  setupDevice(pair.first);
140  break;
141  case SESSION_CLOSED:
142  if( callback != null ) {
143  if (pair.first.getPreviousState() == BleDeviceSession.DeviceSessionState.SESSION_OPEN ||
144  pair.first.getPreviousState() == BleDeviceSession.DeviceSessionState.SESSION_CLOSING){
146  }
147  }
148  break;
149  case SESSION_OPENING:
150  if(callback != null){
152  }
153  break;
154  }
155  }
156  },
157  new Consumer<Throwable>() {
158  @Override
159  public void accept(Throwable throwable) throws Exception {
160  logError(throwable.getMessage());
161  }
162  },
163  new Action() {
164  @Override
165  public void run() throws Exception {
166 
167  }
168  }
169  );
170  listener.monitorBleState().observeOn(scheduler).subscribe(
171  new Consumer<Boolean>() {
172  @Override
173  public void accept(Boolean aBoolean) throws Exception {
174  if(callback != null){
175  callback.blePowerStateChanged(aBoolean);
176  }
177  }
178  },
179  new Consumer<Throwable>() {
180  @Override
181  public void accept(Throwable throwable) throws Exception {
182  logError(throwable.getMessage());
183  }
184  },
185  new Action() {
186  @Override
187  public void run() throws Exception {
188 
189  }
190  }
191  );
192  BleLogger.setLoggerInterface(new BleLogger.BleLoggerInterface() {
193  @Override
194  public void d(String tag, String msg) {
195  log(tag+"/"+msg);
196  }
197 
198  @Override
199  public void e(String tag, String msg) {
200  logError(tag+"/"+msg);
201  }
202 
203  @Override
204  public void w(String tag, String msg) {
205  }
206 
207  @Override
208  public void i(String tag, String msg) {
209  }
210  });
211  }
212 
213  @SuppressLint("NewApi")
214  private void enableAndroidScanFilter() {
215  if (Build.VERSION.SDK_INT >= ANDROID_VERSION_O) {
216  List<ScanFilter> filter = new ArrayList<>();
217  filter.add(new ScanFilter.Builder().setServiceUuid(
218  ParcelUuid.fromString(BleHrClient.HR_SERVICE.toString())).build());
219  filter.add(new ScanFilter.Builder().setServiceUuid(
220  ParcelUuid.fromString(BlePsFtpUtils.RFC77_PFTP_SERVICE.toString())).build());
221  listener.setScanFilters(filter);
222  }
223  }
224 
225  @Override
226  public void shutDown() {
227  listener.shutDown();
228  }
229 
230  @Override
231  public void cleanup() {
232  listener.removeAllSessions();
233  }
234 
235  @Override
236  public boolean isFeatureReady(final String deviceId, int feature) {
237  try {
238  switch (feature) {
240  return sessionPsFtpClientReady(deviceId) != null;
242  return sessionPmdClientReady(deviceId) != null;
243  }
244  } catch (Throwable ignored) {
245  }
246  return false;
247  }
248 
249  @Override
251  this.callback = callback;
253  }
254 
255  @Override
256  public void setApiLogger(@Nullable PolarBleApiLogger logger) {
257  this.logger = logger;
258  }
259 
260  @Override
261  public void setAutomaticReconnection(boolean disable) {
262  listener.setAutomaticReconnection(disable);
263  }
264 
265  @Override
266  public Completable setLocalTime(String identifier, Date local) {
267  try {
268  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
269  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
270  PftpRequest.PbPFtpSetLocalTimeParams.Builder builder = PftpRequest.PbPFtpSetLocalTimeParams.newBuilder();
271  Calendar cal = Calendar.getInstance();
272  cal.setTime(local);
273  Types.PbDate date = Types.PbDate.newBuilder()
274  .setYear(cal.get(Calendar.YEAR))
275  .setMonth(cal.get(Calendar.MONTH) + 1)
276  .setDay(cal.get(Calendar.DAY_OF_MONTH)).build();
277  Types.PbTime time = Types.PbTime.newBuilder()
278  .setHour(cal.get(Calendar.HOUR_OF_DAY))
279  .setMinute(cal.get(Calendar.MINUTE))
280  .setSeconds(cal.get(Calendar.SECOND))
281  .setMillis(cal.get(Calendar.MILLISECOND)).build();
282  builder.setDate(date).setTime(time).setTzOffset(cal.get(Calendar.ZONE_OFFSET));
283  return client.query(PftpRequest.PbPFtpQuery.SET_LOCAL_TIME_VALUE,builder.build().toByteArray()).toObservable().ignoreElements();
284  } catch (Throwable error){
285  return Completable.error(error);
286  }
287  }
288 
289  @Override
290  public Single<PolarSensorSetting> requestAccSettings(String identifier) {
291  return querySettings(identifier,BlePMDClient.PmdMeasurementType.ACC);
292  }
293 
294  @Override
295  public Single<PolarSensorSetting> requestEcgSettings(String identifier) {
296  return querySettings(identifier,BlePMDClient.PmdMeasurementType.ECG);
297  }
298 
299  @Override
300  public Single<PolarSensorSetting> requestPpgSettings(String identifier) {
301  return querySettings(identifier,BlePMDClient.PmdMeasurementType.PPG);
302  }
303 
304  @Override
305  public Single<PolarSensorSetting> requestBiozSettings(final String identifier){
306  return querySettings(identifier,BlePMDClient.PmdMeasurementType.BIOZ);
307  }
308 
309  private Single<PolarSensorSetting> querySettings(final String identifier, final BlePMDClient.PmdMeasurementType type) {
310  try {
311  final BleDeviceSession session = sessionPmdClientReady(identifier);
312  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
313  return client.querySettings(type).map(new Function<BlePMDClient.PmdSetting, PolarSensorSetting>() {
314  @Override
315  public PolarSensorSetting apply(BlePMDClient.PmdSetting setting) throws Exception {
316  return new PolarSensorSetting(setting.settings, type);
317  }
318  });
319  } catch (Throwable e){
320  return Single.error(e);
321  }
322  }
323 
324  @Override
325  public void backgroundEntered() {
327  }
328 
329  @Override
330  public void foregroundEntered() {
331  listener.setScanFilters(null);
332  }
333 
334  @Override
335  public Completable autoConnectToPolarDevice(final int rssiLimit, final int timeout, final TimeUnit unit, final String polarDeviceType) {
336  final long[] start = {0};
337  return listener.search(false).filter(new Predicate<BleDeviceSession>() {
338  @Override
339  public boolean test(BleDeviceSession bleDeviceSession) throws Exception {
340  if( bleDeviceSession.getMedianRssi() >= rssiLimit &&
341  bleDeviceSession.getPolarDeviceId().length() != 0 &&
342  bleDeviceSession.isConnectableAdvertisement() &&
343  (polarDeviceType == null || polarDeviceType.equals(bleDeviceSession.getPolarDeviceType())) ) {
344  if(start[0] == 0){
345  start[0] = System.currentTimeMillis();
346  }
347  return true;
348  }
349  return false;
350  }
351  }).timestamp().takeUntil(new Predicate<Timed<BleDeviceSession>>() {
352  @Override
353  public boolean test(Timed<BleDeviceSession> bleDeviceSessionTimed) throws Exception {
354  long diff = bleDeviceSessionTimed.time(TimeUnit.MILLISECONDS) - start[0];
355  return (diff >= unit.toMillis(timeout));
356  }
357  }).reduce(new HashSet<BleDeviceSession>(), new BiFunction<Set<BleDeviceSession>, Timed<BleDeviceSession>, Set<BleDeviceSession>>() {
358  @Override
359  public Set<BleDeviceSession> apply(Set<BleDeviceSession> objects, Timed<BleDeviceSession> bleDeviceSessionTimed) throws Exception {
360  objects.add(bleDeviceSessionTimed.value());
361  return objects;
362  }
363  }).doOnSuccess(new Consumer<Set<BleDeviceSession>>() {
364  @Override
365  public void accept(Set<BleDeviceSession> set) throws Exception {
366  List<BleDeviceSession> list = new ArrayList<>(set);
367  Collections.sort(list, new Comparator<BleDeviceSession>() {
368  @Override
369  public int compare(BleDeviceSession o1, BleDeviceSession o2) {
370  return o1.getRssi() > o2.getRssi() ? -1 : 1;
371  }
372  });
373  listener.openSessionDirect(list.get(0));
374  log("auto connect search complete");
375  }
376  }).toObservable().ignoreElements();
377  }
378 
379  @Override
380  public Completable autoConnectToPolarDevice(final int rssiLimit, final String polarDeviceType) {
381  return autoConnectToPolarDevice(rssiLimit, 2, TimeUnit.SECONDS, polarDeviceType);
382  }
383 
384  @Override
385  public void connectToPolarDevice(final String identifier) {
386  BleDeviceSession session = sessionByDeviceId(identifier);
387  if( session == null || session.getSessionState() == BleDeviceSession.DeviceSessionState.SESSION_CLOSED ){
388  if( connectSubscriptions.containsKey(identifier) ){
389  connectSubscriptions.get(identifier).dispose();
390  }
391  connectSubscriptions.put(identifier,listener.search(false).filter(new Predicate<BleDeviceSession>() {
392  @Override
393  public boolean test(BleDeviceSession bleDeviceSession) throws Exception {
394  return bleDeviceSession.getPolarDeviceId().equals(identifier);
395  }
396  }).take(1).observeOn(scheduler).subscribe(
397  new Consumer<BleDeviceSession>() {
398  @Override
399  public void accept(BleDeviceSession bleDeviceSession) throws Exception {
400  listener.openSessionDirect(bleDeviceSession);
401  }
402  },
403  new Consumer<Throwable>() {
404  @Override
405  public void accept(Throwable throwable) throws Exception {
406  logError(throwable.getMessage());
407  }
408  },
409  new Action() {
410  @Override
411  public void run() throws Exception {
412  log("connect search complete");
413  }
414  }
415  ));
416  }
417  }
418 
419  @Override
420  public void disconnectFromPolarDevice(String identifier) {
421  BleDeviceSession session = sessionByDeviceId(identifier);
422  if( session != null ){
423  if( session.getSessionState() == BleDeviceSession.DeviceSessionState.SESSION_OPEN ||
424  session.getSessionState() == BleDeviceSession.DeviceSessionState.SESSION_OPENING ||
425  session.getSessionState() == BleDeviceSession.DeviceSessionState.SESSION_OPEN_PARK ) {
426  listener.closeSessionDirect(session);
427  }
428  }
429  if (connectSubscriptions.containsKey(identifier)){
430  connectSubscriptions.get(identifier).dispose();
431  connectSubscriptions.remove(identifier);
432  }
433  }
434 
435  @Override
436  public Completable startRecording(String identifier, String exerciseId, RecordingInterval interval, SampleType type) {
437  try {
438  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
439  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
440  if(session.getPolarDeviceType().equals("H10")) {
441  Types.PbSampleType t = type == SampleType.HR ?
442  Types.PbSampleType.SAMPLE_TYPE_HEART_RATE :
443  Types.PbSampleType.SAMPLE_TYPE_RR_INTERVAL;
444  Types.PbDuration duration = Types.PbDuration.newBuilder().setSeconds(interval.getValue()).build();
445  PftpRequest.PbPFtpRequestStartRecordingParams params = PftpRequest.PbPFtpRequestStartRecordingParams.newBuilder().
446  setSampleDataIdentifier(exerciseId).setSampleType(t).setRecordingInterval(duration).build();
447  return client.query(PftpRequest.PbPFtpQuery.REQUEST_START_RECORDING_VALUE, params.toByteArray()).toObservable().ignoreElements().onErrorResumeNext(new Function<Throwable, CompletableSource>() {
448  @Override
449  public CompletableSource apply(Throwable throwable) throws Exception {
450  return Completable.error(throwable);
451  }
452  });
453  }
454  return Completable.error(new PolarOperationNotSupported());
455  } catch (Throwable error){
456  return Completable.error(error);
457  }
458  }
459 
460  @Override
461  public Completable stopRecording(String identifier) {
462  try {
463  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
464  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
465  if(session.getPolarDeviceType().equals("H10")) {
466  return client.query(PftpRequest.PbPFtpQuery.REQUEST_STOP_RECORDING_VALUE, null).toObservable().ignoreElements().onErrorResumeNext(new Function<Throwable, CompletableSource>() {
467  @Override
468  public CompletableSource apply(Throwable throwable) throws Exception {
469  return Completable.error(handleError(throwable));
470  }
471  });
472  }
473  return Completable.error(new PolarOperationNotSupported());
474  } catch (Throwable error){
475  return Completable.error(error);
476  }
477  }
478 
479  @Override
480  public Single<Pair<Boolean,String>> requestRecordingStatus(String identifier) {
481  try {
482  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
483  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
484  if(session.getPolarDeviceType().equals("H10")) {
485  return client.query(PftpRequest.PbPFtpQuery.REQUEST_RECORDING_STATUS_VALUE, null).map(new Function<ByteArrayOutputStream, Pair<Boolean,String>>() {
486  @Override
487  public Pair<Boolean,String> apply(ByteArrayOutputStream byteArrayOutputStream) throws Exception {
488  PftpResponse.PbRequestRecordingStatusResult result = PftpResponse.PbRequestRecordingStatusResult.parseFrom(byteArrayOutputStream.toByteArray());
489  return new Pair<>(result.getRecordingOn(),result.hasSampleDataIdentifier() ? result.getSampleDataIdentifier() : "");
490  }
491  }).onErrorResumeNext(new Function<Throwable, SingleSource<? extends Pair<Boolean, String>>>() {
492  @Override
493  public SingleSource<? extends Pair<Boolean, String>> apply(Throwable throwable) throws Exception {
494  return Single.error(handleError(throwable));
495  }
496  });
497  }
498  return Single.error(new PolarOperationNotSupported());
499  } catch (Throwable error){
500  return Single.error(error);
501  }
502  }
503 
504  @Override
505  public Flowable<PolarExerciseEntry> listExercises(String identifier) {
506  try{
507  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
508  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
509  switch (session.getPolarDeviceType()) {
510  case "OH1":
511  return fetchRecursively(client, "/U/0/", new FetchRecursiveCondition() {
512  @Override
513  public boolean include(String entry) {
514  return entry.matches("^([0-9]{8})(\\/)") ||
515  entry.matches("^([0-9]{6})(\\/)") ||
516  entry.equals("E/") ||
517  entry.equals("SAMPLES.BPB") ||
518  entry.equals("00/");
519  }
520  }).map(new Function<String, PolarExerciseEntry>() {
521  @Override
522  public PolarExerciseEntry apply(String p) throws Exception {
523  String components[] = p.split("/");
524  SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd HHmmss", Locale.getDefault());
525  Date date = format.parse(components[3] + " " + components[5]);
526  return new PolarExerciseEntry(p, date, components[3] + components[5]);
527  }
528  }).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarExerciseEntry>>() {
529  @Override
530  public Publisher<? extends PolarExerciseEntry> apply(Throwable throwable) throws Exception {
531  return Flowable.error(handleError(throwable));
532  }
533  });
534  case "H10":
535  return fetchRecursively(client, "/", new FetchRecursiveCondition() {
536  @Override
537  public boolean include(String entry) {
538  return entry.endsWith("/") || entry.equals("SAMPLES.BPB");
539  }
540  }).map(new Function<String, PolarExerciseEntry>() {
541  @Override
542  public PolarExerciseEntry apply(String p) throws Exception {
543  String components[] = p.split("/");
544  return new PolarExerciseEntry(p, new Date(), components[1]);
545  }
546  }).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarExerciseEntry>>() {
547  @Override
548  public Publisher<? extends PolarExerciseEntry> apply(Throwable throwable) throws Exception {
549  return Flowable.error(handleError(throwable));
550  }
551  });
552  default:
553  return Flowable.error(new PolarOperationNotSupported());
554  }
555  } catch (Throwable error){
556  return Flowable.error(error);
557  }
558  }
559 
560  @Override
561  public Single<PolarExerciseData> fetchExercise(String identifier, PolarExerciseEntry entry) {
562  try{
563  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
564  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
565  protocol.PftpRequest.PbPFtpOperation.Builder builder = protocol.PftpRequest.PbPFtpOperation.newBuilder();
566  builder.setCommand(PftpRequest.PbPFtpOperation.Command.GET);
567  builder.setPath(entry.path);
568  if(session.getPolarDeviceType().equals("OH1") || session.getPolarDeviceType().equals("H10")) {
569  return client.request(builder.build().toByteArray()).map(new Function<ByteArrayOutputStream, PolarExerciseData>() {
570  @Override
571  public PolarExerciseData apply(ByteArrayOutputStream byteArrayOutputStream) throws Exception {
572  ExerciseSamples.PbExerciseSamples samples = ExerciseSamples.PbExerciseSamples.parseFrom(byteArrayOutputStream.toByteArray());
573  return new PolarExerciseData(samples.getRecordingInterval().getSeconds(), samples.getHeartRateSamplesList());
574  }
575  }).onErrorResumeNext(new Function<Throwable, SingleSource<? extends PolarExerciseData>>() {
576  @Override
577  public SingleSource<? extends PolarExerciseData> apply(Throwable throwable) throws Exception {
578  return Single.error(handleError(throwable));
579  }
580  });
581  }
582  return Single.error(new PolarOperationNotSupported());
583  } catch (Throwable error){
584  return Single.error(error);
585  }
586  }
587 
588  @Override
589  public Completable removeExercise(String identifier, PolarExerciseEntry entry) {
590  try{
591  final BleDeviceSession session = sessionPsFtpClientReady(identifier);
592  final BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
593  if(session.getPolarDeviceType().equals("OH1")){
594  protocol.PftpRequest.PbPFtpOperation.Builder builder = protocol.PftpRequest.PbPFtpOperation.newBuilder();
595  builder.setCommand(PftpRequest.PbPFtpOperation.Command.GET);
596  final String components[] = entry.path.split("/");
597  final String exerciseParent = "/U/0/" + components[3] + "/E/";
598  builder.setPath(exerciseParent);
599  return client.request(builder.build().toByteArray()).flatMap(new Function<ByteArrayOutputStream, SingleSource<?>>() {
600  @Override
601  public SingleSource<?> apply(ByteArrayOutputStream byteArrayOutputStream) throws Exception {
602  PftpResponse.PbPFtpDirectory directory = PftpResponse.PbPFtpDirectory.parseFrom(byteArrayOutputStream.toByteArray());
603  protocol.PftpRequest.PbPFtpOperation.Builder removeBuilder = protocol.PftpRequest.PbPFtpOperation.newBuilder();
604  removeBuilder.setCommand(PftpRequest.PbPFtpOperation.Command.REMOVE);
605  if( directory.getEntriesCount() <= 1 ){
606  // remove entire directory
607  removeBuilder.setPath("/U/0/" + components[3] + "/");
608  } else {
609  // remove only exercise
610  removeBuilder.setPath("/U/0/" + components[3] + "/E/" + components[5] + "/");
611  }
612  return client.request(removeBuilder.build().toByteArray());
613  }
614  }).toObservable().ignoreElements().onErrorResumeNext(new Function<Throwable, CompletableSource>() {
615  @Override
616  public CompletableSource apply(Throwable throwable) throws Exception {
617  return Completable.error(handleError(throwable));
618  }
619  });
620  } else if(session.getPolarDeviceType().equals("H10")){
621  protocol.PftpRequest.PbPFtpOperation.Builder builder = protocol.PftpRequest.PbPFtpOperation.newBuilder();
622  builder.setCommand(PftpRequest.PbPFtpOperation.Command.REMOVE);
623  builder.setPath(entry.path);
624  return client.request(builder.build().toByteArray()).toObservable().ignoreElements().onErrorResumeNext(new Function<Throwable, CompletableSource>() {
625  @Override
626  public CompletableSource apply(Throwable throwable) throws Exception {
627  return Completable.error(handleError(throwable));
628  }
629  });
630  }
631  return Completable.error(new PolarOperationNotSupported());
632  } catch (Throwable error){
633  return Completable.error(error);
634  }
635  }
636 
637  @Override
638  public Flowable<PolarDeviceInfo> searchForPolarDevice() {
639  return listener.search(false).filter(new Predicate<BleDeviceSession>() {
640  @Override
641  public boolean test(BleDeviceSession bleDeviceSession) throws Exception {
642  return bleDeviceSession.getAdvertisementContent().getPolarDeviceId().length() != 0;
643  }
644  }).distinct().map(new Function<BleDeviceSession, PolarDeviceInfo>() {
645  @Override
646  public PolarDeviceInfo apply(BleDeviceSession bleDeviceSession) throws Exception {
647  return new PolarDeviceInfo(bleDeviceSession.getPolarDeviceId(),bleDeviceSession.getRssi(),bleDeviceSession.getName(), bleDeviceSession.isConnectableAdvertisement());
648  }
649  });
650  }
651 
652  @Override
653  public Flowable<PolarHrBroadcastData> startListenForPolarHrBroadcasts(final Set<String> deviceIds) {
654  // set filter to null, NOTE this disables reconnection in background
655  return listener.search(false).filter(new Predicate<BleDeviceSession>() {
656  @Override
657  public boolean test(BleDeviceSession bleDeviceSession) throws Exception {
658  return (deviceIds == null || deviceIds.contains(bleDeviceSession.getPolarDeviceId())) &&
659  bleDeviceSession.getAdvertisementContent().getPolarHrAdvertisement().isPresent();
660  }
661  }).map(new Function<BleDeviceSession, PolarHrBroadcastData>() {
662  @Override
663  public PolarHrBroadcastData apply(BleDeviceSession bleDeviceSession) throws Exception {
664  BlePolarHrAdvertisement advertisement = bleDeviceSession.getBlePolarHrAdvertisement();
665  return new PolarHrBroadcastData( new PolarDeviceInfo(bleDeviceSession.getPolarDeviceId(),
666  bleDeviceSession.getRssi(), bleDeviceSession.getName(), bleDeviceSession.isConnectableAdvertisement()),
667  advertisement.getHrForDisplay(), advertisement.getBatteryStatus() != 0);
668  }
669  });
670  }
671 
672  @Override
673  public Flowable<PolarEcgData> startEcgStreaming(String identifier,
674  PolarSensorSetting setting) {
675  try {
676  final BleDeviceSession session = sessionPmdClientReady(identifier);
677  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
678  return client.startMeasurement(BlePMDClient.PmdMeasurementType.ECG, setting.map2PmdSettings()).andThen(
679  client.monitorEcgNotifications(true).map(new Function<BlePMDClient.EcgData, PolarEcgData>() {
680  @Override
681  public PolarEcgData apply(BlePMDClient.EcgData ecgData) throws Exception {
682  List<Integer> samples = new ArrayList<>();
683  for( BlePMDClient.EcgData.EcgSample s : ecgData.ecgSamples ){
684  samples.add(s.microVolts);
685  }
686  return new PolarEcgData(samples,ecgData.timeStamp);
687  }
688  }).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarEcgData>>() {
689  @Override
690  public Publisher<? extends PolarEcgData> apply(Throwable throwable) throws Exception {
691  return Flowable.error(handleError(throwable));
692  }
693  }).doFinally(new Action() {
694  @Override
695  public void run() throws Exception {
696  stopPmdStreaming(session,client, BlePMDClient.PmdMeasurementType.ECG);
697  }
698  }));
699  } catch (Throwable t){
700  return Flowable.error(t);
701  }
702  }
703 
704  @Override
705  public Flowable<PolarAccelerometerData> startAccStreaming(String identifier,
706  PolarSensorSetting setting) {
707  try {
708  final BleDeviceSession session = sessionPmdClientReady(identifier);
709  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
710  return client.startMeasurement(BlePMDClient.PmdMeasurementType.ACC, setting.map2PmdSettings()).andThen(
711  client.monitorAccNotifications(true).map(new Function<BlePMDClient.AccData, PolarAccelerometerData>() {
712  @Override
713  public PolarAccelerometerData apply(BlePMDClient.AccData accData) throws Exception {
714  List<PolarAccelerometerData.PolarAccelerometerSample> samples = new ArrayList<>();
715  for( BlePMDClient.AccData.AccSample s : accData.accSamples ){
716  samples.add(new PolarAccelerometerData.PolarAccelerometerSample(s.x,s.y,s.z));
717  }
718  return new PolarAccelerometerData(samples,accData.timeStamp);
719  }
720  }).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarAccelerometerData>>() {
721  @Override
722  public Publisher<? extends PolarAccelerometerData> apply(Throwable throwable) throws Exception {
723  return Flowable.error(handleError(throwable));
724  }
725  }).doFinally(new Action() {
726  @Override
727  public void run() throws Exception {
728  stopPmdStreaming(session,client, BlePMDClient.PmdMeasurementType.ACC);
729  }
730  }));
731  } catch (Throwable t){
732  return Flowable.error(t);
733  }
734  }
735 
736  @Override
737  public Flowable<PolarOhrPPGData> startOhrPPGStreaming(String identifier,
738  PolarSensorSetting setting) {
739  try {
740  final BleDeviceSession session = sessionPmdClientReady(identifier);
741  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
742  return client.startMeasurement(BlePMDClient.PmdMeasurementType.PPG, setting.map2PmdSettings()).andThen(
743  client.monitorPpgNotifications(true).map(new Function<BlePMDClient.PpgData, PolarOhrPPGData>() {
744  @Override
745  public PolarOhrPPGData apply(BlePMDClient.PpgData ppgData) throws Exception {
746  List<PolarOhrPPGData.PolarOhrPPGSample> samples = new ArrayList<>();
747  for( BlePMDClient.PpgData.PpgSample s : ppgData.ppgSamples ){
748  samples.add(new PolarOhrPPGData.PolarOhrPPGSample(s.ppg0,s.ppg1,s.ppg2,s.ambient));
749  }
750  return new PolarOhrPPGData(samples,ppgData.timeStamp);
751  }
752  }).doFinally(new Action() {
753  @Override
754  public void run() throws Exception {
755  stopPmdStreaming(session,client, BlePMDClient.PmdMeasurementType.PPG);
756  }
757  })).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarOhrPPGData>>() {
758  @Override
759  public Publisher<? extends PolarOhrPPGData> apply(Throwable throwable) throws Exception {
760  return Flowable.error(handleError(throwable));
761  }
762  });
763  } catch (Throwable t){
764  return Flowable.error(t);
765  }
766  }
767 
768  @Override
769  public Flowable<PolarOhrPPIData> startOhrPPIStreaming(String identifier) {
770  try {
771  final BleDeviceSession session = sessionPmdClientReady(identifier);
772  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
773  return client.startMeasurement(BlePMDClient.PmdMeasurementType.PPI, new BlePMDClient.PmdSetting(new HashMap<BlePMDClient.PmdSetting.PmdSettingType, Integer>())).andThen(
774  client.monitorPpiNotifications(true).map(new Function<BlePMDClient.PpiData, PolarOhrPPIData>() {
775  @Override
776  public PolarOhrPPIData apply(BlePMDClient.PpiData ppiData) throws Exception {
777  List<PolarOhrPPIData.PolarOhrPPISample> samples = new ArrayList<>();
778  for(BlePMDClient.PpiData.PPSample ppSample : ppiData.ppSamples){
779  samples.add(new PolarOhrPPIData.PolarOhrPPISample(ppSample.ppInMs,
780  ppSample.ppErrorEstimate,
781  ppSample.hr,
782  ppSample.blockerBit != 0,
783  ppSample.skinContactStatus != 0,
784  ppSample.skinContactSupported != 0));
785  }
786  return new PolarOhrPPIData(ppiData.timestamp,samples);
787  }
788  }).doFinally(new Action() {
789  @Override
790  public void run() throws Exception {
791  stopPmdStreaming(session,client, BlePMDClient.PmdMeasurementType.PPI);
792  }
793  })).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarOhrPPIData>>() {
794  @Override
795  public Publisher<? extends PolarOhrPPIData> apply(Throwable throwable) throws Exception {
796  return Flowable.error(handleError(throwable));
797  }
798  });
799  } catch (Throwable t){
800  return Flowable.error(t);
801  }
802  }
803 
804  @Override
805  public Flowable<PolarBiozData> startBiozStreaming(final String identifier, PolarSensorSetting setting){
806  try {
807  final BleDeviceSession session = sessionPmdClientReady(identifier);
808  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
809  return client.startMeasurement(BlePMDClient.PmdMeasurementType.BIOZ, setting.map2PmdSettings()).andThen(
810  client.monitorBiozNotifications(true).map(new Function<BlePMDClient.BiozData, PolarBiozData>() {
811  @Override
812  public PolarBiozData apply(BlePMDClient.BiozData biozData) throws Exception {
813  return new PolarBiozData(biozData.timeStamp,biozData.samples);
814  }
815  }).doFinally(new Action() {
816  @Override
817  public void run() throws Exception {
818  stopPmdStreaming(session,client, BlePMDClient.PmdMeasurementType.PPG);
819  }
820  })).onErrorResumeNext(new Function<Throwable, Publisher<? extends PolarBiozData>>() {
821  @Override
822  public Publisher<? extends PolarBiozData> apply(Throwable throwable) throws Exception {
823  return Flowable.error(handleError(throwable));
824  }
825  });
826  } catch (Throwable t){
827  return Flowable.error(t);
828  }
829  }
830 
831  private BleDeviceSession sessionByDeviceId(final String deviceId) {
832  for ( BleDeviceSession session : listener.deviceSessions() ){
833  if( session.getAdvertisementContent().getPolarDeviceId().equals(deviceId) ){
834  return session;
835  }
836  }
837  return null;
838  }
839 
840  private BleDeviceSession sessionServiceReady(final String identifier, UUID service) throws Throwable {
841  BleDeviceSession session = sessionByDeviceId(identifier);
842  if(session != null){
843  if(session.getSessionState() == BleDeviceSession.DeviceSessionState.SESSION_OPEN) {
844  BleGattBase client = session.fetchClient(service);
845  if (client.isServiceDiscovered()) {
846  return session;
847  }
848  throw new PolarServiceNotAvailable();
849  }
850  throw new PolarDeviceDisconnected();
851  }
852  throw new PolarDeviceNotFound();
853  }
854 
855  public BleDeviceSession sessionPmdClientReady(final String identifier) throws Throwable {
856  BleDeviceSession session = sessionServiceReady(identifier, BlePMDClient.PMD_SERVICE);
857  BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
858  final AtomicInteger pair = client.getNotificationAtomicInteger(BlePMDClient.PMD_CP);
859  final AtomicInteger pairData = client.getNotificationAtomicInteger(BlePMDClient.PMD_DATA);
860  if (pair != null && pairData != null &&
861  pair.get() == BleGattBase.ATT_SUCCESS &&
862  pairData.get() == BleGattBase.ATT_SUCCESS) {
863  return session;
864  }
865  throw new PolarNotificationNotEnabled();
866  }
867 
868  private BleDeviceSession sessionPsFtpClientReady(final String identifier) throws Throwable {
869  BleDeviceSession session = sessionServiceReady(identifier, BlePsFtpUtils.RFC77_PFTP_SERVICE);
870  BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
871  final AtomicInteger pair = client.getNotificationAtomicInteger(BlePsFtpUtils.RFC77_PFTP_MTU_CHARACTERISTIC);
872  if (pair != null && pair.get() == BleGattBase.ATT_SUCCESS ) {
873  return session;
874  }
875  throw new PolarNotificationNotEnabled();
876  }
877 
878  @SuppressLint("CheckResult")
879  private void stopPmdStreaming(BleDeviceSession session, BlePMDClient client, BlePMDClient.PmdMeasurementType type) {
880  if( session.getSessionState() == BleDeviceSession.DeviceSessionState.SESSION_OPEN ){
881  // stop streaming
882  client.stopMeasurement(type).subscribe(
883  new Action() {
884  @Override
885  public void run() throws Exception {
886 
887  }
888  },
889  new Consumer<Throwable>() {
890  @Override
891  public void accept(Throwable throwable) throws Exception {
892  logError("failed to stop pmd stream: " + throwable.getLocalizedMessage());
893  }
894  }
895  );
896  }
897  }
898 
899  @SuppressLint("CheckResult")
900  private void setupDevice(final BleDeviceSession session){
901  final String deviceId = session.getPolarDeviceId();
902  session.monitorServicesDiscovered(true).observeOn(scheduler).toFlowable().flatMapIterable(
903  new Function<List<UUID>, Iterable<UUID>>() {
904  @Override
905  public Iterable<UUID> apply(List<UUID> uuids) throws Exception {
906  return uuids;
907  }
908  }
909  ).flatMap(new Function<UUID, Publisher<?>>() {
910  @Override
911  public Publisher<?> apply(UUID uuid) throws Exception {
912  if(session.fetchClient(uuid) != null) {
913  if (uuid.equals(BleHrClient.HR_SERVICE)) {
914  if (callback != null) {
915  callback.hrFeatureReady(deviceId);
916  }
917  final BleHrClient client = (BleHrClient) session.fetchClient(BleHrClient.HR_SERVICE);
918  client.observeHrNotifications(true).observeOn(scheduler).subscribe(
919  new Consumer<BleHrClient.HrNotificationData>() {
920  @Override
921  public void accept(BleHrClient.HrNotificationData hrNotificationData) throws Exception {
922  if (callback != null) {
924  new PolarHrData(hrNotificationData.hrValue,
925  hrNotificationData.rrs,
926  hrNotificationData.sensorContact,
927  hrNotificationData.sensorContactSupported,
928  hrNotificationData.rrPresent));
929  }
930  }
931  },
932  new Consumer<Throwable>() {
933  @Override
934  public void accept(Throwable throwable) throws Exception {
935  logError(throwable.getMessage());
936  }
937  },
938  new Action() {
939  @Override
940  public void run() throws Exception {
941 
942  }
943  }
944  );
945  } else if (uuid.equals(BleBattClient.BATTERY_SERVICE)) {
946  BleBattClient client = (BleBattClient) session.fetchClient(BleBattClient.BATTERY_SERVICE);
947  return client.waitBatteryLevelUpdate(true).observeOn(scheduler).doOnSuccess(new Consumer<Integer>() {
948  @Override
949  public void accept(Integer integer) throws Exception {
950  if (callback != null) {
951  callback.batteryLevelReceived(deviceId, integer);
952  }
953  }
954  }).toFlowable();
955  } else if (uuid.equals(BlePMDClient.PMD_SERVICE)) {
956  final BlePMDClient client = (BlePMDClient) session.fetchClient(BlePMDClient.PMD_SERVICE);
957  return client.waitNotificationEnabled(BlePMDClient.PMD_CP, true).
958  concatWith(client.waitNotificationEnabled(BlePMDClient.PMD_DATA, true)).andThen(client.readFeature(true).doOnSuccess(new Consumer<BlePMDClient.PmdFeature>() {
959  @Override
960  public void accept(BlePMDClient.PmdFeature pmdFeature) {
961  if (callback != null) {
962  if (pmdFeature.ecgSupported) {
963  callback.ecgFeatureReady(deviceId);
964  }
965  if (pmdFeature.accSupported) {
967  }
968  if (pmdFeature.ppgSupported) {
969  callback.ppgFeatureReady(deviceId);
970  }
971  if (pmdFeature.ppiSupported) {
972  callback.ppiFeatureReady(deviceId);
973  }
974  if (pmdFeature.bioZSupported) {
975  callback.biozFeatureReady(deviceId);
976  }
977  }
978  }
979  })).toFlowable();
980  } else if (uuid.equals(BleDisClient.DIS_SERVICE)) {
981  BleDisClient client = (BleDisClient) session.fetchClient(BleDisClient.DIS_SERVICE);
982  return client.observeDisInfo(true).takeUntil(new Predicate<HashMap<UUID, String>>() {
983  @Override
984  public boolean test(HashMap<UUID, String> map) throws Exception {
985  return map.containsKey(BleDisClient.SOFTWARE_REVISION_STRING);
986  }
987  }).observeOn(scheduler).doOnNext(new Consumer<HashMap<UUID, String>>() {
988  @Override
989  public void accept(HashMap<UUID, String> uuidStringHashMap) throws Exception {
990  if (callback != null && uuidStringHashMap.containsKey(BleDisClient.SOFTWARE_REVISION_STRING)) {
991  callback.fwInformationReceived(deviceId, uuidStringHashMap.get(BleDisClient.SOFTWARE_REVISION_STRING));
992  }
993  }
994  });
995  } else if (uuid.equals(BlePsFtpUtils.RFC77_PFTP_SERVICE)) {
996  BlePsFtpClient client = (BlePsFtpClient) session.fetchClient(BlePsFtpUtils.RFC77_PFTP_SERVICE);
997  return client.waitPsFtpClientReady(true).observeOn(scheduler).doOnComplete(new Action() {
998  @Override
999  public void run() throws Exception {
1000  if (callback != null &&
1001  (session.getPolarDeviceType().equals("OH1") || session.getPolarDeviceType().equals("H10"))) {
1002  callback.polarFtpFeatureReady(deviceId);
1003  }
1004  }
1005  }).toFlowable();
1006  }
1007  }
1008  return Flowable.empty();
1009  }
1010  }).subscribe(
1011  new Consumer<Object>() {
1012  @Override
1013  public void accept(Object o) throws Exception {
1014 
1015  }
1016  },
1017  new Consumer<Throwable>() {
1018  @Override
1019  public void accept(Throwable throwable) throws Exception {
1020  logError(throwable.getMessage());
1021  }
1022  },
1023  new Action() {
1024  @Override
1025  public void run() throws Exception {
1026  log("complete");
1027  }
1028  });
1029  }
1030 
1031  private Exception handleError(Throwable throwable) {
1032  if( throwable instanceof BleDisconnected ){
1033  return new PolarDeviceDisconnected();
1034  } else {
1035  return new Exception("Unknown Error: " + throwable.getLocalizedMessage());
1036  }
1037  }
1038 
1039  interface FetchRecursiveCondition {
1040  boolean include(String entry);
1041  }
1042 
1043  private Flowable<String> fetchRecursively(final BlePsFtpClient client, final String path, final FetchRecursiveCondition condition) {
1044  protocol.PftpRequest.PbPFtpOperation.Builder builder = protocol.PftpRequest.PbPFtpOperation.newBuilder();
1045  builder.setCommand(PftpRequest.PbPFtpOperation.Command.GET);
1046  builder.setPath(path);
1047  return client.request(builder.build().toByteArray()).toFlowable().flatMap(new Function<ByteArrayOutputStream, Publisher<String>>() {
1048  @Override
1049  public Publisher<String> apply(ByteArrayOutputStream byteArrayOutputStream) throws Exception {
1050  PftpResponse.PbPFtpDirectory dir = PftpResponse.PbPFtpDirectory.parseFrom(byteArrayOutputStream.toByteArray());
1051  Set<String> entrys = new HashSet<>();
1052  for( int i=0; i < dir.getEntriesCount(); ++i ){
1053  PftpResponse.PbPFtpEntry entry = dir.getEntries(i);
1054  if( condition.include(entry.getName()) ){
1055  BleUtils.validate(entrys.add(path + entry.getName()),"duplicate entry");
1056  }
1057  }
1058  if(entrys.size()!=0) {
1059  return Flowable.fromIterable(entrys).flatMap(new Function<String, Publisher<String>>() {
1060  @Override
1061  public Publisher<String> apply(String s) {
1062  if (s.endsWith("/")) {
1063  return fetchRecursively(client, s, condition);
1064  } else {
1065  return Flowable.just(s);
1066  }
1067  }
1068  });
1069  }
1070  return Flowable.empty();
1071  }
1072  });
1073  }
1074 
1075  private void log(final String message) {
1076  if(logger != null){
1077  logger.message("" + message);
1078  }
1079  }
1080 
1081  private void logError(final String message) {
1082  if(logger != null){
1083  logger.message("Error: "+message);
1084  }
1085  }
1086 }
+
void log(final String message)
+
Flowable< PolarDeviceInfo > searchForPolarDevice()
+ +
static final int ANDROID_VERSION_O
+
Single< PolarExerciseData > fetchExercise(String identifier, PolarExerciseEntry entry)
+ +
Completable startRecording(String identifier, String exerciseId, RecordingInterval interval, SampleType type)
-
void setAutomaticReconnection(boolean disable)
-
Single< PolarSensorSetting > requestAccSettings(String identifier)
-
PolarBleApiCallback callback
-
Exception handleError(Throwable throwable)
+
void setAutomaticReconnection(boolean disable)
+
Single< PolarSensorSetting > requestAccSettings(String identifier)
+
PolarBleApiCallback callback
+
Exception handleError(Throwable throwable)
void accelerometerFeatureReady(@NonNull final String identifier)
-
Flowable< PolarOhrPPIData > startOhrPPIStreaming(String identifier)
+
Flowable< PolarOhrPPIData > startOhrPPIStreaming(String identifier)
- +
void hrFeatureReady(@NonNull final String identifier)
- +
void fwInformationReceived(@NonNull final String identifier, @NonNull final String fwVersion)
-
Flowable< PolarHrBroadcastData > startListenForPolarHrBroadcasts(final Set< String > deviceIds)
- +
Flowable< PolarHrBroadcastData > startListenForPolarHrBroadcasts(final Set< String > deviceIds)
+
void ecgFeatureReady(@NonNull final String identifier)
- - -
Single< PolarSensorSetting > querySettings(final String identifier, final BlePMDClient.PmdMeasurementType type)
+ + +
Single< PolarSensorSetting > querySettings(final String identifier, final BlePMDClient.PmdMeasurementType type)
-
static final int FEATURE_POLAR_SENSOR_STREAMING
+
static final int FEATURE_POLAR_SENSOR_STREAMING
-
Map< String, Disposable > connectSubscriptions
+
Map< String, Disposable > connectSubscriptions
void ppgFeatureReady(@NonNull final String identifier)
-
Completable autoConnectToPolarDevice(final int rssiLimit, final String polarDeviceType)
-
Single< PolarSensorSetting > requestBiozSettings(final String identifier)
-
void disconnectFromPolarDevice(String identifier)
- -
Single< PolarSensorSetting > requestEcgSettings(String identifier)
-
BleDeviceSession sessionServiceReady(final String identifier, UUID service)
-
Single< Pair< Boolean, String > > requestRecordingStatus(String identifier)
+
Completable autoConnectToPolarDevice(final int rssiLimit, final String polarDeviceType)
+
Single< PolarSensorSetting > requestBiozSettings(final String identifier)
+ +
void disconnectFromPolarDevice(String identifier)
+ +
Single< PolarSensorSetting > requestEcgSettings(String identifier)
+
BleDeviceSession sessionServiceReady(final String identifier, UUID service)
+
Single< Pair< Boolean, String > > requestRecordingStatus(String identifier)
- + -
static final int FEATURE_BATTERY_INFO
+
static final int FEATURE_BATTERY_INFO
-
boolean isFeatureReady(final String deviceId, int feature)
+
boolean isFeatureReady(final String deviceId, int feature)
void polarDeviceConnecting(@NonNull final PolarDeviceInfo polarDeviceInfo)
-
Flowable< PolarAccelerometerData > startAccStreaming(String identifier, PolarSensorSetting setting)
- -
BDBleApiImpl(final Context context, int features)
-
Single< PolarSensorSetting > requestPpgSettings(String identifier)
+
Flowable< PolarAccelerometerData > startAccStreaming(String identifier, PolarSensorSetting setting)
+ +
BDBleApiImpl(final Context context, int features)
+
Single< PolarSensorSetting > requestPpgSettings(String identifier)
- + -
BleDeviceSession sessionPmdClientReady(final String identifier)
+
BleDeviceSession sessionPmdClientReady(final String identifier)
-
Flowable< String > fetchRecursively(final BlePsFtpClient client, final String path, final FetchRecursiveCondition condition)
-
Completable stopRecording(String identifier)
+
Flowable< String > fetchRecursively(final BlePsFtpClient client, final String path, final FetchRecursiveCondition condition)
+
Completable stopRecording(String identifier)
void ppiFeatureReady(@NonNull final String identifier)
-
Completable setLocalTime(String identifier, Date local)
+
Completable setLocalTime(String identifier, Date local)
void polarDeviceDisconnected(@NonNull final PolarDeviceInfo polarDeviceInfo)
void batteryLevelReceived(@NonNull final String identifier, final int level)
-
void sendNotification(BlePsFtpClient client, int notification)
-
static final int FEATURE_DEVICE_INFO
-
void setupDevice(final BleDeviceSession session)
+
static final int FEATURE_DEVICE_INFO
+
void setupDevice(final BleDeviceSession session)
-
Flowable< PolarBiozData > startBiozStreaming(final String identifier, PolarSensorSetting setting)
-
Flowable< PolarExerciseEntry > listExercises(String identifier)
- +
Flowable< PolarBiozData > startBiozStreaming(final String identifier, PolarSensorSetting setting)
+
Flowable< PolarExerciseEntry > listExercises(String identifier)
+ -
BleDeviceSession sessionByDeviceId(final String deviceId)
+
BleDeviceSession sessionByDeviceId(final String deviceId)
void hrNotificationReceived(@NonNull final String identifier, @NonNull final PolarHrData data)
void blePowerStateChanged(final boolean powered)
-
static final int FEATURE_POLAR_FILE_TRANSFER
-
Completable removeExercise(String identifier, PolarExerciseEntry entry)
+
static final int FEATURE_POLAR_FILE_TRANSFER
+
Completable removeExercise(String identifier, PolarExerciseEntry entry)
void polarFtpFeatureReady(@NonNull final String identifier)
void polarDeviceConnected(@NonNull final PolarDeviceInfo polarDeviceInfo)
- - -
void stopPmdStreaming(BleDeviceSession session, BlePMDClient client, BlePMDClient.PmdMeasurementType type)
- -
void setApiLogger(@Nullable PolarBleApiLogger logger)
-
Completable autoConnectToPolarDevice(final int rssiLimit, final int timeout, final TimeUnit unit, final String polarDeviceType)
-
Flowable< PolarOhrPPGData > startOhrPPGStreaming(String identifier, PolarSensorSetting setting)
-
Flowable< PolarEcgData > startEcgStreaming(String identifier, PolarSensorSetting setting)
+ + +
void stopPmdStreaming(BleDeviceSession session, BlePMDClient client, BlePMDClient.PmdMeasurementType type)
+ +
void setApiLogger(@Nullable PolarBleApiLogger logger)
+
Completable autoConnectToPolarDevice(final int rssiLimit, final int timeout, final TimeUnit unit, final String polarDeviceType)
+
Flowable< PolarOhrPPGData > startOhrPPGStreaming(String identifier, PolarSensorSetting setting)
+
Flowable< PolarEcgData > startEcgStreaming(String identifier, PolarSensorSetting setting)
void biozFeatureReady(@NonNull final String identifier)
- + -
void setApiCallback(PolarBleApiCallback callback)
+
void setApiCallback(PolarBleApiCallback callback)
-
BleDeviceSession sessionPsFtpClientReady(final String identifier)
-
void logError(final String message)
+
BleDeviceSession sessionPsFtpClientReady(final String identifier)
+
void logError(final String message)
- -
void connectToPolarDevice(final String identifier)
+ +
void connectToPolarDevice(final String identifier)
diff --git a/polar-sdk-android/docs/html/PolarAccelerometerData_8java_source.html b/polar-sdk-android/docs/html/PolarAccelerometerData_8java_source.html index 5f2f8c38..0c89c789 100644 --- a/polar-sdk-android/docs/html/PolarAccelerometerData_8java_source.html +++ b/polar-sdk-android/docs/html/PolarAccelerometerData_8java_source.html @@ -66,7 +66,7 @@
PolarAccelerometerData.java
-Go to the documentation of this file.
1 // Copyright © 2019 Polar Electro Oy. All rights reserved.
2 package polar.com.sdk.api.model;
3 
4 import java.util.List;
5 
9 public class PolarAccelerometerData {
10 
14  public static class PolarAccelerometerSample {
18  public int x;
19 
23  public int y;
24 
28  public int z;
29 
30  public PolarAccelerometerSample(int x, int y, int z) {
31  this.x = x;
32  this.y = y;
33  this.z = z;
34  }
35  }
36 
40  public List<PolarAccelerometerSample> samples;
41 
45  public long timeStamp;
46 
52  public PolarAccelerometerData(List<PolarAccelerometerSample> samples, long timeStamp) {
53  this.samples = samples;
54  this.timeStamp = timeStamp;
55  }
56 }
+Go to the documentation of this file.
1 // Copyright © 2019 Polar Electro Oy. All rights reserved.
2 package polar.com.sdk.api.model;
3 
4 import java.util.List;
5 
9 public class PolarAccelerometerData {
10 
14  public static class PolarAccelerometerSample {
18  public int x;
19 
23  public int y;
24 
28  public int z;
29 
30  public PolarAccelerometerSample(int x, int y, int z) {
31  this.x = x;
32  this.y = y;
33  this.z = z;
34  }
35  }
36 
40  public List<PolarAccelerometerSample> samples;
41 
45  public long timeStamp;
46 
52  public PolarAccelerometerData(List<PolarAccelerometerSample> samples, long timeStamp) {
53  this.samples = samples;
54  this.timeStamp = timeStamp;
55  }
56 }
PolarAccelerometerData(List< PolarAccelerometerSample > samples, long timeStamp)
diff --git a/polar-sdk-android/docs/html/PolarBleApiDefaultImpl_8java_source.html b/polar-sdk-android/docs/html/PolarBleApiDefaultImpl_8java_source.html index 62a275f6..664cb754 100644 --- a/polar-sdk-android/docs/html/PolarBleApiDefaultImpl_8java_source.html +++ b/polar-sdk-android/docs/html/PolarBleApiDefaultImpl_8java_source.html @@ -66,14 +66,14 @@
PolarBleApiDefaultImpl.java
-Go to the documentation of this file.
1 // Copyright © 2019 Polar Electro Oy. All rights reserved.
2 package polar.com.sdk.api;
3 
4 import android.content.Context;
5 
6 import com.androidcommunications.polar.api.ble.BleRefApiVersion;
7 
9 
13 public class PolarBleApiDefaultImpl {
20  public static PolarBleApi defaultImplementation(final Context context, int features){
21  return new BDBleApiImpl(context,features);
22  }
23 
27  public static String versionInfo(){
28  return "13.0.0";//BleRefApiVersion.major() + "." + BleRefApiVersion.minor() + "." + BleRefApiVersion.patch();
29  }
30 }
+Go to the documentation of this file.
1 // Copyright © 2019 Polar Electro Oy. All rights reserved.
2 package polar.com.sdk.api;
3 
4 import android.content.Context;
5 
6 import com.androidcommunications.polar.api.ble.BleRefApiVersion;
7 
9 
13 public class PolarBleApiDefaultImpl {
20  public static PolarBleApi defaultImplementation(final Context context, int features){
21  return new BDBleApiImpl(context,features);
22  }
23 
27  public static String versionInfo(){
28  return "" + (BleRefApiVersion.major()-12) + ".1.0";
29  }
30 }
static PolarBleApi defaultImplementation(final Context context, int features)
- +
diff --git a/polar-sdk-android/docs/html/PolarBleApi_8java_source.html b/polar-sdk-android/docs/html/PolarBleApi_8java_source.html index 193cd020..0c97a90e 100644 --- a/polar-sdk-android/docs/html/PolarBleApi_8java_source.html +++ b/polar-sdk-android/docs/html/PolarBleApi_8java_source.html @@ -66,7 +66,7 @@
PolarBleApi.java
-Go to the documentation of this file.
1 // Copyright © 2019 Polar Electro Oy. All rights reserved.
2 package polar.com.sdk.api;
3 
4 import android.support.annotation.Nullable;
5 import android.support.annotation.Size;
6 import android.util.Pair;
7 
8 import com.androidcommunications.polar.api.ble.model.gatt.client.BlePMDClient;
9 
10 import java.util.Date;
11 import java.util.Set;
12 import java.util.concurrent.TimeUnit;
13 
14 import io.reactivex.Completable;
15 import io.reactivex.Flowable;
16 import io.reactivex.Single;
17 import io.reactivex.annotations.NonNull;
18 import io.reactivex.disposables.Disposable;
29 
33 public abstract class PolarBleApi {
34 
38  public interface PolarBleApiLogger {
43  void message(final String str);
44  }
45 
49  public enum RecordingInterval {
53  private int value;
54 
55  RecordingInterval(int value) {
56  this.value = value;
57  }
58 
59  public int getValue() {
60  return value;
61  }
62  };
63 
67  public enum SampleType {
68  HR,
69  RR;
70  };
71 
75  public static final int FEATURE_HR = 1;
79  public static final int FEATURE_DEVICE_INFO = 2;
83  public static final int FEATURE_BATTERY_INFO = 4;
87  public static final int FEATURE_POLAR_SENSOR_STREAMING = 8;
91  public static final int FEATURE_POLAR_FILE_TRANSFER = 16;
95  public static final int ALL_FEATURES = 0xff;
96 
97  protected int features;
98 
103  protected PolarBleApi(final int features) {
104  this.features = features;
105  }
106 
110  public abstract void shutDown();
111 
118  public abstract boolean isFeatureReady(@NonNull final String deviceId, final int feature);
119 
123  public abstract void backgroundEntered();
124 
128  public abstract void foregroundEntered();
129 
133  public abstract void setApiCallback(@Nullable PolarBleApiCallback callback);
134 
138  public abstract void setApiLogger(@Nullable PolarBleApiLogger logger);
139 
144  public abstract void setAutomaticReconnection(boolean enable);
145 
153  public abstract Completable setLocalTime(@NonNull final String identifier,@NonNull final Date time);
154 
160  public abstract Single<PolarSensorSetting> requestAccSettings(@NonNull final String identifier);
161 
167  public abstract Single<PolarSensorSetting> requestEcgSettings(@NonNull final String identifier);
168 
174  public abstract Single<PolarSensorSetting> requestPpgSettings(@NonNull final String identifier);
175 
176  public abstract Single<PolarSensorSetting> requestBiozSettings(@NonNull final String identifier);
177 
188  public abstract Completable autoConnectToPolarDevice(int rssiLimit, int timeout,@NonNull TimeUnit unit,@Nullable final String polarDeviceType);
189  public abstract Completable autoConnectToPolarDevice(int rssiLimit, final String polarDeviceType);
190 
195  public abstract void connectToPolarDevice(@NonNull final String identifier);
196 
201  public abstract void disconnectFromPolarDevice(@NonNull final String identifier);
202 
211  public abstract Completable startRecording(@NonNull final String identifier,
212  @NonNull @Size(min = 1, max = 64) final String exerciseId,
213  @NonNull RecordingInterval interval,
214  @NonNull SampleType type);
215 
221  public abstract Completable stopRecording(@NonNull final String identifier);
222 
228  public abstract Single<Pair<Boolean,String>> requestRecordingStatus(@NonNull final String identifier);
229 
235  public abstract Flowable<PolarExerciseEntry> listExercises(@NonNull final String identifier);
236 
243  public abstract Single<PolarExerciseData> fetchExercise(@NonNull final String identifier, @NonNull final PolarExerciseEntry entry);
244 
251  public abstract Completable removeExercise(@NonNull final String identifier, @NonNull final PolarExerciseEntry entry);
252 
261  public abstract Flowable<PolarDeviceInfo> searchForPolarDevice();
262 
272  public abstract Flowable<PolarHrBroadcastData> startListenForPolarHrBroadcasts(@Nullable final Set<String> deviceIds);
273 
286  public abstract Flowable<PolarEcgData> startEcgStreaming(@NonNull final String identifier,
287  @NonNull PolarSensorSetting sensorSetting);
288 
301  public abstract Flowable<PolarAccelerometerData> startAccStreaming(@NonNull final String identifier,
302  @NonNull PolarSensorSetting sensorSetting);
303 
316  public abstract Flowable<PolarOhrPPGData> startOhrPPGStreaming(@NonNull final String identifier,
317  @NonNull PolarSensorSetting sensorSetting);
318 
319  public abstract Flowable<PolarBiozData> startBiozStreaming(@NonNull final String identifier,
320  @NonNull PolarSensorSetting sensorSetting);
321 
332  public abstract Flowable<PolarOhrPPIData> startOhrPPIStreaming(@NonNull final String identifier);
333 }
+Go to the documentation of this file.
1 // Copyright © 2019 Polar Electro Oy. All rights reserved.
2 package polar.com.sdk.api;
3 
4 import android.support.annotation.Nullable;
5 import android.support.annotation.Size;
6 import android.util.Pair;
7 
8 import java.util.Date;
9 import java.util.Set;
10 import java.util.concurrent.TimeUnit;
11 
12 import io.reactivex.Completable;
13 import io.reactivex.Flowable;
14 import io.reactivex.Single;
15 import io.reactivex.annotations.NonNull;
26 
30 public abstract class PolarBleApi {
31 
35  public interface PolarBleApiLogger {
40  void message(final String str);
41  }
42 
46  public enum RecordingInterval {
50  private int value;
51 
52  RecordingInterval(int value) {
53  this.value = value;
54  }
55 
56  public int getValue() {
57  return value;
58  }
59  };
60 
64  public enum SampleType {
65  HR,
66  RR;
67  };
68 
72  public static final int FEATURE_HR = 1;
76  public static final int FEATURE_DEVICE_INFO = 2;
80  public static final int FEATURE_BATTERY_INFO = 4;
84  public static final int FEATURE_POLAR_SENSOR_STREAMING = 8;
88  public static final int FEATURE_POLAR_FILE_TRANSFER = 16;
92  public static final int ALL_FEATURES = 0xff;
93 
94  protected int features;
95 
100  protected PolarBleApi(final int features) {
101  this.features = features;
102  }
103 
107  public abstract void shutDown();
108 
112  public abstract void cleanup();
113 
120  public abstract boolean isFeatureReady(@NonNull final String deviceId, final int feature);
121 
125  public abstract void backgroundEntered();
126 
130  public abstract void foregroundEntered();
131 
135  public abstract void setApiCallback(@Nullable PolarBleApiCallback callback);
136 
140  public abstract void setApiLogger(@Nullable PolarBleApiLogger logger);
141 
146  public abstract void setAutomaticReconnection(boolean enable);
147 
155  public abstract Completable setLocalTime(@NonNull final String identifier,@NonNull final Date time);
156 
162  public abstract Single<PolarSensorSetting> requestAccSettings(@NonNull final String identifier);
163 
169  public abstract Single<PolarSensorSetting> requestEcgSettings(@NonNull final String identifier);
170 
176  public abstract Single<PolarSensorSetting> requestPpgSettings(@NonNull final String identifier);
177 
178  public abstract Single<PolarSensorSetting> requestBiozSettings(@NonNull final String identifier);
179 
190  public abstract Completable autoConnectToPolarDevice(int rssiLimit, int timeout,@NonNull TimeUnit unit,@Nullable final String polarDeviceType);
191  public abstract Completable autoConnectToPolarDevice(int rssiLimit, final String polarDeviceType);
192 
197  public abstract void connectToPolarDevice(@NonNull final String identifier);
198 
203  public abstract void disconnectFromPolarDevice(@NonNull final String identifier);
204 
213  public abstract Completable startRecording(@NonNull final String identifier,
214  @NonNull @Size(min = 1, max = 64) final String exerciseId,
215  @NonNull RecordingInterval interval,
216  @NonNull SampleType type);
217 
223  public abstract Completable stopRecording(@NonNull final String identifier);
224 
230  public abstract Single<Pair<Boolean,String>> requestRecordingStatus(@NonNull final String identifier);
231 
237  public abstract Flowable<PolarExerciseEntry> listExercises(@NonNull final String identifier);
238 
245  public abstract Single<PolarExerciseData> fetchExercise(@NonNull final String identifier, @NonNull final PolarExerciseEntry entry);
246 
253  public abstract Completable removeExercise(@NonNull final String identifier, @NonNull final PolarExerciseEntry entry);
254 
263  public abstract Flowable<PolarDeviceInfo> searchForPolarDevice();
264 
274  public abstract Flowable<PolarHrBroadcastData> startListenForPolarHrBroadcasts(@Nullable final Set<String> deviceIds);
275 
288  public abstract Flowable<PolarEcgData> startEcgStreaming(@NonNull final String identifier,
289  @NonNull PolarSensorSetting sensorSetting);
290 
303  public abstract Flowable<PolarAccelerometerData> startAccStreaming(@NonNull final String identifier,
304  @NonNull PolarSensorSetting sensorSetting);
305 
318  public abstract Flowable<PolarOhrPPGData> startOhrPPGStreaming(@NonNull final String identifier,
319  @NonNull PolarSensorSetting sensorSetting);
320 
321  public abstract Flowable<PolarBiozData> startBiozStreaming(@NonNull final String identifier,
322  @NonNull PolarSensorSetting sensorSetting);
323 
334  public abstract Flowable<PolarOhrPPIData> startOhrPPIStreaming(@NonNull final String identifier);
335 }
abstract Single< PolarSensorSetting > requestEcgSettings(@NonNull final String identifier)
abstract Flowable< PolarOhrPPIData > startOhrPPIStreaming(@NonNull final String identifier)
@@ -74,25 +74,25 @@
abstract Flowable< PolarDeviceInfo > searchForPolarDevice()
abstract Flowable< PolarAccelerometerData > startAccStreaming(@NonNull final String identifier, @NonNull PolarSensorSetting sensorSetting)
- +
abstract void setApiLogger(@Nullable PolarBleApiLogger logger)
- +
abstract Completable stopRecording(@NonNull final String identifier)
- +
abstract Single< PolarSensorSetting > requestAccSettings(@NonNull final String identifier)
abstract void setAutomaticReconnection(boolean enable)
abstract void foregroundEntered()
-
static final int FEATURE_POLAR_SENSOR_STREAMING
+
static final int FEATURE_POLAR_SENSOR_STREAMING
abstract Flowable< PolarHrBroadcastData > startListenForPolarHrBroadcasts(@Nullable final Set< String > deviceIds)
- -
static final int ALL_FEATURES
+ +
static final int ALL_FEATURES
abstract boolean isFeatureReady(@NonNull final String deviceId, final int feature)
- + -
static final int FEATURE_BATTERY_INFO
- +
static final int FEATURE_BATTERY_INFO
+
abstract void backgroundEntered()
@@ -101,33 +101,34 @@
abstract Flowable< PolarOhrPPGData > startOhrPPGStreaming(@NonNull final String identifier, @NonNull PolarSensorSetting sensorSetting)
abstract void disconnectFromPolarDevice(@NonNull final String identifier)
abstract Single< PolarSensorSetting > requestBiozSettings(@NonNull final String identifier)
-
PolarBleApi(final int features)
+
PolarBleApi(final int features)
abstract Flowable< PolarExerciseEntry > listExercises(@NonNull final String identifier)
- +
abstract Single< Pair< Boolean, String > > requestRecordingStatus(@NonNull final String identifier)
- + -
static final int FEATURE_DEVICE_INFO
- - +
static final int FEATURE_DEVICE_INFO
+ +
abstract Completable removeExercise(@NonNull final String identifier, @NonNull final PolarExerciseEntry entry)
-
static final int FEATURE_POLAR_FILE_TRANSFER
+
static final int FEATURE_POLAR_FILE_TRANSFER
abstract Flowable< PolarEcgData > startEcgStreaming(@NonNull final String identifier, @NonNull PolarSensorSetting sensorSetting)
abstract void connectToPolarDevice(@NonNull final String identifier)
abstract Single< PolarSensorSetting > requestPpgSettings(@NonNull final String identifier)
- +
abstract Completable autoConnectToPolarDevice(int rssiLimit, int timeout, @NonNull TimeUnit unit, @Nullable final String polarDeviceType)
- + +
abstract void setApiCallback(@Nullable PolarBleApiCallback callback)
- +
abstract Flowable< PolarBiozData > startBiozStreaming(@NonNull final String identifier, @NonNull PolarSensorSetting sensorSetting)
abstract Single< PolarExerciseData > fetchExercise(@NonNull final String identifier, @NonNull final PolarExerciseEntry entry)
diff --git a/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html b/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html index a52037ad..1019e8ac 100644 --- a/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html +++ b/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html @@ -95,6 +95,8 @@ Public Member Functions abstract void shutDown ()   +abstract void cleanup () +  abstract boolean isFeatureReady (@NonNull final String deviceId, final int feature)   abstract void backgroundEntered () @@ -180,7 +182,7 @@

Detailed Description

Main class of the API.

-

Definition at line 33 of file PolarBleApi.java.

+

Definition at line 30 of file PolarBleApi.java.

Constructor & Destructor Documentation

◆ PolarBleApi()

@@ -212,7 +214,7 @@

Definition at line 103 of file PolarBleApi.java.

+

Definition at line 100 of file PolarBleApi.java.

@@ -335,6 +337,32 @@

enables scan filter while on background

+ + +
+

◆ cleanup()

+ +
+
+ + + + + +
+ + + + + + + +
abstract void polar.com.sdk.api.PolarBleApi.cleanup ()
+
+abstract
+
+

removes all known devices which are not in use currently

+
@@ -1323,7 +1351,7 @@

all features mask

-

Definition at line 95 of file PolarBleApi.java.

+

Definition at line 92 of file PolarBleApi.java.

@@ -1348,7 +1376,7 @@

bas feature to receive battery level info.

-

Definition at line 83 of file PolarBleApi.java.

+

Definition at line 80 of file PolarBleApi.java.

@@ -1373,7 +1401,7 @@

dis feature to receive sw information.

-

Definition at line 79 of file PolarBleApi.java.

+

Definition at line 76 of file PolarBleApi.java.

@@ -1398,7 +1426,7 @@

hr feature to receive hr and rr data.

-

Definition at line 75 of file PolarBleApi.java.

+

Definition at line 72 of file PolarBleApi.java.

@@ -1423,7 +1451,7 @@

polar file transfer feature to read exercises from device

-

Definition at line 91 of file PolarBleApi.java.

+

Definition at line 88 of file PolarBleApi.java.

@@ -1448,7 +1476,7 @@

polar sensor streaming for ecg, acc, ppg, ppi, etc...

-

Definition at line 87 of file PolarBleApi.java.

+

Definition at line 84 of file PolarBleApi.java.

@@ -1472,7 +1500,7 @@

-

Definition at line 97 of file PolarBleApi.java.

+

Definition at line 94 of file PolarBleApi.java.

diff --git a/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.js b/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.js index be575377..11e6bdcd 100644 --- a/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.js +++ b/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.js @@ -7,6 +7,7 @@ var classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi = [ "autoConnectToPolarDevice", "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#aed92cfd7807194a6a82d708bdee2a313", null ], [ "autoConnectToPolarDevice", "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#ab8f30183f9ee4d1a0cc229e06f4f5d5b", null ], [ "backgroundEntered", "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a5397f7034f2f36820910b65d84b45b1c", null ], + [ "cleanup", "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a43c533a7a7011c6d2f56a4497fae04f7", null ], [ "connectToPolarDevice", "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a1d83a0eec58e4a36f095207dcee71a6c", null ], [ "disconnectFromPolarDevice", "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a90a6c60c7f16506e93745cd4111a5b25", null ], [ "fetchExercise", "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a63713c5d8a89dee1d2e769068e803bed", null ], diff --git a/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html b/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html index 5ff13b32..5e0bf108 100644 --- a/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html +++ b/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html @@ -93,6 +93,8 @@   void shutDown ()   +void cleanup () +  boolean isFeatureReady (final String deviceId, int feature)   void setApiCallback (PolarBleApiCallback callback) @@ -154,6 +156,8 @@ - Public Member Functions inherited from polar.com.sdk.api.PolarBleApi abstract void shutDown ()   +abstract void cleanup () +  abstract boolean isFeatureReady (@NonNull final String deviceId, final int feature)   abstract void backgroundEntered () @@ -231,8 +235,6 @@   Flowable< String > fetchRecursively (final BlePsFtpClient client, final String path, final FetchRecursiveCondition condition)   -void sendNotification (BlePsFtpClient client, int notification) -  void log (final String message)   void logError (final String message) @@ -283,7 +285,7 @@

Detailed Description

The default implementation of the Polar API

-

Definition at line 90 of file BDBleApiImpl.java.

+

Definition at line 91 of file BDBleApiImpl.java.

Constructor & Destructor Documentation

◆ BDBleApiImpl()

@@ -319,7 +321,7 @@

-

Definition at line 100 of file BDBleApiImpl.java.

+

Definition at line 101 of file BDBleApiImpl.java.

@@ -370,7 +372,7 @@

-

Definition at line 329 of file BDBleApiImpl.java.

+

Definition at line 335 of file BDBleApiImpl.java.

@@ -408,7 +410,7 @@

-

Definition at line 374 of file BDBleApiImpl.java.

+

Definition at line 380 of file BDBleApiImpl.java.

@@ -435,7 +437,34 @@

-

Definition at line 319 of file BDBleApiImpl.java.

+

Definition at line 325 of file BDBleApiImpl.java.

+ + + + +

◆ cleanup()

+ +
+
+ + + + + +
+ + + + + + + +
void polar.com.sdk.impl.BDBleApiImpl.cleanup ()
+
+inline
+
+ +

Definition at line 231 of file BDBleApiImpl.java.

@@ -463,7 +492,7 @@

-

Definition at line 379 of file BDBleApiImpl.java.

+

Definition at line 385 of file BDBleApiImpl.java.

@@ -491,7 +520,7 @@

-

Definition at line 414 of file BDBleApiImpl.java.

+

Definition at line 420 of file BDBleApiImpl.java.

@@ -518,7 +547,7 @@

-

Definition at line 213 of file BDBleApiImpl.java.

+

Definition at line 214 of file BDBleApiImpl.java.

@@ -556,7 +585,7 @@

-

Definition at line 555 of file BDBleApiImpl.java.

+

Definition at line 561 of file BDBleApiImpl.java.

@@ -600,7 +629,7 @@

-

Definition at line 1037 of file BDBleApiImpl.java.

+

Definition at line 1043 of file BDBleApiImpl.java.

@@ -627,7 +656,7 @@

-

Definition at line 324 of file BDBleApiImpl.java.

+

Definition at line 330 of file BDBleApiImpl.java.

@@ -655,7 +684,7 @@

-

Definition at line 1025 of file BDBleApiImpl.java.

+

Definition at line 1031 of file BDBleApiImpl.java.

@@ -693,7 +722,7 @@

-

Definition at line 230 of file BDBleApiImpl.java.

+

Definition at line 236 of file BDBleApiImpl.java.

@@ -721,7 +750,7 @@

-

Definition at line 499 of file BDBleApiImpl.java.

+

Definition at line 505 of file BDBleApiImpl.java.

@@ -749,7 +778,7 @@

-

Definition at line 1086 of file BDBleApiImpl.java.

+

Definition at line 1075 of file BDBleApiImpl.java.

@@ -777,7 +806,7 @@

-

Definition at line 1092 of file BDBleApiImpl.java.

+

Definition at line 1081 of file BDBleApiImpl.java.

@@ -815,7 +844,7 @@

-

Definition at line 303 of file BDBleApiImpl.java.

+

Definition at line 309 of file BDBleApiImpl.java.

@@ -853,7 +882,7 @@

-

Definition at line 583 of file BDBleApiImpl.java.

+

Definition at line 589 of file BDBleApiImpl.java.

@@ -881,7 +910,7 @@

-

Definition at line 284 of file BDBleApiImpl.java.

+

Definition at line 290 of file BDBleApiImpl.java.

@@ -909,7 +938,7 @@

-

Definition at line 299 of file BDBleApiImpl.java.

+

Definition at line 305 of file BDBleApiImpl.java.

@@ -937,7 +966,7 @@

-

Definition at line 289 of file BDBleApiImpl.java.

+

Definition at line 295 of file BDBleApiImpl.java.

@@ -965,7 +994,7 @@

-

Definition at line 294 of file BDBleApiImpl.java.

+

Definition at line 300 of file BDBleApiImpl.java.

@@ -993,7 +1022,7 @@

-

Definition at line 474 of file BDBleApiImpl.java.

+

Definition at line 480 of file BDBleApiImpl.java.

@@ -1020,45 +1049,7 @@

-

Definition at line 632 of file BDBleApiImpl.java.

- - - - -

◆ sendNotification()

- -
-
- - - - - -
- - - - - - - - - - - - - - - - - - -
void polar.com.sdk.impl.BDBleApiImpl.sendNotification (BlePsFtpClient client,
int notification 
)
-
-inlineprivate
-
- -

Definition at line 1070 of file BDBleApiImpl.java.

+

Definition at line 638 of file BDBleApiImpl.java.

@@ -1086,7 +1077,7 @@

-

Definition at line 825 of file BDBleApiImpl.java.

+

Definition at line 831 of file BDBleApiImpl.java.

@@ -1114,7 +1105,7 @@

-

Definition at line 849 of file BDBleApiImpl.java.

+

Definition at line 855 of file BDBleApiImpl.java.

@@ -1142,7 +1133,7 @@

-

Definition at line 862 of file BDBleApiImpl.java.

+

Definition at line 868 of file BDBleApiImpl.java.

@@ -1180,7 +1171,7 @@

-

Definition at line 834 of file BDBleApiImpl.java.

+

Definition at line 840 of file BDBleApiImpl.java.

@@ -1208,7 +1199,7 @@

-

Definition at line 244 of file BDBleApiImpl.java.

+

Definition at line 250 of file BDBleApiImpl.java.

@@ -1236,7 +1227,7 @@

-

Definition at line 250 of file BDBleApiImpl.java.

+

Definition at line 256 of file BDBleApiImpl.java.

@@ -1264,7 +1255,7 @@

-

Definition at line 255 of file BDBleApiImpl.java.

+

Definition at line 261 of file BDBleApiImpl.java.

@@ -1302,7 +1293,7 @@

-

Definition at line 260 of file BDBleApiImpl.java.

+

Definition at line 266 of file BDBleApiImpl.java.

@@ -1330,7 +1321,7 @@

-

Definition at line 894 of file BDBleApiImpl.java.

+

Definition at line 900 of file BDBleApiImpl.java.

@@ -1357,7 +1348,7 @@

-

Definition at line 225 of file BDBleApiImpl.java.

+

Definition at line 226 of file BDBleApiImpl.java.

@@ -1395,7 +1386,7 @@

-

Definition at line 699 of file BDBleApiImpl.java.

+

Definition at line 705 of file BDBleApiImpl.java.

@@ -1433,7 +1424,7 @@

-

Definition at line 799 of file BDBleApiImpl.java.

+

Definition at line 805 of file BDBleApiImpl.java.

@@ -1471,7 +1462,7 @@

-

Definition at line 667 of file BDBleApiImpl.java.

+

Definition at line 673 of file BDBleApiImpl.java.

@@ -1499,7 +1490,7 @@

-

Definition at line 647 of file BDBleApiImpl.java.

+

Definition at line 653 of file BDBleApiImpl.java.

@@ -1537,7 +1528,7 @@

-

Definition at line 731 of file BDBleApiImpl.java.

+

Definition at line 737 of file BDBleApiImpl.java.

@@ -1565,7 +1556,7 @@

-

Definition at line 763 of file BDBleApiImpl.java.

+

Definition at line 769 of file BDBleApiImpl.java.

@@ -1615,7 +1606,7 @@

-

Definition at line 430 of file BDBleApiImpl.java.

+

Definition at line 436 of file BDBleApiImpl.java.

@@ -1659,7 +1650,7 @@

-

Definition at line 873 of file BDBleApiImpl.java.

+

Definition at line 879 of file BDBleApiImpl.java.

@@ -1687,7 +1678,7 @@

-

Definition at line 455 of file BDBleApiImpl.java.

+

Definition at line 461 of file BDBleApiImpl.java.

@@ -1712,7 +1703,7 @@

-

Definition at line 97 of file BDBleApiImpl.java.

+

Definition at line 98 of file BDBleApiImpl.java.

@@ -1736,7 +1727,7 @@

-

Definition at line 95 of file BDBleApiImpl.java.

+

Definition at line 96 of file BDBleApiImpl.java.

@@ -1760,7 +1751,7 @@

-

Definition at line 93 of file BDBleApiImpl.java.

+

Definition at line 94 of file BDBleApiImpl.java.

@@ -1784,7 +1775,7 @@

-

Definition at line 92 of file BDBleApiImpl.java.

+

Definition at line 93 of file BDBleApiImpl.java.

@@ -1808,7 +1799,7 @@

-

Definition at line 96 of file BDBleApiImpl.java.

+

Definition at line 97 of file BDBleApiImpl.java.

@@ -1832,7 +1823,7 @@

-

Definition at line 94 of file BDBleApiImpl.java.

+

Definition at line 95 of file BDBleApiImpl.java.

@@ -1856,7 +1847,7 @@

-

Definition at line 91 of file BDBleApiImpl.java.

+

Definition at line 92 of file BDBleApiImpl.java.

diff --git a/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.js b/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.js index 1e665343..13a75eb3 100644 --- a/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.js +++ b/polar-sdk-android/docs/html/classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.js @@ -4,6 +4,7 @@ var classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl = [ "autoConnectToPolarDevice", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a964a35d7b8b782183fad03aae73b99be", null ], [ "autoConnectToPolarDevice", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#af8fe71975e2d06a5eac90781f5555d07", null ], [ "backgroundEntered", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a24707fd78988e8b9f57d47a6d24cc7e3", null ], + [ "cleanup", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a4f3fceac06da15b3c1a39dc5bb7b80f1", null ], [ "connectToPolarDevice", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a4736cc12d728a7a8ddcd15a883486765", null ], [ "disconnectFromPolarDevice", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a4d8a6d2fd920b9140d071db665aa762a", null ], [ "enableAndroidScanFilter", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aea179b27f1dc4b7ed1ad3e2cb971a7a8", null ], @@ -23,7 +24,6 @@ var classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl = [ "requestPpgSettings", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aa65443950ef837c869eb6199a643487c", null ], [ "requestRecordingStatus", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aded82e5731dc626c167ea7437551ad6d", null ], [ "searchForPolarDevice", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a29b955b7813f2a1e6ebab906548964c8", null ], - [ "sendNotification", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a89db663f43bd488f631c5d76201171c9", null ], [ "sessionByDeviceId", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a2ca3ebc9ca23822d2aca71a2002c1b73", null ], [ "sessionPmdClientReady", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a568cbfd6e9548d54fff470a938cbf000", null ], [ "sessionPsFtpClientReady", "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aed83b0c4e2180511a242f1ccedd3d03c", null ], diff --git a/polar-sdk-android/docs/html/enumpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1RecordingInterval.html b/polar-sdk-android/docs/html/enumpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1RecordingInterval.html index 4085170b..e6727ba4 100644 --- a/polar-sdk-android/docs/html/enumpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1RecordingInterval.html +++ b/polar-sdk-android/docs/html/enumpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1RecordingInterval.html @@ -93,7 +93,7 @@

Detailed Description

Recoding intervals for H10 recording start

-

Definition at line 49 of file PolarBleApi.java.

+

Definition at line 46 of file PolarBleApi.java.

Constructor & Destructor Documentation

◆ RecordingInterval()

@@ -119,7 +119,7 @@

-

Definition at line 55 of file PolarBleApi.java.

+

Definition at line 52 of file PolarBleApi.java.

@@ -147,7 +147,7 @@

-

Definition at line 59 of file PolarBleApi.java.

+

Definition at line 56 of file PolarBleApi.java.

@@ -165,7 +165,7 @@

1 second interval

-

Definition at line 50 of file PolarBleApi.java.

+

Definition at line 47 of file PolarBleApi.java.

@@ -182,7 +182,7 @@

5 second interval

-

Definition at line 51 of file PolarBleApi.java.

+

Definition at line 48 of file PolarBleApi.java.

@@ -206,7 +206,7 @@

-

Definition at line 53 of file PolarBleApi.java.

+

Definition at line 50 of file PolarBleApi.java.

diff --git a/polar-sdk-android/docs/html/enumpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1SampleType.html b/polar-sdk-android/docs/html/enumpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1SampleType.html index fb5f07c5..f5cd78c0 100644 --- a/polar-sdk-android/docs/html/enumpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1SampleType.html +++ b/polar-sdk-android/docs/html/enumpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1SampleType.html @@ -79,7 +79,7 @@

Detailed Description

Sample types for H10 recording start

-

Definition at line 67 of file PolarBleApi.java.

+

Definition at line 64 of file PolarBleApi.java.

Field Documentation

◆ HR

@@ -94,7 +94,7 @@

HeartRate in BPM

-

Definition at line 68 of file PolarBleApi.java.

+

Definition at line 65 of file PolarBleApi.java.

@@ -110,7 +110,7 @@

-

Definition at line 69 of file PolarBleApi.java.

+

Definition at line 66 of file PolarBleApi.java.

diff --git a/polar-sdk-android/docs/html/functions.html b/polar-sdk-android/docs/html/functions.html index be96e938..9f8f420f 100644 --- a/polar-sdk-android/docs/html/functions.html +++ b/polar-sdk-android/docs/html/functions.html @@ -108,6 +108,10 @@

- c -

  • callback : polar.com.sdk.impl.BDBleApiImpl
  • +
  • cleanup() +: polar.com.sdk.api.PolarBleApi +, polar.com.sdk.impl.BDBleApiImpl +
  • connectSubscriptions : polar.com.sdk.impl.BDBleApiImpl
  • @@ -427,9 +431,6 @@

    - s -

      : polar.com.sdk.api.PolarBleApi , polar.com.sdk.impl.BDBleApiImpl -
    • sendNotification() -: polar.com.sdk.impl.BDBleApiImpl -
    • sessionByDeviceId() : polar.com.sdk.impl.BDBleApiImpl
    • diff --git a/polar-sdk-android/docs/html/functions_func.html b/polar-sdk-android/docs/html/functions_func.html index eca368fa..d3d64af6 100644 --- a/polar-sdk-android/docs/html/functions_func.html +++ b/polar-sdk-android/docs/html/functions_func.html @@ -96,6 +96,10 @@

      - b -

        - c -

          +
        • cleanup() +: polar.com.sdk.api.PolarBleApi +, polar.com.sdk.impl.BDBleApiImpl +
        • connectToPolarDevice() : polar.com.sdk.api.PolarBleApi , polar.com.sdk.impl.BDBleApiImpl @@ -301,9 +305,6 @@

          - s -

            : polar.com.sdk.api.PolarBleApi , polar.com.sdk.impl.BDBleApiImpl -
          • sendNotification() -: polar.com.sdk.impl.BDBleApiImpl -
          • sessionByDeviceId() : polar.com.sdk.impl.BDBleApiImpl
          • diff --git a/polar-sdk-android/docs/html/interfacepolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1PolarBleApiLogger.html b/polar-sdk-android/docs/html/interfacepolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1PolarBleApiLogger.html index 3bca80bc..56c34f6d 100644 --- a/polar-sdk-android/docs/html/interfacepolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1PolarBleApiLogger.html +++ b/polar-sdk-android/docs/html/interfacepolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1PolarBleApiLogger.html @@ -77,7 +77,7 @@

            Detailed Description

            Logger interface declaration

            -

            Definition at line 38 of file PolarBleApi.java.

            +

            Definition at line 35 of file PolarBleApi.java.

            Member Function Documentation

            ◆ message()

            diff --git a/polar-sdk-android/docs/html/navtreeindex0.js b/polar-sdk-android/docs/html/navtreeindex0.js index 25340f26..30b018cc 100644 --- a/polar-sdk-android/docs/html/navtreeindex0.js +++ b/polar-sdk-android/docs/html/navtreeindex0.js @@ -45,37 +45,38 @@ var NAVTREEINDEX0 = "annotated.html":[1,0], "classes.html":[1,1], "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html":[1,0,0,0,0,0,2], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a08884e4115932e7917d190daf15ddff1":[1,0,0,0,0,0,2,14], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a11aa139fffa100c346c13a23fdedfe71":[1,0,0,0,0,0,2,25], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a19008b45f93c7ef985a4e47df77674dc":[1,0,0,0,0,0,2,19], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a1d83a0eec58e4a36f095207dcee71a6c":[1,0,0,0,0,0,2,7], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a20700bbdf15b3ea25c632814d3bde8a2":[1,0,0,0,0,0,2,31], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a24e95523c086c9c3818dabc81358d54c":[1,0,0,0,0,0,2,27], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a29176c44198372ae4215d9de9a89c5b7":[1,0,0,0,0,0,2,23], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a2f95d2c9b7c9963c3b7fa5d7c2949e43":[1,0,0,0,0,0,2,18], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a32484f5b3bacdde45573298a4e1d12a5":[1,0,0,0,0,0,2,22], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a36bcd4eb256abc810de32d3dbdfdf9e2":[1,0,0,0,0,0,2,26], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a4682d9318c9ac41927694421bde349a5":[1,0,0,0,0,0,2,20], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a08884e4115932e7917d190daf15ddff1":[1,0,0,0,0,0,2,15], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a11aa139fffa100c346c13a23fdedfe71":[1,0,0,0,0,0,2,26], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a19008b45f93c7ef985a4e47df77674dc":[1,0,0,0,0,0,2,20], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a1d83a0eec58e4a36f095207dcee71a6c":[1,0,0,0,0,0,2,8], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a20700bbdf15b3ea25c632814d3bde8a2":[1,0,0,0,0,0,2,32], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a24e95523c086c9c3818dabc81358d54c":[1,0,0,0,0,0,2,28], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a29176c44198372ae4215d9de9a89c5b7":[1,0,0,0,0,0,2,24], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a2f95d2c9b7c9963c3b7fa5d7c2949e43":[1,0,0,0,0,0,2,19], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a32484f5b3bacdde45573298a4e1d12a5":[1,0,0,0,0,0,2,23], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a36bcd4eb256abc810de32d3dbdfdf9e2":[1,0,0,0,0,0,2,27], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a43c533a7a7011c6d2f56a4497fae04f7":[1,0,0,0,0,0,2,7], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a4682d9318c9ac41927694421bde349a5":[1,0,0,0,0,0,2,21], "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a5397f7034f2f36820910b65d84b45b1c":[1,0,0,0,0,0,2,6], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a551ad9f20c37fba8d7e1ad08c6c1b258":[1,0,0,0,0,0,2,11], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a63713c5d8a89dee1d2e769068e803bed":[1,0,0,0,0,0,2,9], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a6b3b45f899b318df179c9779f9faaf48":[1,0,0,0,0,0,2,33], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a6cfd8b8ffa6ccf0a1763d54017825814":[1,0,0,0,0,0,2,28], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a72fb1fff72cefb0a594537439e77ce30":[1,0,0,0,0,0,2,29], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a8fadd778436185235f0d579077504d0b":[1,0,0,0,0,0,2,12], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a90a6c60c7f16506e93745cd4111a5b25":[1,0,0,0,0,0,2,8], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a914fe430c1ab1cd41f9a3ed72ccacda6":[1,0,0,0,0,0,2,13], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#aa29e34cea992198209979e5c780b0d81":[1,0,0,0,0,0,2,15], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#ab3027dbef46fdc8d3bc15348b494d6bc":[1,0,0,0,0,0,2,16], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#ab6dec221f95ea5dce6118cadeb362006":[1,0,0,0,0,0,2,24], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a551ad9f20c37fba8d7e1ad08c6c1b258":[1,0,0,0,0,0,2,12], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a63713c5d8a89dee1d2e769068e803bed":[1,0,0,0,0,0,2,10], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a6b3b45f899b318df179c9779f9faaf48":[1,0,0,0,0,0,2,34], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a6cfd8b8ffa6ccf0a1763d54017825814":[1,0,0,0,0,0,2,29], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a72fb1fff72cefb0a594537439e77ce30":[1,0,0,0,0,0,2,30], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a8fadd778436185235f0d579077504d0b":[1,0,0,0,0,0,2,13], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a90a6c60c7f16506e93745cd4111a5b25":[1,0,0,0,0,0,2,9], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#a914fe430c1ab1cd41f9a3ed72ccacda6":[1,0,0,0,0,0,2,14], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#aa29e34cea992198209979e5c780b0d81":[1,0,0,0,0,0,2,16], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#ab3027dbef46fdc8d3bc15348b494d6bc":[1,0,0,0,0,0,2,17], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#ab6dec221f95ea5dce6118cadeb362006":[1,0,0,0,0,0,2,25], "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#ab8f30183f9ee4d1a0cc229e06f4f5d5b":[1,0,0,0,0,0,2,5], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#ac2737c48f2aad83fd535d34134e43d17":[1,0,0,0,0,0,2,30], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#ac92b34d91563bb7a208818dd4358b260":[1,0,0,0,0,0,2,21], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#ae34d02d96a9fac60edde6d7b3f61a2d5":[1,0,0,0,0,0,2,17], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#ac2737c48f2aad83fd535d34134e43d17":[1,0,0,0,0,0,2,31], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#ac92b34d91563bb7a208818dd4358b260":[1,0,0,0,0,0,2,22], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#ae34d02d96a9fac60edde6d7b3f61a2d5":[1,0,0,0,0,0,2,18], "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#aed92cfd7807194a6a82d708bdee2a313":[1,0,0,0,0,0,2,4], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#aede0baa6824966c902f5981a3d2e3f72":[1,0,0,0,0,0,2,10], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#aede0baa6824966c902f5981a3d2e3f72":[1,0,0,0,0,0,2,11], "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#afa663962cfcfa76ea7140315074ba39f":[1,0,0,0,0,0,2,3], -"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#afe25cdd5414973383db68bffc75d492f":[1,0,0,0,0,0,2,32], +"classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi.html#afe25cdd5414973383db68bffc75d492f":[1,0,0,0,0,0,2,33], "classpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApiDefaultImpl.html":[1,0,0,0,0,0,4], "classpolar_1_1com_1_1sdk_1_1api_1_1errors_1_1PolarDeviceDisconnected.html":[1,0,0,0,0,0,0,0], "classpolar_1_1com_1_1sdk_1_1api_1_1errors_1_1PolarDeviceNotConnected.html":[1,0,0,0,0,0,0,1], @@ -140,53 +141,53 @@ var NAVTREEINDEX0 = "classpolar_1_1com_1_1sdk_1_1api_1_1model_1_1PolarSensorSetting.html#ae59d938cc770438c06bbd16ea015c9ff":[1,0,0,0,0,0,1,10,5], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html":[1,0,0,0,0,1,0], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a1163224a654db6b5917ad81fc3aa2d23":[1,0,0,0,0,1,0,38], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a1218a5c9c6a590b55f1d00c9a76d4a90":[1,0,0,0,0,1,0,9], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a1218a5c9c6a590b55f1d00c9a76d4a90":[1,0,0,0,0,1,0,10], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a14a4d99e3a14c3e8dd2a9695e25ec9a8":[1,0,0,0,0,1,0,40], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a24707fd78988e8b9f57d47a6d24cc7e3":[1,0,0,0,0,1,0,3], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a29b955b7813f2a1e6ebab906548964c8":[1,0,0,0,0,1,0,22], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a29b955b7813f2a1e6ebab906548964c8":[1,0,0,0,0,1,0,23], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a2c36d4ab6fbdc804df500d2a1d1c0e5d":[1,0,0,0,0,1,0,30], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a2ca3ebc9ca23822d2aca71a2002c1b73":[1,0,0,0,0,1,0,24], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a31b079f8337863ff89f6f1d6dbce65b9":[1,0,0,0,0,1,0,10], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a31b079f8337863ff89f6f1d6dbce65b9":[1,0,0,0,0,1,0,11], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a32dd8f5e44596851f227b793113e9cd2":[1,0,0,0,0,1,0,31], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a34b010c3844f564a377bfb430170e4a9":[1,0,0,0,0,1,0,34], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a4736cc12d728a7a8ddcd15a883486765":[1,0,0,0,0,1,0,4], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a4736cc12d728a7a8ddcd15a883486765":[1,0,0,0,0,1,0,5], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a49685140c9028f1d6f140977b03ab4ca":[1,0,0,0,0,1,0,0], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a4a711dc98144cb480f5b4e4ef3c2af5b":[1,0,0,0,0,1,0,32], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a4d8a6d2fd920b9140d071db665aa762a":[1,0,0,0,0,1,0,5], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a4d8a6d2fd920b9140d071db665aa762a":[1,0,0,0,0,1,0,6], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a4eb11a28590fe41d76fdb88c28894ce2":[1,0,0,0,0,1,0,42], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a4f3fceac06da15b3c1a39dc5bb7b80f1":[1,0,0,0,0,1,0,4], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a568cbfd6e9548d54fff470a938cbf000":[1,0,0,0,0,1,0,25], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a573753301ab6af12467792bc87fc19a2":[1,0,0,0,0,1,0,7], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a573753301ab6af12467792bc87fc19a2":[1,0,0,0,0,1,0,8], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a5ccfe3027f85d5b1262737b1160006b8":[1,0,0,0,0,1,0,43], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a5d33c2910d8f2583ee44962c4bcac2bf":[1,0,0,0,0,1,0,39], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a5e80e959cbc19490c9a1963e6914a092":[1,0,0,0,0,1,0,41], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a6170765b10eb5ecc9b6b9584b350fb1a":[1,0,0,0,0,1,0,13], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a6170765b10eb5ecc9b6b9584b350fb1a":[1,0,0,0,0,1,0,14], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a647db72c6f3a1cbd7587cac769cf0e2c":[1,0,0,0,0,1,0,27], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a7700f8c34663e4f37e208c0b5c779582":[1,0,0,0,0,1,0,36], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a89db663f43bd488f631c5d76201171c9":[1,0,0,0,0,1,0,23], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a8bdd3c4c4bc2c98a5ff9ac7cd1385948":[1,0,0,0,0,1,0,17], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a8bdd3c4c4bc2c98a5ff9ac7cd1385948":[1,0,0,0,0,1,0,18], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a964a35d7b8b782183fad03aae73b99be":[1,0,0,0,0,1,0,1], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#a9863d8f3a3756b95cf030e821af4c21c":[1,0,0,0,0,1,0,35], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aa65443950ef837c869eb6199a643487c":[1,0,0,0,0,1,0,20], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aa7b05d48c5f57c4d66f1e1c182883739":[1,0,0,0,0,1,0,12], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aae9728d213d59602f3c74b447c83c136":[1,0,0,0,0,1,0,8], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aa65443950ef837c869eb6199a643487c":[1,0,0,0,0,1,0,21], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aa7b05d48c5f57c4d66f1e1c182883739":[1,0,0,0,0,1,0,13], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aae9728d213d59602f3c74b447c83c136":[1,0,0,0,0,1,0,9], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#abb45392febb6f61abfe49ef9482f07bb":[1,0,0,0,0,1,0,46], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#abc85de0575973be85cc572460952b5d3":[1,0,0,0,0,1,0,19], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#abc85de0575973be85cc572460952b5d3":[1,0,0,0,0,1,0,20], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#ac08998b625def30d377e05abb8a80f8d":[1,0,0,0,0,1,0,45], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#ac61c2b578af2d5563ef677172196d04d":[1,0,0,0,0,1,0,28], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#ac645b2eedd096132b613ed5c0b6ecc2f":[1,0,0,0,0,1,0,16], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#ac645b2eedd096132b613ed5c0b6ecc2f":[1,0,0,0,0,1,0,17], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#ac6df07abc427e5ad2ba3167a2d8c109b":[1,0,0,0,0,1,0,44], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#ad239df6d03a59f3a85506346931b52a1":[1,0,0,0,0,1,0,29], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aded82e5731dc626c167ea7437551ad6d":[1,0,0,0,0,1,0,21], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aded82e5731dc626c167ea7437551ad6d":[1,0,0,0,0,1,0,22], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#ae1296701871fe33af919ca9423cadd7a":[1,0,0,0,0,1,0,33], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#ae46e26479d9e1d5c57605c97343fd0f4":[1,0,0,0,0,1,0,47], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#ae897ee6968f1b84641861cda05859a6a":[1,0,0,0,0,1,0,14], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aea179b27f1dc4b7ed1ad3e2cb971a7a8":[1,0,0,0,0,1,0,6], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#ae897ee6968f1b84641861cda05859a6a":[1,0,0,0,0,1,0,15], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aea179b27f1dc4b7ed1ad3e2cb971a7a8":[1,0,0,0,0,1,0,7], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aed55c3ce811dbb765d761f3b90b8ff96":[1,0,0,0,0,1,0,37], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#aed83b0c4e2180511a242f1ccedd3d03c":[1,0,0,0,0,1,0,26], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#af300d862a83d6f973d78081cde32ab99":[1,0,0,0,0,1,0,11], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#af7371642d2f1d673a4d20fd05be9e983":[1,0,0,0,0,1,0,15], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#af300d862a83d6f973d78081cde32ab99":[1,0,0,0,0,1,0,12], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#af7371642d2f1d673a4d20fd05be9e983":[1,0,0,0,0,1,0,16], "classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#af8fe71975e2d06a5eac90781f5555d07":[1,0,0,0,0,1,0,2], -"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#afc92150da6c98b93a9f86439a0d33e3d":[1,0,0,0,0,1,0,18], +"classpolar_1_1com_1_1sdk_1_1impl_1_1BDBleApiImpl.html#afc92150da6c98b93a9f86439a0d33e3d":[1,0,0,0,0,1,0,19], "enumpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1RecordingInterval.html":[1,0,0,0,0,0,2,1], "enumpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1RecordingInterval.html#a393dd3e19d57d5f0a9a256f275050f4b":[1,0,0,0,0,0,2,1,2], "enumpolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1RecordingInterval.html#a4a931111cd9d6b0103000bbd7e9aee8a":[1,0,0,0,0,0,2,1,0], @@ -228,18 +229,18 @@ var NAVTREEINDEX0 = "interfacepolar_1_1com_1_1sdk_1_1api_1_1PolarBleApi_1_1PolarBleApiLogger.html#ae55d724f7a34d52fab2f781993d4efcc":[1,0,0,0,0,0,2,0,0], "namespacepolar.html":[1,0,0], "namespacepolar.html":[0,0,0], -"namespacepolar_1_1com.html":[0,0,0,0], "namespacepolar_1_1com.html":[1,0,0,0], -"namespacepolar_1_1com_1_1sdk.html":[0,0,0,0,0], +"namespacepolar_1_1com.html":[0,0,0,0], "namespacepolar_1_1com_1_1sdk.html":[1,0,0,0,0], +"namespacepolar_1_1com_1_1sdk.html":[0,0,0,0,0], "namespacepolar_1_1com_1_1sdk_1_1api.html":[1,0,0,0,0,0], "namespacepolar_1_1com_1_1sdk_1_1api.html":[0,0,0,0,0,0], "namespacepolar_1_1com_1_1sdk_1_1api_1_1errors.html":[0,0,0,0,0,0,0], "namespacepolar_1_1com_1_1sdk_1_1api_1_1errors.html":[1,0,0,0,0,0,0], -"namespacepolar_1_1com_1_1sdk_1_1api_1_1model.html":[0,0,0,0,0,0,1], "namespacepolar_1_1com_1_1sdk_1_1api_1_1model.html":[1,0,0,0,0,0,1], -"namespacepolar_1_1com_1_1sdk_1_1impl.html":[1,0,0,0,0,1], +"namespacepolar_1_1com_1_1sdk_1_1api_1_1model.html":[0,0,0,0,0,0,1], "namespacepolar_1_1com_1_1sdk_1_1impl.html":[0,0,0,0,0,1], +"namespacepolar_1_1com_1_1sdk_1_1impl.html":[1,0,0,0,0,1], "namespaces.html":[0,0], "pages.html":[] }; diff --git a/polar-sdk-ios/docs/API Default Implementation.html b/polar-sdk-ios/docs/API Default Implementation.html index dc599539..e57191e5 100644 --- a/polar-sdk-ios/docs/API Default Implementation.html +++ b/polar-sdk-ios/docs/API Default Implementation.html @@ -119,14 +119,6 @@
        • - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -