@josuelmm/capacitor-background-geolocation 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/JosuelmmCapacitorBackgroundGeolocation.podspec +34 -0
- package/LICENSE +17 -0
- package/NOTICE.md +32 -0
- package/Package.swift +45 -0
- package/README.md +402 -0
- package/android/build.gradle +79 -0
- package/android/proguard-rules.pro +1 -0
- package/android/src/main/AndroidManifest.xml +83 -0
- package/android/src/main/java/com/evgenii/jsevaluator/HandlerWrapper.java +18 -0
- package/android/src/main/java/com/evgenii/jsevaluator/JavaScriptInterface.java +22 -0
- package/android/src/main/java/com/evgenii/jsevaluator/JsEvaluator.java +133 -0
- package/android/src/main/java/com/evgenii/jsevaluator/JsFunctionCallFormatter.java +37 -0
- package/android/src/main/java/com/evgenii/jsevaluator/WebViewWrapper.java +71 -0
- package/android/src/main/java/com/evgenii/jsevaluator/interfaces/CallJavaResultInterface.java +8 -0
- package/android/src/main/java/com/evgenii/jsevaluator/interfaces/HandlerWrapperInterface.java +5 -0
- package/android/src/main/java/com/evgenii/jsevaluator/interfaces/JsCallback.java +10 -0
- package/android/src/main/java/com/evgenii/jsevaluator/interfaces/JsEvaluatorInterface.java +18 -0
- package/android/src/main/java/com/evgenii/jsevaluator/interfaces/WebViewWrapperInterface.java +14 -0
- package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/BackgroundGeolocationPlugin.java +898 -0
- package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/ConfigMapper.java +303 -0
- package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/HeadlessTaskRegistry.java +34 -0
- package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/JsEvaluatorTaskRunner.java +63 -0
- package/android/src/main/java/com/marianhello/bgloc/BackgroundGeolocationFacade.java +699 -0
- package/android/src/main/java/com/marianhello/bgloc/BootCompletedReceiver.java +103 -0
- package/android/src/main/java/com/marianhello/bgloc/Config.java +1155 -0
- package/android/src/main/java/com/marianhello/bgloc/ConnectivityListener.java +5 -0
- package/android/src/main/java/com/marianhello/bgloc/HttpPostService.java +362 -0
- package/android/src/main/java/com/marianhello/bgloc/LocationManager.java +138 -0
- package/android/src/main/java/com/marianhello/bgloc/PluginDelegate.java +45 -0
- package/android/src/main/java/com/marianhello/bgloc/PluginException.java +38 -0
- package/android/src/main/java/com/marianhello/bgloc/PostLocationTask.java +238 -0
- package/android/src/main/java/com/marianhello/bgloc/ResourceResolver.java +55 -0
- package/android/src/main/java/com/marianhello/bgloc/data/AbstractLocationTemplate.java +69 -0
- package/android/src/main/java/com/marianhello/bgloc/data/ArrayListLocationTemplate.java +88 -0
- package/android/src/main/java/com/marianhello/bgloc/data/BackgroundActivity.java +108 -0
- package/android/src/main/java/com/marianhello/bgloc/data/BackgroundLocation.java +1088 -0
- package/android/src/main/java/com/marianhello/bgloc/data/ConfigJsonMapper.java +211 -0
- package/android/src/main/java/com/marianhello/bgloc/data/ConfigurationDAO.java +13 -0
- package/android/src/main/java/com/marianhello/bgloc/data/DAOFactory.java +17 -0
- package/android/src/main/java/com/marianhello/bgloc/data/HashMapLocationTemplate.java +82 -0
- package/android/src/main/java/com/marianhello/bgloc/data/LocationDAO.java +27 -0
- package/android/src/main/java/com/marianhello/bgloc/data/LocationTemplate.java +12 -0
- package/android/src/main/java/com/marianhello/bgloc/data/LocationTemplateFactory.java +71 -0
- package/android/src/main/java/com/marianhello/bgloc/data/LocationTransform.java +19 -0
- package/android/src/main/java/com/marianhello/bgloc/data/SessionLocationDAO.java +18 -0
- package/android/src/main/java/com/marianhello/bgloc/data/provider/ContentProviderLocationDAO.java +406 -0
- package/android/src/main/java/com/marianhello/bgloc/data/provider/LocationContentProvider.java +321 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteConfigurationContract.java +94 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteConfigurationDAO.java +227 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteLocationContract.java +122 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteLocationDAO.java +550 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteOpenHelper.java +189 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteSessionContract.java +74 -0
- package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteSessionLocationDAO.java +169 -0
- package/android/src/main/java/com/marianhello/bgloc/driving/DrivingEventsDetector.java +265 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/AbstractTaskRunner.java +15 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/ActivityTask.java +48 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/JsCallback.java +10 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/LocationTask.java +60 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/StationaryTask.java +25 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/Task.java +8 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/TaskRunner.java +5 -0
- package/android/src/main/java/com/marianhello/bgloc/headless/TaskRunnerFactory.java +8 -0
- package/android/src/main/java/com/marianhello/bgloc/http/UrlTemplateResolver.java +115 -0
- package/android/src/main/java/com/marianhello/bgloc/oem/BatteryOemHelper.java +214 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/AbstractLocationProvider.java +218 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/ActivityRecognitionLocationProvider.java +385 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/DistanceFilterLocationProvider.java +685 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/LocationProvider.java +32 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/LocationProviderFactory.java +47 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/ProviderDelegate.java +12 -0
- package/android/src/main/java/com/marianhello/bgloc/provider/RawLocationProvider.java +175 -0
- package/android/src/main/java/com/marianhello/bgloc/sensor/SensorFusionDetector.java +199 -0
- package/android/src/main/java/com/marianhello/bgloc/service/LocationService.java +16 -0
- package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceImpl.java +1531 -0
- package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceInfo.java +6 -0
- package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceInfoImpl.java +41 -0
- package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceIntentBuilder.java +203 -0
- package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceProxy.java +156 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/AccountHelper.java +39 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/Authenticator.java +68 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/AuthenticatorService.java +28 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/BatchManager.java +311 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/NotificationHelper.java +148 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/SyncAdapter.java +301 -0
- package/android/src/main/java/com/marianhello/bgloc/sync/SyncService.java +68 -0
- package/android/src/main/java/com/marianhello/logging/DBLogReader.java +208 -0
- package/android/src/main/java/com/marianhello/logging/LogEntry.java +99 -0
- package/android/src/main/java/com/marianhello/logging/LoggerManager.java +70 -0
- package/android/src/main/java/com/marianhello/logging/UncaughtExceptionLogger.java +36 -0
- package/android/src/main/java/com/marianhello/utils/CloneHelper.java +22 -0
- package/android/src/main/java/com/marianhello/utils/Convert.java +56 -0
- package/android/src/main/java/com/marianhello/utils/TextUtils.java +72 -0
- package/android/src/main/java/com/marianhello/utils/ToneGenerator.java +68 -0
- package/android/src/main/java/org/apache/commons/io/Charsets.java +153 -0
- package/android/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java +344 -0
- package/android/src/main/java/org/chromium/content/browser/ThreadUtils.java +134 -0
- package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlExpression.java +398 -0
- package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlSelectStatement.java +671 -0
- package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlStatement.java +29 -0
- package/android/src/main/java/ru/andremoniy/utils/TextUtils.java +61 -0
- package/android/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/android/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/android/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/android/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/android/src/main/res/values/strings.xml +15 -0
- package/android/src/main/res/xml/authenticator.xml +7 -0
- package/android/src/main/res/xml/syncadapter.xml +9 -0
- package/dist/esm/definitions.d.ts +1052 -0
- package/dist/esm/definitions.js +142 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.js +23 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +92 -0
- package/dist/esm/web.js +242 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +415 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +418 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin-Bridging-Header.h +18 -0
- package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin.m +52 -0
- package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin.swift +750 -0
- package/ios/Tests/BackgroundGeolocationPluginTests/BackgroundGeolocationPluginTests.swift +12 -0
- package/ios/common/BackgroundGeolocation/CocoaLumberjack.h +1945 -0
- package/ios/common/BackgroundGeolocation/CocoaLumberjack.m +5255 -0
- package/ios/common/BackgroundGeolocation/FMDB.h +2357 -0
- package/ios/common/BackgroundGeolocation/FMDB.m +2672 -0
- package/ios/common/BackgroundGeolocation/FMDBLogger.h +42 -0
- package/ios/common/BackgroundGeolocation/FMDBLogger.m +264 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTUHeadingRequest.h +41 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTUHeadingRequest.m +68 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager+Internal.h +33 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager.h +178 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager.m +1025 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequest.h +103 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequest.m +238 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequestDefines.h +163 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTURequestIDGenerator.h +39 -0
- package/ios/common/BackgroundGeolocation/INTULocationManager/INTURequestIDGenerator.m +37 -0
- package/ios/common/BackgroundGeolocation/MAURAbstractLocationProvider.h +51 -0
- package/ios/common/BackgroundGeolocation/MAURAbstractLocationProvider.m +53 -0
- package/ios/common/BackgroundGeolocation/MAURActivity.h +23 -0
- package/ios/common/BackgroundGeolocation/MAURActivity.m +52 -0
- package/ios/common/BackgroundGeolocation/MAURActivityLocationProvider.h +18 -0
- package/ios/common/BackgroundGeolocation/MAURActivityLocationProvider.m +340 -0
- package/ios/common/BackgroundGeolocation/MAURBackgroundGeolocationFacade.h +88 -0
- package/ios/common/BackgroundGeolocation/MAURBackgroundGeolocationFacade.m +1193 -0
- package/ios/common/BackgroundGeolocation/MAURBackgroundSync.h +46 -0
- package/ios/common/BackgroundGeolocation/MAURBackgroundSync.m +283 -0
- package/ios/common/BackgroundGeolocation/MAURBackgroundTaskManager.h +25 -0
- package/ios/common/BackgroundGeolocation/MAURBackgroundTaskManager.m +105 -0
- package/ios/common/BackgroundGeolocation/MAURConfig.h +99 -0
- package/ios/common/BackgroundGeolocation/MAURConfig.m +636 -0
- package/ios/common/BackgroundGeolocation/MAURConfigurationContract.h +53 -0
- package/ios/common/BackgroundGeolocation/MAURConfigurationContract.m +54 -0
- package/ios/common/BackgroundGeolocation/MAURDistanceFilterLocationProvider.h +20 -0
- package/ios/common/BackgroundGeolocation/MAURDistanceFilterLocationProvider.m +550 -0
- package/ios/common/BackgroundGeolocation/MAURGeolocationOpenHelper.h +17 -0
- package/ios/common/BackgroundGeolocation/MAURGeolocationOpenHelper.m +124 -0
- package/ios/common/BackgroundGeolocation/MAURLocation.h +73 -0
- package/ios/common/BackgroundGeolocation/MAURLocation.m +392 -0
- package/ios/common/BackgroundGeolocation/MAURLocationContract.h +38 -0
- package/ios/common/BackgroundGeolocation/MAURLocationContract.m +39 -0
- package/ios/common/BackgroundGeolocation/MAURLocationManager.h +53 -0
- package/ios/common/BackgroundGeolocation/MAURLocationManager.m +305 -0
- package/ios/common/BackgroundGeolocation/MAURLogReader.h +26 -0
- package/ios/common/BackgroundGeolocation/MAURLogReader.m +122 -0
- package/ios/common/BackgroundGeolocation/MAURLogging.h +19 -0
- package/ios/common/BackgroundGeolocation/MAURPostLocationTask.h +53 -0
- package/ios/common/BackgroundGeolocation/MAURPostLocationTask.m +367 -0
- package/ios/common/BackgroundGeolocation/MAURProviderDelegate.h +52 -0
- package/ios/common/BackgroundGeolocation/MAURRawLocationProvider.h +18 -0
- package/ios/common/BackgroundGeolocation/MAURRawLocationProvider.m +138 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteConfigurationDAO.h +26 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteConfigurationDAO.m +335 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteHelper.h +57 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteHelper.m +93 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteLocationDAO.h +52 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteLocationDAO.m +520 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteOpenHelper.h +32 -0
- package/ios/common/BackgroundGeolocation/MAURSQLiteOpenHelper.m +276 -0
- package/ios/common/BackgroundGeolocation/MAURSensorFusionDetector.h +41 -0
- package/ios/common/BackgroundGeolocation/MAURSensorFusionDetector.m +137 -0
- package/ios/common/BackgroundGeolocation/MAURSessionLocationContract.h +29 -0
- package/ios/common/BackgroundGeolocation/MAURSessionLocationContract.m +31 -0
- package/ios/common/BackgroundGeolocation/MAURSessionLocationDAO.h +25 -0
- package/ios/common/BackgroundGeolocation/MAURSessionLocationDAO.m +153 -0
- package/ios/common/BackgroundGeolocation/MAURUncaughtExceptionLogger.h +20 -0
- package/ios/common/BackgroundGeolocation/MAURUncaughtExceptionLogger.m +62 -0
- package/ios/common/BackgroundGeolocation/MAURUrlTemplateResolver.h +31 -0
- package/ios/common/BackgroundGeolocation/MAURUrlTemplateResolver.m +107 -0
- package/ios/common/BackgroundGeolocation/Reachability.h +102 -0
- package/ios/common/BackgroundGeolocation/Reachability.m +475 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/README.md +170 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/ext/NSString+ZIMString.h +55 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/ext/NSString+ZIMString.m +47 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlDataManipulationCommand.h +27 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlExpression.h +250 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlExpression.m +259 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlSelectStatement.h +360 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlSelectStatement.m +427 -0
- package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlStatement.h +37 -0
- package/ios/common/BackgroundGeolocation/module.modulemap +16 -0
- package/package.json +82 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
package com.marianhello.bgloc.provider;
|
|
2
|
+
|
|
3
|
+
import android.app.PendingIntent;
|
|
4
|
+
import android.content.BroadcastReceiver;
|
|
5
|
+
import android.content.Context;
|
|
6
|
+
import android.content.Intent;
|
|
7
|
+
import android.content.IntentFilter;
|
|
8
|
+
import android.content.pm.PackageManager;
|
|
9
|
+
import android.location.Location;
|
|
10
|
+
import android.Manifest;
|
|
11
|
+
import android.os.Build;
|
|
12
|
+
import android.os.Looper;
|
|
13
|
+
import androidx.core.app.ActivityCompat;
|
|
14
|
+
|
|
15
|
+
import com.google.android.gms.common.ConnectionResult;
|
|
16
|
+
import com.google.android.gms.common.GoogleApiAvailability;
|
|
17
|
+
import com.google.android.gms.location.ActivityRecognition;
|
|
18
|
+
import com.google.android.gms.location.ActivityRecognitionClient;
|
|
19
|
+
import com.google.android.gms.location.ActivityRecognitionResult;
|
|
20
|
+
import com.google.android.gms.location.DetectedActivity;
|
|
21
|
+
import com.google.android.gms.location.FusedLocationProviderClient;
|
|
22
|
+
import com.google.android.gms.location.LocationCallback;
|
|
23
|
+
import com.google.android.gms.location.LocationRequest;
|
|
24
|
+
import com.google.android.gms.location.LocationResult;
|
|
25
|
+
import com.google.android.gms.location.LocationServices;
|
|
26
|
+
import com.google.android.gms.location.Priority;
|
|
27
|
+
import com.marianhello.bgloc.Config;
|
|
28
|
+
import com.marianhello.bgloc.data.BackgroundActivity;
|
|
29
|
+
|
|
30
|
+
import java.util.List;
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
public class ActivityRecognitionLocationProvider extends AbstractLocationProvider {
|
|
34
|
+
|
|
35
|
+
private static final String P_NAME = "com.marianhello.bgloc";
|
|
36
|
+
private static final String DETECTED_ACTIVITY_UPDATE = P_NAME + ".DETECTED_ACTIVITY_UPDATE";
|
|
37
|
+
|
|
38
|
+
private FusedLocationProviderClient fusedLocationClient;
|
|
39
|
+
private ActivityRecognitionClient activityRecognitionClient;
|
|
40
|
+
private PendingIntent detectedActivitiesPI;
|
|
41
|
+
|
|
42
|
+
// Must default to false: onConfigure() is called before onStart() by LocationServiceImpl.
|
|
43
|
+
private boolean isStarted = false;
|
|
44
|
+
private boolean isTracking = false;
|
|
45
|
+
private boolean isWatchingActivity = false;
|
|
46
|
+
private boolean playServicesAvailable = false;
|
|
47
|
+
private boolean activityPermissionErrorEmitted = false;
|
|
48
|
+
private boolean stopOnStillWarningEmitted = false;
|
|
49
|
+
private DetectedActivity lastActivity = new DetectedActivity(DetectedActivity.UNKNOWN, 100);
|
|
50
|
+
|
|
51
|
+
// v4.5.2: snapshot of fields that require restarting tracking when they change.
|
|
52
|
+
private Integer prevDesiredAccuracy;
|
|
53
|
+
private Integer prevInterval;
|
|
54
|
+
private Integer prevFastestInterval;
|
|
55
|
+
private Integer prevDistanceFilter;
|
|
56
|
+
private Integer prevActivitiesInterval;
|
|
57
|
+
private Boolean prevStopOnStillActivity;
|
|
58
|
+
|
|
59
|
+
private final LocationCallback locationCallback = new LocationCallback() {
|
|
60
|
+
@Override
|
|
61
|
+
public void onLocationResult(LocationResult result) {
|
|
62
|
+
if (result == null) return;
|
|
63
|
+
List<Location> locations = result.getLocations();
|
|
64
|
+
if (locations == null) return;
|
|
65
|
+
for (Location location : locations) {
|
|
66
|
+
onLocationReceived(location);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
public ActivityRecognitionLocationProvider(Context context) {
|
|
72
|
+
super(context);
|
|
73
|
+
PROVIDER_ID = Config.ACTIVITY_PROVIDER;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@Override
|
|
77
|
+
public void onCreate() {
|
|
78
|
+
super.onCreate();
|
|
79
|
+
|
|
80
|
+
// v4.5.2: ACTIVITY_PROVIDER strictly depends on Google Play Services
|
|
81
|
+
// (FusedLocationProviderClient + ActivityRecognitionClient). If GPS is
|
|
82
|
+
// missing/outdated we cannot operate — surface a clear error instead of
|
|
83
|
+
// silently failing.
|
|
84
|
+
int gps = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(mContext);
|
|
85
|
+
playServicesAvailable = (gps == ConnectionResult.SUCCESS);
|
|
86
|
+
if (!playServicesAvailable) {
|
|
87
|
+
String msg = "Google Play Services unavailable for ACTIVITY_PROVIDER (code=" + gps + "); provider will be inert.";
|
|
88
|
+
logger.error(msg);
|
|
89
|
+
handleServiceError(msg);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
fusedLocationClient = LocationServices.getFusedLocationProviderClient(mContext);
|
|
94
|
+
activityRecognitionClient = ActivityRecognition.getClient(mContext);
|
|
95
|
+
|
|
96
|
+
Intent detectedActivitiesIntent = new Intent(mContext, DetectedActivitiesReceiver.class);
|
|
97
|
+
detectedActivitiesIntent.setAction(DETECTED_ACTIVITY_UPDATE);
|
|
98
|
+
|
|
99
|
+
int updateCurrentFlag = android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
|
100
|
+
? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
|
|
101
|
+
: PendingIntent.FLAG_UPDATE_CURRENT;
|
|
102
|
+
detectedActivitiesPI = PendingIntent.getBroadcast(mContext, 9002, detectedActivitiesIntent, updateCurrentFlag);
|
|
103
|
+
registerReceiver(detectedActivitiesReceiver, new IntentFilter(DETECTED_ACTIVITY_UPDATE));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@Override
|
|
107
|
+
public void onStart() {
|
|
108
|
+
logger.info("Start recording");
|
|
109
|
+
this.isStarted = true;
|
|
110
|
+
|
|
111
|
+
// v4.5.2: ACTIVITY_PROVIDER hinges on the STILL/ACTIVE state machine.
|
|
112
|
+
// If the host turned that off, the provider degenerates into a tracker
|
|
113
|
+
// that never pauses — warn so it shows up in logcat for the integrator.
|
|
114
|
+
if (mConfig != null && Boolean.FALSE.equals(mConfig.getStopOnStillActivity()) && !stopOnStillWarningEmitted) {
|
|
115
|
+
logger.warn("ACTIVITY_PROVIDER with stopOnStillActivity=false will track continuously; consider DISTANCE_FILTER_PROVIDER or RAW_PROVIDER for that use case.");
|
|
116
|
+
stopOnStillWarningEmitted = true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
attachRecorder();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@Override
|
|
123
|
+
public void onStop() {
|
|
124
|
+
logger.info("Stop recording");
|
|
125
|
+
this.isStarted = false;
|
|
126
|
+
detachRecorder();
|
|
127
|
+
stopTracking();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@Override
|
|
131
|
+
public void onConfigure(Config config) {
|
|
132
|
+
// v4.5.2: only restart tracking if a field that actually affects the
|
|
133
|
+
// LocationRequest / activity-updates subscription has changed. A no-op
|
|
134
|
+
// reconfigure used to drop+re-add the location callback and momentarily
|
|
135
|
+
// leave the service without updates.
|
|
136
|
+
boolean restart = false;
|
|
137
|
+
if (isStarted) {
|
|
138
|
+
restart = !sameValue(prevDesiredAccuracy, config != null ? config.getDesiredAccuracy() : null)
|
|
139
|
+
|| !sameValue(prevInterval, config != null ? config.getInterval() : null)
|
|
140
|
+
|| !sameValue(prevFastestInterval, config != null ? config.getFastestInterval() : null)
|
|
141
|
+
|| !sameValue(prevDistanceFilter, config != null ? config.getDistanceFilter() : null)
|
|
142
|
+
|| !sameValue(prevActivitiesInterval, config != null ? config.getActivitiesInterval() : null)
|
|
143
|
+
|| !sameValue(prevStopOnStillActivity, config != null ? config.getStopOnStillActivity() : null);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
super.onConfigure(config);
|
|
147
|
+
|
|
148
|
+
if (restart) {
|
|
149
|
+
logger.debug("Restarting ACTIVITY_PROVIDER tracking after relevant config change.");
|
|
150
|
+
onStop();
|
|
151
|
+
onStart();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (config != null) {
|
|
155
|
+
prevDesiredAccuracy = config.getDesiredAccuracy();
|
|
156
|
+
prevInterval = config.getInterval();
|
|
157
|
+
prevFastestInterval = config.getFastestInterval();
|
|
158
|
+
prevDistanceFilter = config.getDistanceFilter();
|
|
159
|
+
prevActivitiesInterval = config.getActivitiesInterval();
|
|
160
|
+
prevStopOnStillActivity = config.getStopOnStillActivity();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private static boolean sameValue(Object a, Object b) {
|
|
165
|
+
return a == null ? b == null : a.equals(b);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
@Override
|
|
169
|
+
public boolean isStarted() {
|
|
170
|
+
return isStarted;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@Override
|
|
174
|
+
public void onCommand(int commandId, int arg1) {
|
|
175
|
+
if (commandId == LocationProvider.CMD_SWITCH_MODE && isStarted) {
|
|
176
|
+
// Foreground: ensure tracking; background: keep current behavior (activity still drives start/stop).
|
|
177
|
+
if (arg1 == LocationProvider.FOREGROUND_MODE) {
|
|
178
|
+
startTracking();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Same logic as former onLocationChanged: STILL -> stationary + stopTracking, else handleLocation.
|
|
185
|
+
*/
|
|
186
|
+
private void onLocationReceived(Location location) {
|
|
187
|
+
logger.debug("Location change: {}", location.toString());
|
|
188
|
+
|
|
189
|
+
if (lastActivity.getType() == DetectedActivity.STILL) {
|
|
190
|
+
handleStationary(location);
|
|
191
|
+
stopTracking();
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
showDebugToast("acy:" + location.getAccuracy() + ",v:" + location.getSpeed());
|
|
196
|
+
|
|
197
|
+
handleLocation(location);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
public void startTracking() {
|
|
201
|
+
if (isTracking) { return; }
|
|
202
|
+
if (fusedLocationClient == null || mConfig == null) { return; }
|
|
203
|
+
|
|
204
|
+
int priority = translateDesiredAccuracy(mConfig.getDesiredAccuracy());
|
|
205
|
+
// v3.4: LocationRequest.Builder (play-services-location 21.0.0+) replaces deprecated
|
|
206
|
+
// LocationRequest.create() + setPriority/setInterval/setFastestInterval.
|
|
207
|
+
// v4.5.2: also honor distanceFilter (was ignored on ACTIVITY_PROVIDER), so the
|
|
208
|
+
// FusedLocationProvider can throttle by distance and not just by interval.
|
|
209
|
+
LocationRequest.Builder builder = new LocationRequest.Builder(priority, mConfig.getInterval())
|
|
210
|
+
.setMinUpdateIntervalMillis(mConfig.getFastestInterval())
|
|
211
|
+
.setWaitForAccurateLocation(false);
|
|
212
|
+
Integer distanceFilter = mConfig.getDistanceFilter();
|
|
213
|
+
if (distanceFilter != null && distanceFilter > 0) {
|
|
214
|
+
builder.setMinUpdateDistanceMeters(distanceFilter.floatValue());
|
|
215
|
+
}
|
|
216
|
+
LocationRequest locationRequest = builder.build();
|
|
217
|
+
|
|
218
|
+
try {
|
|
219
|
+
fusedLocationClient.requestLocationUpdates(
|
|
220
|
+
locationRequest,
|
|
221
|
+
locationCallback,
|
|
222
|
+
Looper.getMainLooper()
|
|
223
|
+
);
|
|
224
|
+
isTracking = true;
|
|
225
|
+
logger.debug("Start tracking with priority={} fastestInterval={} interval={} activitiesInterval={} stopOnStillActivity={}",
|
|
226
|
+
priority, mConfig.getFastestInterval(), mConfig.getInterval(), mConfig.getActivitiesInterval(), mConfig.getStopOnStillActivity());
|
|
227
|
+
} catch (SecurityException e) {
|
|
228
|
+
logger.error("Security exception: {}", e.getMessage());
|
|
229
|
+
this.handleSecurityException(e);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
public void stopTracking() {
|
|
234
|
+
if (!isTracking) { return; }
|
|
235
|
+
if (fusedLocationClient == null) {
|
|
236
|
+
isTracking = false;
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
try {
|
|
240
|
+
fusedLocationClient.removeLocationUpdates(locationCallback);
|
|
241
|
+
} catch (SecurityException e) {
|
|
242
|
+
logger.warn("Security exception removing location updates: {}", e.getMessage());
|
|
243
|
+
} finally {
|
|
244
|
+
isTracking = false;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
private boolean activityRecognitionPermitted() {
|
|
249
|
+
return Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
|
|
250
|
+
|| ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_GRANTED;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
private void attachRecorder() {
|
|
254
|
+
if (fusedLocationClient == null || activityRecognitionClient == null) { return; }
|
|
255
|
+
if (mConfig == null) { return; }
|
|
256
|
+
|
|
257
|
+
startTracking();
|
|
258
|
+
|
|
259
|
+
if (!isWatchingActivity && mConfig.getStopOnStillActivity()) {
|
|
260
|
+
// v4.5.2: on Android 10+ ACTIVITY_RECOGNITION is a runtime permission.
|
|
261
|
+
// Without it, requestActivityUpdates() silently returns no broadcasts and
|
|
262
|
+
// STILL/ACTIVE never flips — the provider then runs as a continuous tracker
|
|
263
|
+
// by accident. Emit a one-shot error so the host app knows to request it.
|
|
264
|
+
if (!activityRecognitionPermitted()) {
|
|
265
|
+
if (!activityPermissionErrorEmitted) {
|
|
266
|
+
String msg = "ACTIVITY_RECOGNITION permission denied; ACTIVITY_PROVIDER cannot detect STILL/ACTIVE transitions.";
|
|
267
|
+
logger.warn(msg);
|
|
268
|
+
handlePermissionDenied(msg);
|
|
269
|
+
activityPermissionErrorEmitted = true;
|
|
270
|
+
}
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
activityRecognitionClient.requestActivityUpdates(
|
|
274
|
+
mConfig.getActivitiesInterval(),
|
|
275
|
+
detectedActivitiesPI
|
|
276
|
+
).addOnFailureListener(e -> logger.error("requestActivityUpdates failed: {}", e.getMessage()));
|
|
277
|
+
isWatchingActivity = true;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
private void detachRecorder() {
|
|
282
|
+
if (!isWatchingActivity) { return; }
|
|
283
|
+
if (activityRecognitionClient == null) {
|
|
284
|
+
isWatchingActivity = false;
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
try {
|
|
288
|
+
logger.debug("Detaching recorder");
|
|
289
|
+
activityRecognitionClient.removeActivityUpdates(detectedActivitiesPI)
|
|
290
|
+
.addOnSuccessListener(v -> logger.debug("removeActivityUpdates ok"))
|
|
291
|
+
.addOnFailureListener(e -> logger.warn("removeActivityUpdates failed: {}", e.getMessage()));
|
|
292
|
+
} finally {
|
|
293
|
+
isWatchingActivity = false;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Translates a number representing desired accuracy of Geolocation system from set [0, 10, 100, 1000].
|
|
299
|
+
* 0: most aggressive, most accurate, worst battery drain
|
|
300
|
+
* 1000: least aggressive, least accurate, best for battery.
|
|
301
|
+
*/
|
|
302
|
+
private int translateDesiredAccuracy(Integer accuracy) {
|
|
303
|
+
// v3.4: Priority.* (play-services-location 21.0.0+) replaces deprecated LocationRequest.PRIORITY_*.
|
|
304
|
+
if (accuracy == null) {
|
|
305
|
+
return Priority.PRIORITY_BALANCED_POWER_ACCURACY;
|
|
306
|
+
}
|
|
307
|
+
if (accuracy >= 10000) {
|
|
308
|
+
return Priority.PRIORITY_PASSIVE;
|
|
309
|
+
}
|
|
310
|
+
if (accuracy >= 1000) {
|
|
311
|
+
return Priority.PRIORITY_LOW_POWER;
|
|
312
|
+
}
|
|
313
|
+
if (accuracy >= 100) {
|
|
314
|
+
return Priority.PRIORITY_BALANCED_POWER_ACCURACY;
|
|
315
|
+
}
|
|
316
|
+
return Priority.PRIORITY_HIGH_ACCURACY;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
public static DetectedActivity getProbableActivity(List<DetectedActivity> detectedActivities) {
|
|
320
|
+
int highestConfidence = 0;
|
|
321
|
+
DetectedActivity mostLikelyActivity = new DetectedActivity(DetectedActivity.UNKNOWN, 0);
|
|
322
|
+
|
|
323
|
+
for (DetectedActivity da : detectedActivities) {
|
|
324
|
+
if (da.getType() != DetectedActivity.TILTING && da.getType() != DetectedActivity.UNKNOWN) {
|
|
325
|
+
if (highestConfidence < da.getConfidence()) {
|
|
326
|
+
highestConfidence = da.getConfidence();
|
|
327
|
+
mostLikelyActivity = da;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return mostLikelyActivity;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
private class DetectedActivitiesReceiver extends BroadcastReceiver {
|
|
335
|
+
@Override
|
|
336
|
+
public void onReceive(Context context, Intent intent) {
|
|
337
|
+
ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
|
|
338
|
+
if (result == null) return;
|
|
339
|
+
List<DetectedActivity> detectedActivities = result.getProbableActivities();
|
|
340
|
+
if (detectedActivities == null || detectedActivities.isEmpty()) return;
|
|
341
|
+
|
|
342
|
+
DetectedActivity candidate = getProbableActivity(detectedActivities);
|
|
343
|
+
|
|
344
|
+
// v4.5.2: skip transitions whose confidence is below the configured
|
|
345
|
+
// threshold (default 50). Prevents jittery STILL/ACTIVE flips when the
|
|
346
|
+
// motion classifier is unsure — which translated into spurious GPS
|
|
347
|
+
// start/stop bursts in earlier versions.
|
|
348
|
+
Integer threshold = mConfig != null ? mConfig.getActivityConfidenceThreshold() : null;
|
|
349
|
+
if (threshold != null && candidate.getConfidence() < threshold) {
|
|
350
|
+
logger.debug("Ignoring low-confidence activity={} confidence={} threshold={}",
|
|
351
|
+
BackgroundActivity.getActivityString(candidate.getType()),
|
|
352
|
+
candidate.getConfidence(),
|
|
353
|
+
threshold);
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
lastActivity = candidate;
|
|
358
|
+
|
|
359
|
+
logger.debug("Detected activity={} confidence={}", BackgroundActivity.getActivityString(lastActivity.getType()), lastActivity.getConfidence());
|
|
360
|
+
|
|
361
|
+
handleActivity(lastActivity);
|
|
362
|
+
|
|
363
|
+
if (lastActivity.getType() == DetectedActivity.STILL) {
|
|
364
|
+
showDebugToast("Detected STILL Activity");
|
|
365
|
+
} else {
|
|
366
|
+
showDebugToast("Detected ACTIVE Activity");
|
|
367
|
+
startTracking();
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
private final BroadcastReceiver detectedActivitiesReceiver = new DetectedActivitiesReceiver();
|
|
373
|
+
|
|
374
|
+
@Override
|
|
375
|
+
public void onDestroy() {
|
|
376
|
+
logger.info("Destroying ActivityRecognitionLocationProvider");
|
|
377
|
+
onStop();
|
|
378
|
+
try {
|
|
379
|
+
unregisterReceiver(detectedActivitiesReceiver);
|
|
380
|
+
} catch (Exception ignored) {
|
|
381
|
+
// Receiver may not be registered if onCreate/onStart never completed
|
|
382
|
+
}
|
|
383
|
+
super.onDestroy();
|
|
384
|
+
}
|
|
385
|
+
}
|