Skip to content

Commit 1290c43

Browse files
committed
RxFit methods are now non-static for better testability. Dependency updates.
1 parent a6fe60c commit 1290c43

File tree

57 files changed

+1392
-893
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1392
-893
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ android:
99
- tools
1010

1111
# The BuildTools version used by your project
12-
- build-tools-24.0.0
12+
- build-tools-24.0.2
1313

1414
# The SDK version used to compile your project
1515
- android-24

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## Version 1.4.0
4+
5+
* Updated Play Services (9.6.1) and RxJava (1.2.0).
6+
* RxFit no longer provides static methods. Create an instance once and share it, e.g. via dependency injection or by providing the instance via your Application class.
7+
38
## Version 1.3.0
49

510
* Updated to Play Services 9.2.0.

README.md

+11-6
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ This library wraps the Fit API in [RxJava](https://github.com/ReactiveX/RxJava)
66

77
# Usage
88

9-
Initialize RxFit once, preferably in your Application `onCreate()` via `RxFit.init(...)`. Make sure to include all the APIs and Scopes that you need for your app. The RxFit class is very similar to the Fitness class provided by the Fit API. Instead of `Fitness.HistoryApi.readData(apiClient, dataReadRequest)` you can use `RxFit.History.read(dataReadRequest)`. Make sure to have the Location and Body Sensors permission from Marshmallow on, if they are needed by your Fit API requests. If the user didn’t already authorize your app for using fitness data, the lib handles showing the authorization dialog.
9+
Create an RxFit instance once, preferably in your Application's `onCreate()` or by using a dependency injection framework. Make sure to include all the APIs and Scopes that you need for your app. The RxFit class is very similar to the Fitness class provided by the Fit API. Instead of `Fitness.HistoryApi.readData(apiClient, dataReadRequest)` you can use `rxFit.history().read(dataReadRequest)`. Make sure to have the Location and Body Sensors permission from Marshmallow on, if they are needed by your Fit API requests. If the user didn’t already authorize your app for using fitness data, the lib handles showing the authorization dialog.
1010

1111
Example:
1212

1313
```java
14-
RxFit.init(
14+
// Create one instance and share it
15+
RxFit rxfit = new RxFit(
1516
context,
1617
new Api[] { Fitness.HISTORY_API },
1718
new Scope[] { new Scope(Scopes.FITNESS_ACTIVITY_READ) }
@@ -24,16 +25,16 @@ DataReadRequest dataReadRequest = new DataReadRequest.Builder()
2425
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
2526
.build();
2627

27-
RxFit.History.read(dataReadRequest)
28+
rxFit.history().read(dataReadRequest)
2829
.flatMapObservable(dataReadResult -> Observable.from(dataReadResult.getBuckets()))
2930
.subscribe(bucket -> {
3031
/* do something */
3132
});
3233
```
3334

34-
An `OnExceptionResumeNext` Transformer is available in the lib, which resumes with another Single/Observable when an Exception is thrown, except when the exception was a GoogleAPIConnectionException which was caused by an unresolved resolution.
35+
An `RxFitOnExceptionResumeNext` Transformer is available in the lib, which resumes with another Single/Observable when an Exception is thrown, except when the exception was a GoogleAPIConnectionException which was caused by an unresolved resolution.
3536

36-
An optional global default timeout for all Fit API requests made through the library can be set via `RxFit.setDefaultTimeout(...)`. In addition, timeouts can be set when creating a new Observable by providing timeout parameters, e.g. `RxFit.History.read(dataReadRequest, 15, TimeUnit.SECONDS)`. These parameters override the default timeout. When a timeout occurs, a StatusException is provided via `onError()`. The RxJava timeout operators can be used instead, but these do not cancel the Fit API request immediately.
37+
An optional global default timeout for all Fit API requests made through the library can be set via `rxFit.setDefaultTimeout(...)`. In addition, timeouts can be set when creating a new Observable by providing timeout parameters, e.g. `rxFit.history().read(dataReadRequest, 15, TimeUnit.SECONDS)`. These parameters override the default timeout. When a timeout occurs, a StatusException is provided via `onError()`. The RxJava timeout operators can be used instead, but these do not cancel the Fit API request immediately.
3738

3839
You can also obtain a `Single<GoogleApiClient>`, which connects on subscribe and disconnects on unsubscribe via `GoogleAPIClientSingle.create(...)`.
3940

@@ -53,9 +54,13 @@ A basic sample app is available in the `sample` project. You need to create an O
5354
The lib is available on jCenter. Add the following to your `build.gradle`:
5455

5556
dependencies {
56-
compile 'com.patloew.rxfit:rxfit:1.3.0'
57+
compile 'com.patloew.rxfit:rxfit:1.4.0'
5758
}
5859

60+
# Testing
61+
62+
When unit testing your app's classes, RxFit behavior can be mocked easily. See the `MainPresenterTest` in the `sample` project for an example test.
63+
5964
# Credits
6065

6166
The code for managing the GoogleApiClient is taken from the [Android-ReactiveLocation](https://github.com/mcharmas/Android-ReactiveLocation) library by Michał Charmas, which is licensed under the Apache License, Version 2.0.

build.gradle

+4-7
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,17 @@ buildscript {
55
jcenter()
66
}
77
dependencies {
8-
classpath 'com.android.tools.build:gradle:2.1.2'
8+
classpath 'com.android.tools.build:gradle:2.2.0'
99

10-
classpath 'me.tatarka:gradle-retrolambda:3.3.0-beta4'
11-
classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
10+
classpath 'me.tatarka:gradle-retrolambda:3.3.0'
1211

13-
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'
14-
classpath "com.github.dcendents:android-maven-gradle-plugin:1.3"
12+
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.1'
13+
classpath "com.github.dcendents:android-maven-gradle-plugin:1.5"
1514

1615

1716
// NOTE: Do not place your application dependencies here; they belong
1817
// in the individual module build.gradle files
1918
}
20-
21-
configurations.classpath.exclude group: 'com.android.tools.external.lombok'
2219
}
2320

2421
allprojects {

gradle/wrapper/gradle-wrapper.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-all.zip

library/build.gradle

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@ apply plugin: 'com.jfrog.bintray'
33
apply plugin: 'com.github.dcendents.android-maven'
44

55
group = 'com.patloew.rxfit'
6-
version = '1.3.0'
6+
version = '1.4.0'
77
project.archivesBaseName = 'rxfit'
88

99
android {
1010
compileSdkVersion 24
11-
buildToolsVersion "24.0.0"
11+
buildToolsVersion "24.0.2"
1212

1313
defaultConfig {
1414
minSdkVersion 9
1515
targetSdkVersion 24
16-
versionCode 6
17-
versionName "1.3.0"
16+
versionCode 7
17+
versionName "1.4.0"
1818
}
1919
buildTypes {
2020
release {
@@ -32,8 +32,8 @@ android {
3232

3333
dependencies {
3434
compile fileTree(dir: 'libs', include: ['*.jar'])
35-
compile 'io.reactivex:rxjava:1.1.6'
36-
compile 'com.google.android.gms:play-services-fitness:9.2.0'
35+
compile 'io.reactivex:rxjava:1.2.0'
36+
compile 'com.google.android.gms:play-services-fitness:9.6.1'
3737

3838
testCompile 'junit:junit:4.12'
3939
testCompile 'org.mockito:mockito-core:1.10.19'

library/src/main/java/com/patloew/rxfit/BaseObservable.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
* FILE MODIFIED by Patrick Löwenstein, 2016
4040
*
4141
*/
42-
public abstract class BaseObservable<T> extends BaseRx<T> implements Observable.OnSubscribe<T> {
42+
abstract class BaseObservable<T> extends BaseRx<T> implements Observable.OnSubscribe<T> {
4343
private final boolean handleResolution;
4444

4545
private final Map<GoogleApiClient, Subscriber<? super T>> subscriptionInfoMap = new ConcurrentHashMap<>();

library/src/main/java/com/patloew/rxfit/BaseRx.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
* FILE MODIFIED by Patrick Löwenstein, 2016
3535
*
3636
*/
37-
public abstract class BaseRx<T> {
37+
abstract class BaseRx<T> {
3838
protected static final Set<BaseRx> observableSet = new HashSet<>();
3939

4040
protected final Context ctx;
@@ -44,16 +44,16 @@ public abstract class BaseRx<T> {
4444
private final TimeUnit timeoutUnit;
4545

4646
protected BaseRx(@NonNull RxFit rxFit, Long timeout, TimeUnit timeUnit) {
47-
this.ctx = rxFit.getContext();
48-
this.services = rxFit.getApis();
49-
this.scopes = rxFit.getScopes();
47+
this.ctx = rxFit.ctx;
48+
this.services = rxFit.apis;
49+
this.scopes = rxFit.scopes;
5050

5151
if(timeout != null && timeUnit != null) {
5252
this.timeoutTime = timeout;
5353
this.timeoutUnit = timeUnit;
5454
} else {
55-
this.timeoutTime = RxFit.getDefaultTimeout();
56-
this.timeoutUnit = RxFit.getDefaultTimeoutUnit();
55+
this.timeoutTime = rxFit.timeoutTime;
56+
this.timeoutUnit = rxFit.timeoutUnit;
5757
}
5858
}
5959

library/src/main/java/com/patloew/rxfit/BaseSingle.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
* FILE MODIFIED by Patrick Löwenstein, 2016
4040
*
4141
*/
42-
public abstract class BaseSingle<T> extends BaseRx<T> implements Single.OnSubscribe<T> {
42+
abstract class BaseSingle<T> extends BaseRx<T> implements Single.OnSubscribe<T> {
4343
private final boolean handleResolution;
4444

4545
private final Map<GoogleApiClient, SingleSubscriber<? super T>> subscriptionInfoMap = new ConcurrentHashMap<>();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
package com.patloew.rxfit;
2+
3+
import android.support.annotation.NonNull;
4+
import android.support.annotation.RequiresPermission;
5+
6+
import com.google.android.gms.common.api.Status;
7+
import com.google.android.gms.fitness.data.BleDevice;
8+
import com.google.android.gms.fitness.data.DataType;
9+
10+
import java.util.List;
11+
import java.util.concurrent.TimeUnit;
12+
13+
import rx.Observable;
14+
import rx.Single;
15+
import rx.functions.Func1;
16+
17+
/* Copyright 2016 Patrick Löwenstein
18+
*
19+
* Licensed under the Apache License, Version 2.0 (the "License");
20+
* you may not use this file except in compliance with the License.
21+
* You may obtain a copy of the License at
22+
*
23+
* http://www.apache.org/licenses/LICENSE-2.0
24+
*
25+
* Unless required by applicable law or agreed to in writing, software
26+
* distributed under the License is distributed on an "AS IS" BASIS,
27+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28+
* See the License for the specific language governing permissions and
29+
* limitations under the License. */
30+
public class Ble {
31+
32+
private final RxFit rxFit;
33+
34+
Ble(RxFit rxFit) {
35+
this.rxFit = rxFit;
36+
}
37+
38+
// claimDevice
39+
40+
public Single<Status> claimDevice(@NonNull BleDevice bleDevice) {
41+
return claimDeviceInternal(bleDevice, null, null, null);
42+
}
43+
44+
public Single<Status> claimDevice(@NonNull BleDevice bleDevice, long timeout, @NonNull TimeUnit timeUnit) {
45+
return claimDeviceInternal(bleDevice, null, timeout, timeUnit);
46+
}
47+
48+
public Single<Status> claimDevice(@NonNull String deviceAddress) {
49+
return claimDeviceInternal(null, deviceAddress, null, null);
50+
}
51+
52+
public Single<Status> claimDevice(@NonNull String deviceAddress, long timeout, @NonNull TimeUnit timeUnit) {
53+
return claimDeviceInternal(null, deviceAddress, timeout, timeUnit);
54+
}
55+
56+
private Single<Status> claimDeviceInternal(BleDevice bleDevice, String deviceAddress, Long timeout, TimeUnit timeUnit) {
57+
return Single.create(new BleClaimDeviceSingle(rxFit, bleDevice, deviceAddress, timeout, timeUnit));
58+
}
59+
60+
// getClaimedDevices
61+
62+
public Observable<BleDevice> getClaimedDevices() {
63+
return getClaimedDeviceListInternal(null, null, null);
64+
}
65+
66+
public Observable<BleDevice> getClaimedDevices(long timeout, @NonNull TimeUnit timeUnit) {
67+
return getClaimedDeviceListInternal(null, timeout, timeUnit);
68+
}
69+
70+
public Observable<BleDevice> getClaimedDevices(DataType dataType) {
71+
return getClaimedDeviceListInternal(dataType, null, null);
72+
}
73+
74+
private Observable<BleDevice> getClaimedDevicesInternal(DataType dataType, long timeout, @NonNull TimeUnit timeUnit) {
75+
return getClaimedDeviceListInternal(dataType, timeout, timeUnit);
76+
}
77+
78+
private Observable<BleDevice> getClaimedDeviceListInternal(DataType dataType, Long timeout, TimeUnit timeUnit) {
79+
return Single.create(new BleListClaimedDevicesSingle(rxFit, dataType, timeout, timeUnit))
80+
.flatMapObservable(new Func1<List<BleDevice>, Observable<BleDevice>>() {
81+
@Override
82+
public Observable<BleDevice> call(List<BleDevice> bleDevices) {
83+
return Observable.from(bleDevices);
84+
}
85+
});
86+
}
87+
88+
// scan
89+
90+
@RequiresPermission("android.permission.BLUETOOTH_ADMIN")
91+
public Observable<BleDevice> scan() {
92+
return scanInternal(null, null, null, null);
93+
}
94+
95+
@RequiresPermission("android.permission.BLUETOOTH_ADMIN")
96+
public Observable<BleDevice> scan(long timeout, @NonNull TimeUnit timeUnit) {
97+
return scanInternal(null, null, timeout, timeUnit);
98+
}
99+
100+
@RequiresPermission("android.permission.BLUETOOTH_ADMIN")
101+
public Observable<BleDevice> scan(@NonNull DataType... dataTypes) {
102+
return scanInternal(dataTypes, null, null, null);
103+
}
104+
105+
@RequiresPermission("android.permission.BLUETOOTH_ADMIN")
106+
public Observable<BleDevice> scan(@NonNull DataType[] dataTypes, long timeout, @NonNull TimeUnit timeUnit) {
107+
return scanInternal(dataTypes, null, timeout, timeUnit);
108+
}
109+
110+
@RequiresPermission("android.permission.BLUETOOTH_ADMIN")
111+
public Observable<BleDevice> scan(int stopTimeSecs) {
112+
return scanInternal(null, stopTimeSecs, null, null);
113+
}
114+
115+
@RequiresPermission("android.permission.BLUETOOTH_ADMIN")
116+
public Observable<BleDevice> scan(int stopTimeSecs, long timeout, @NonNull TimeUnit timeUnit) {
117+
return scanInternal(null, stopTimeSecs, timeout, timeUnit);
118+
}
119+
120+
@RequiresPermission("android.permission.BLUETOOTH_ADMIN")
121+
public Observable<BleDevice> scan(@NonNull DataType[] dataTypes, int stopTimeSecs) {
122+
return scanInternal(dataTypes, stopTimeSecs, null, null);
123+
}
124+
125+
@RequiresPermission("android.permission.BLUETOOTH_ADMIN")
126+
public Observable<BleDevice> scan(@NonNull DataType[] dataTypes, int stopTimeSecs, long timeout, @NonNull TimeUnit timeUnit) {
127+
return scanInternal(dataTypes, stopTimeSecs, timeout, timeUnit);
128+
}
129+
130+
@SuppressWarnings("MissingPermission")
131+
private Observable<BleDevice> scanInternal(DataType[] dataTypes, Integer stopTimeSecs, Long timeout, TimeUnit timeUnit) {
132+
return Observable.create(new BleScanObservable(rxFit, dataTypes, stopTimeSecs, timeout, timeUnit));
133+
}
134+
135+
// unclaim Device
136+
137+
public Single<Status> unclaimDevice(@NonNull BleDevice bleDevice) {
138+
return unclaimDeviceInternal(bleDevice, null, null, null);
139+
}
140+
141+
public Single<Status> unclaimDevice(@NonNull BleDevice bleDevice, long timeout, @NonNull TimeUnit timeUnit) {
142+
return unclaimDeviceInternal(bleDevice, null, timeout, timeUnit);
143+
}
144+
145+
public Single<Status> unclaimDevice(@NonNull String deviceAddress) {
146+
return unclaimDeviceInternal(null, deviceAddress, null, null);
147+
}
148+
149+
public Single<Status> unclaimDevice(@NonNull String deviceAddress, long timeout, @NonNull TimeUnit timeUnit) {
150+
return unclaimDeviceInternal(null, deviceAddress, timeout, timeUnit);
151+
}
152+
153+
private Single<Status> unclaimDeviceInternal(BleDevice bleDevice, String deviceAddress, Long timeout, TimeUnit timeUnit) {
154+
return Single.create(new BleUnclaimDeviceSingle(rxFit, bleDevice, deviceAddress, timeout, timeUnit));
155+
}
156+
157+
}

library/src/main/java/com/patloew/rxfit/BleClaimDeviceSingle.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2424
* See the License for the specific language governing permissions and
2525
* limitations under the License. */
26-
public class BleClaimDeviceSingle extends BaseSingle<Status> {
26+
class BleClaimDeviceSingle extends BaseSingle<Status> {
2727

2828
private final BleDevice bleDevice;
2929
private final String deviceAddress;

library/src/main/java/com/patloew/rxfit/BleListClaimedDevicesSingle.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2828
* See the License for the specific language governing permissions and
2929
* limitations under the License. */
30-
public class BleListClaimedDevicesSingle extends BaseSingle<List<BleDevice>> {
30+
class BleListClaimedDevicesSingle extends BaseSingle<List<BleDevice>> {
3131

3232
private final DataType dataType;
3333

library/src/main/java/com/patloew/rxfit/BleScanObservable.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3030
* See the License for the specific language governing permissions and
3131
* limitations under the License. */
32-
public class BleScanObservable extends BaseObservable<BleDevice> {
32+
class BleScanObservable extends BaseObservable<BleDevice> {
3333

3434
private final DataType[] dataTypes;
3535
private final Integer stopTimeSecs;

library/src/main/java/com/patloew/rxfit/BleUnclaimDeviceSingle.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2424
* See the License for the specific language governing permissions and
2525
* limitations under the License. */
26-
public class BleUnclaimDeviceSingle extends BaseSingle<Status> {
26+
class BleUnclaimDeviceSingle extends BaseSingle<Status> {
2727

2828
private final BleDevice bleDevice;
2929
private final String deviceAddress;

library/src/main/java/com/patloew/rxfit/CheckConnectionObservable.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1818
* See the License for the specific language governing permissions and
1919
* limitations under the License. */
20-
public class CheckConnectionObservable extends BaseObservable<Void> {
20+
class CheckConnectionObservable extends BaseObservable<Void> {
2121

2222
CheckConnectionObservable(RxFit rxFit) {
2323
super(rxFit, null, null);

0 commit comments

Comments
 (0)