Skip to content

Commit 01f82eb

Browse files
committed
Latest updates from private repo, including refactored Android service architecture
1 parent c8923ef commit 01f82eb

File tree

70 files changed

+2418
-438
lines changed

Some content is hidden

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

70 files changed

+2418
-438
lines changed

CHANGELOG.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,49 @@
11
# Change Log
22

3+
## [3.0.0-beta.1] - 2019-02-27
4+
- [Changed] Major refactor of Android Service architecture. The SDK no longer requires a foreground-service active at all times. The foreground-service (and cooresponding persistent notification) will only be active while the SDK is in the *moving* state. No breaking dart api changes.
5+
- [Changed] Improved Android debug notifications.
6+
7+
- [Added] Added new Config options `persistMode` for specifying exactly which events get persisted: location | geofence | all | none.
8+
- [Added] Experimental Android-only Config option `speedJumpFilter (default 300 meters/second)` for detecting location anomalies. The plugin will measure the distance and apparent speed of the current location relative to last location. If the apparent speed is > `speedJumpFilter`, the location will be ignored. Some users, particularly in Australia, curiously, have had locations suddenly jump hundreds of kilometers away, into the ocean.
9+
- [Changed] iOS and Android will not perform odometer updates when the calculated distance is less than the average accuracy of the current and previous location. This is to prevent small odometer changes when the device is lingering around the same position.
10+
- [Fixed] Added Android gradle dependency `appcompat-v7`
11+
- [Fixed] Minor change to Android `HeadlessTask` to fix possible issue with `Looper`.
12+
13+
- [Added] New `DeviceSettings` API for redirecting user to Android Settings screens, including vendor-specific screens (eg: Huawei, OnePlus, Xiaomi, etc). This is an attempt to help direct the user to appropriate device-settings screens for poor Android vendors as detailed in the site [Don't kill my app](https://dontkillmyapp.com/).
14+
- [Added] `schedule` can now be configured to optionally execute geofences-only mode (ie: `#startGeofences`) per schedule entry. See `schedule` docs.
15+
- [Changed] Update Gradle config to use `implementation` instead of deprecated `compile`
16+
- **[BREAKING]** Change Gradle `ext` configuration property `googlePlayServicesVersion` -> `googlePlayServicesLocationVersion`. Now that Google has decoupled all their libraries, `play-services:location` now has its own version, independant of all other libs.
17+
18+
`android/build.gradle`:
19+
```diff
20+
buildscript {
21+
ext {
22+
buildToolsVersion = "28.0.3"
23+
minSdkVersion = 16
24+
compileSdkVersion = 28
25+
targetSdkVersion = 27
26+
supportLibVersion = "28.0.0"
27+
- googlePlayServicesVersion = "16.0.0"
28+
+ googlePlayServicesLocationVersion = "16.0.0"
29+
}
30+
}
31+
```
32+
33+
- [Changed] Android Service: Return `START_STICKY` instead of `START_REDELIVER_INTENT`.
34+
- [Changed] Android: `setShowBadge(false)` on Android `NotificationChannel`. Some users reporting that Android shows a badge-count on app icon when service is started / stopped.
35+
36+
- [Fixed] Android `extras` provided to `watchPosition` were not being appended to location data.
37+
38+
- [Fixed] Android NPE in `watchPosition`
39+
- [Added] Added method `getProviderState` for querying current state of location-services.
40+
- [Added] Added method `requestPermission` for manually requesting location-permission (`#start`, `#getCurrentPosition`, `#watchPosition` etc, will already automatically request permission.
41+
42+
- [Changed] Upgrade Android logger dependency to latest version (`logback`).
43+
- [Fixed] Prevent Android foreground-service from auto-starting when location permission is revoked via Settings screen.
44+
- [Fixed] NPE in Android HTTP Service when manual sync is called. Probably a threading issue with multiple sync operations executed simultaneously.
45+
46+
347
## [2.14.2] 2018-11-20
448
- [Added] Android SDK 28 requires new permission to use foreground-service.
549
- [Fixed] Do not calculate odometer with geofence events. Android geofence event's location timestamp does not correspond with the actual time the geofence fires since Android is performing some heuristics in the background to ensure the potential geofence event is not a false positive. The actual geofence event can fire some minutes in the future (ie: the location timestamp will be some minutues in the past). Using geofence location in odometer calculations will corrupt the odometer value.

README.md

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ The plugin's [Philosophy of Operation](../../wiki/Philosophy-of-Operation) is to
1313

1414
- When the device is detected be **stationary**, the plugin will automatically turn off location-services to conserve energy.
1515

16-
Also available for [Cordova](https://github.com/transistorsoft/cordova-background-geolocation-lt), [NativeScript](https://github.com/transistorsoft/nativescript-background-geolocation-lt) and pure native apps.
16+
Also available for [Flutter](https://github.com/transistorsoft/flutter_background_geolocation), [Cordova](https://github.com/transistorsoft/cordova-background-geolocation-lt), [NativeScript](https://github.com/transistorsoft/nativescript-background-geolocation-lt) and pure native apps.
1717

1818
----------------------------------------------------------------------------
1919

@@ -42,6 +42,13 @@ The **[Android module](http://www.transistorsoft.com/shop/products/react-native-
4242

4343
## :large_blue_diamond: Installing the Plugin
4444

45+
### With `yarn`
46+
47+
```bash
48+
yarn add react-native-background-geolocation
49+
```
50+
51+
### With `npm`
4552
```
4653
$ npm install react-native-background-geolocation --save
4754
```
@@ -57,15 +64,6 @@ $ npm install react-native-background-geolocation --save
5764
* [`react-native link` Setup](help/INSTALL-ANDROID-RNPM.md)
5865
* [Manual Setup](help/INSTALL-ANDROID.md)
5966

60-
#### :information_source: Solving Android Gradle Conflicts.
61-
62-
Once of the most common build-issues with Android apps are gradle conflicts between modules specifying different versions of:
63-
- `compileSdkVersion`
64-
- `buildToolsVersion`
65-
- Google `play-services` / `firebase` version.
66-
- Google support libraries (ie `appcompat-v4`, `appcompat-v7`)
67-
68-
For more information, see the Wiki [Solving Android Gradle Conflicts](../../wiki/Solving-Android-Gradle-Conflicts)
6967

7068
## :large_blue_diamond: Configure your license
7169

@@ -119,7 +117,7 @@ import BackgroundGeolocation, {
119117
MotionChangeEvent,
120118
ProviderChangeEvent,
121119
ConnectivityChangeEvent
122-
} from "react-native-background-geolocation-android";
120+
} from "react-native-background-geolocation";
123121

124122
```
125123

android/build.gradle

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,53 @@
11
apply plugin: 'com.android.library'
22

3-
def DEFAULT_COMPILE_SDK_VERSION = 27
4-
def DEFAULT_BUILD_TOOLS_VERSION = "27.0.3"
5-
def DEFAULT_TARGET_SDK_VERSION = 27
6-
def DEFAULT_PLAY_SERVICES_VERSION = "16.0.0"
3+
// Android dependencies
4+
def DEFAULT_COMPILE_SDK_VERSION = 28
5+
def DEFAULT_BUILD_TOOLS_VERSION = "28.0.3"
6+
def DEFAULT_TARGET_SDK_VERSION = 27
7+
def DEFAULT_SUPPORT_LIB_VERSION = "28.0.0"
8+
9+
// Plugin dependencies
10+
def DEFAULT_GOOGLE_PLAY_SERVICES_LOCATION_VERSION = "16.0.0"
11+
def DEFAULT_OK_HTTP_VERSION = "3.12.1"
12+
def DEFAULT_ANDROID_PERMISSIONS_VERSION = "0.1.7"
13+
def DEFAULT_EVENTBUS_VERSION = "3.0.0"
14+
15+
def safeExtGet(prop, fallback) {
16+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
17+
}
718

819
android {
9-
compileSdkVersion rootProject.hasProperty('compileSdkVersion') ? rootProject.compileSdkVersion : DEFAULT_COMPILE_SDK_VERSION
10-
buildToolsVersion rootProject.hasProperty('buildToolsVersion') ? rootProject.buildToolsVersion : DEFAULT_BUILD_TOOLS_VERSION
20+
compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
21+
buildToolsVersion safeExtGet('buildToolsVersion', DEFAULT_BUILD_TOOLS_VERSION)
1122

1223
defaultConfig {
1324
minSdkVersion 16
14-
targetSdkVersion rootProject.hasProperty('targetSdkVersion') ? rootProject.targetSdkVersion : DEFAULT_TARGET_SDK_VERSION
25+
targetSdkVersion safeExtGet('targetSdkVersion', DEFAULT_TARGET_SDK_VERSION)
1526
versionCode 1
1627
versionName "1.0"
1728
}
1829
}
1930

2031
repositories{
21-
jcenter()
2232
maven {
2333
url './libs'
2434
}
25-
maven {
26-
url 'https://maven.google.com'
27-
}
2835
}
2936

3037
dependencies {
31-
// Check for application-defined play-services version
32-
def playServicesVersion = DEFAULT_PLAY_SERVICES_VERSION
33-
if (rootProject.hasProperty('playServicesVersion')) {
34-
playServicesVersion = rootProject.playServicesVersion
35-
} else if (rootProject.hasProperty('googlePlayServicesVersion')) {
36-
playServicesVersion = rootProject.googlePlayServicesVersion
37-
}
38-
compile 'com.facebook.react:react-native:+'
39-
compile "com.google.android.gms:play-services-location:$playServicesVersion"
40-
compile 'org.greenrobot:eventbus:3.0.0'
41-
compile 'com.squareup.okhttp3:okhttp:3.10.0'
42-
compile(group: 'com.transistorsoft', name:'tslocationmanager', version: '+')
43-
compile 'org.slf4j:slf4j-api:1.7.21'
44-
compile 'com.github.tony19:logback-android:1.1.1-9'
45-
// android-permissions
46-
compile 'com.intentfilter:android-permissions:0.1.6'
38+
def supportLibVersion = safeExtGet('supportLibVersion', DEFAULT_SUPPORT_LIB_VERSION)
39+
def playServicesLocationVersion = safeExtGet('googlePlayServicesLocationVersion', DEFAULT_GOOGLE_PLAY_SERVICES_LOCATION_VERSION)
40+
def okHttpVersion = safeExtGet('okHttpVersion', DEFAULT_OK_HTTP_VERSION)
41+
def androidPermissionsVersion = safeExtGet('androidPermissionsVersion', DEFAULT_ANDROID_PERMISSIONS_VERSION)
42+
def eventBusVersion = safeExtGet('eventBusVersion', DEFAULT_EVENTBUS_VERSION)
43+
44+
compileOnly 'com.facebook.react:react-native:+'
45+
implementation "com.android.support:appcompat-v7:$supportLibVersion"
46+
implementation "com.google.android.gms:play-services-location:$playServicesLocationVersion"
47+
implementation "org.greenrobot:eventbus:$eventBusVersion"
48+
implementation "com.squareup.okhttp3:okhttp:$okHttpVersion"
49+
implementation(group: 'com.transistorsoft', name:'tslocationmanager', version: '+')
50+
implementation 'org.slf4j:slf4j-api:1.7.25'
51+
implementation 'com.github.tony19:logback-android:1.3.0-2'
52+
implementation "com.intentfilter:android-permissions:$androidPermissionsVersion"
4753
}

android/libs/com/transistorsoft/tslocationmanager/2.14.4/tslocationmanager-2.14.4.aar.md5

Lines changed: 0 additions & 1 deletion
This file was deleted.

android/libs/com/transistorsoft/tslocationmanager/2.14.4/tslocationmanager-2.14.4.aar.sha1

Lines changed: 0 additions & 1 deletion
This file was deleted.

android/libs/com/transistorsoft/tslocationmanager/2.14.4/tslocationmanager-2.14.4.pom.md5

Lines changed: 0 additions & 1 deletion
This file was deleted.

android/libs/com/transistorsoft/tslocationmanager/2.14.4/tslocationmanager-2.14.4.pom.sha1

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5554d19be6e53de92164fa38b1f107c1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1d140525edd12b61985f7544167284ca179fff73

android/libs/com/transistorsoft/tslocationmanager/2.14.4/tslocationmanager-2.14.4.pom renamed to android/libs/com/transistorsoft/tslocationmanager/3.0.0/tslocationmanager-3.0.0.pom

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>com.transistorsoft</groupId>
66
<artifactId>tslocationmanager</artifactId>
7-
<version>2.14.4</version>
7+
<version>3.0.0</version>
88
<packaging>aar</packaging>
99
</project>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0118ce926df6a96c0ea8960becb9f846
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
13c34b6c1a6166f978ee0903f9fa36807a93b8f9

android/libs/com/transistorsoft/tslocationmanager/maven-metadata.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
<groupId>com.transistorsoft</groupId>
44
<artifactId>tslocationmanager</artifactId>
55
<versioning>
6-
<release>2.14.4</release>
6+
<release>3.0.0</release>
77
<versions>
8-
<version>2.14.4</version>
8+
<version>3.0.0</version>
99
</versions>
10-
<lastUpdated>20181120172613</lastUpdated>
10+
<lastUpdated>20190227224055</lastUpdated>
1111
</versioning>
1212
</metadata>

android/src/main/java/com/transistorsoft/rnbackgroundgeolocation/HeadlessTask.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.content.Context;
44
import android.os.Handler;
5+
import android.os.Looper;
56

67
import com.facebook.react.ReactApplication;
78
import com.facebook.react.ReactInstanceManager;
@@ -34,7 +35,6 @@ public class HeadlessTask {
3435
private static String HEADLESS_TASK_NAME = "BackgroundGeolocation";
3536
// Hard-coded time-limit for headless-tasks is 30000 @todo configurable?
3637
private static int TASK_TIMEOUT = 30000;
37-
private static Handler mHandler = new Handler();
3838

3939
private final List<Integer> mTasks = new ArrayList<>();
4040

@@ -89,7 +89,7 @@ public void onHeadlessEvent(HeadlessEvent event) {
8989
e.printStackTrace();
9090
}
9191
}
92-
92+
9393
HeadlessJsTaskConfig config = new HeadlessJsTaskConfig(HEADLESS_TASK_NAME, clientEvent, TASK_TIMEOUT);
9494
try {
9595
startTask(event.getContext(), config);
@@ -116,7 +116,7 @@ private void startTask(Context context, final HeadlessJsTaskConfig taskConfig) t
116116
reactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
117117
@Override public void onReactContextInitialized(final ReactContext reactContext) {
118118
// Hack to fix unknown problem executing asynchronous BackgroundTask when ReactContext is created *first time*. Fixed by adding short delay before #invokeStartTask
119-
mHandler.postDelayed(new Runnable() {
119+
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
120120
@Override
121121
public void run() {
122122
invoke(reactContext, taskConfig);

android/src/main/java/com/transistorsoft/rnbackgroundgeolocation/RNBackgroundGeolocationModule.java

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
import android.Manifest;
44
import android.app.Activity;
5+
import android.content.Context;
56
import android.content.Intent;
67
import android.telecom.Call;
78
import android.util.Log;
9+
import android.os.Build;
810

911
import com.facebook.react.bridge.ActivityEventListener;
1012
import com.facebook.react.bridge.Callback;
@@ -15,6 +17,7 @@
1517
import com.facebook.react.bridge.ReadableArray;
1618
import com.facebook.react.bridge.ReadableMap;
1719
import com.facebook.react.bridge.ReadableMapKeySetIterator;
20+
import com.facebook.react.bridge.ReadableNativeMap;
1821
import com.facebook.react.bridge.ReadableType;
1922
import com.facebook.react.bridge.WritableArray;
2023
import com.facebook.react.bridge.WritableMap;
@@ -43,9 +46,12 @@
4346
import com.transistorsoft.locationmanager.location.TSCurrentPositionRequest;
4447
import com.transistorsoft.locationmanager.location.TSLocation;
4548
import com.transistorsoft.locationmanager.location.TSWatchPositionRequest;
49+
import com.transistorsoft.locationmanager.scheduler.TSScheduleManager;
4650
import com.transistorsoft.locationmanager.scheduler.ScheduleEvent;
51+
import com.transistorsoft.locationmanager.event.TerminateEvent;
4752
import com.transistorsoft.locationmanager.util.Sensors;
4853
import com.transistorsoft.locationmanager.logger.TSLog;
54+
import com.transistorsoft.locationmanager.device.DeviceSettingsRequest;
4955

5056
import java.util.ArrayList;
5157
import java.util.HashMap;
@@ -281,7 +287,11 @@ public void onHostResume() {
281287
}
282288
@Override
283289
public void onHostPause() {
284-
290+
Context context = getReactApplicationContext();
291+
TSConfig config = TSConfig.getInstance(context);
292+
if (config.getEnabled() && config.getEnableHeadless() && !config.getStopOnTerminate()) {
293+
TSScheduleManager.getInstance(context).oneShot(TerminateEvent.ACTION, 10000);
294+
}
285295
}
286296
@Override
287297
public void onHostDestroy() {
@@ -687,7 +697,7 @@ public void finish(Integer taskId) {
687697
}
688698

689699
@ReactMethod
690-
public void playSound( int soundId) {
700+
public void playSound(String soundId) {
691701
getAdapter().startTone(soundId);
692702
}
693703

@@ -737,6 +747,57 @@ public void isPowerSaveMode(Callback success, Callback error) {
737747
success.invoke(getAdapter().isPowerSaveMode());
738748
}
739749

750+
@ReactMethod
751+
public void isIgnoringBatteryOptimizations(Callback success, Callback failure) {
752+
boolean isIgnoring = getAdapter().isIgnoringBatteryOptimizations();
753+
success.invoke(isIgnoring);
754+
}
755+
756+
@ReactMethod
757+
public void requestSettings(ReadableMap args, Callback success, Callback failure) throws JSONException {
758+
String action = args.getString("action");
759+
DeviceSettingsRequest request = getAdapter().requestSettings(action);
760+
761+
if (request != null) {
762+
success.invoke(jsonToMap(request.toJson()));
763+
} else {
764+
failure.invoke("Failed to find " + action + " screen for device " + Build.MANUFACTURER + " " + Build.MODEL + "@" + Build.VERSION.RELEASE);
765+
}
766+
}
767+
768+
@ReactMethod
769+
public void showSettings(ReadableMap args, Callback success, Callback failure) {
770+
String action = args.getString("action");
771+
boolean didShow = getAdapter().showSettings(action);
772+
if (didShow) {
773+
success.invoke();
774+
} else {
775+
failure.invoke("Failed to find " + action + " screen for device " + Build.MANUFACTURER + " " + Build.MODEL + "@" + Build.VERSION.RELEASE);
776+
}
777+
}
778+
779+
@ReactMethod
780+
public void getProviderState(Callback success, Callback error) {
781+
try {
782+
success.invoke(jsonToMap(getAdapter().getProviderState().toJson()));
783+
} catch (JSONException e) {
784+
error.invoke(e.getMessage());
785+
}
786+
}
787+
788+
@ReactMethod
789+
public void requestPermission(final Callback success, final Callback error) {
790+
getAdapter().requestPermission(new TSRequestPermissionCallback() {
791+
@Override public void onSuccess(int status) {
792+
success.invoke(status);
793+
}
794+
@Override public void onFailure(int status) {
795+
error.invoke(status);
796+
}
797+
});
798+
}
799+
800+
740801
@ReactMethod
741802
public void addEventListener(String event) {
742803
if (!events.contains(event)) {
@@ -955,15 +1016,6 @@ public static JSONArray arrayToJson(ReadableArray readableArray) throws JSONExce
9551016
return jsonArray;
9561017
}
9571018

958-
// TODO placehold for implementing Android M permissions request. Just return true for now.
959-
private Boolean hasPermission(String permission) {
960-
return true;
961-
}
962-
// TODO placehold for implementing Android M permissions request. Just return true for now.
963-
private void requestPermissions(int requestCode, String[] action) {
964-
965-
}
966-
9671019
private void initializeLocationManager() {
9681020
Activity activity = getCurrentActivity();
9691021
if (activity == null) {

docs/assets/js/search.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)