@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.
Files changed (207) hide show
  1. package/JosuelmmCapacitorBackgroundGeolocation.podspec +34 -0
  2. package/LICENSE +17 -0
  3. package/NOTICE.md +32 -0
  4. package/Package.swift +45 -0
  5. package/README.md +402 -0
  6. package/android/build.gradle +79 -0
  7. package/android/proguard-rules.pro +1 -0
  8. package/android/src/main/AndroidManifest.xml +83 -0
  9. package/android/src/main/java/com/evgenii/jsevaluator/HandlerWrapper.java +18 -0
  10. package/android/src/main/java/com/evgenii/jsevaluator/JavaScriptInterface.java +22 -0
  11. package/android/src/main/java/com/evgenii/jsevaluator/JsEvaluator.java +133 -0
  12. package/android/src/main/java/com/evgenii/jsevaluator/JsFunctionCallFormatter.java +37 -0
  13. package/android/src/main/java/com/evgenii/jsevaluator/WebViewWrapper.java +71 -0
  14. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/CallJavaResultInterface.java +8 -0
  15. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/HandlerWrapperInterface.java +5 -0
  16. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/JsCallback.java +10 -0
  17. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/JsEvaluatorInterface.java +18 -0
  18. package/android/src/main/java/com/evgenii/jsevaluator/interfaces/WebViewWrapperInterface.java +14 -0
  19. package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/BackgroundGeolocationPlugin.java +898 -0
  20. package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/ConfigMapper.java +303 -0
  21. package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/HeadlessTaskRegistry.java +34 -0
  22. package/android/src/main/java/com/josuelmm/capacitor/backgroundgeolocation/JsEvaluatorTaskRunner.java +63 -0
  23. package/android/src/main/java/com/marianhello/bgloc/BackgroundGeolocationFacade.java +699 -0
  24. package/android/src/main/java/com/marianhello/bgloc/BootCompletedReceiver.java +103 -0
  25. package/android/src/main/java/com/marianhello/bgloc/Config.java +1155 -0
  26. package/android/src/main/java/com/marianhello/bgloc/ConnectivityListener.java +5 -0
  27. package/android/src/main/java/com/marianhello/bgloc/HttpPostService.java +362 -0
  28. package/android/src/main/java/com/marianhello/bgloc/LocationManager.java +138 -0
  29. package/android/src/main/java/com/marianhello/bgloc/PluginDelegate.java +45 -0
  30. package/android/src/main/java/com/marianhello/bgloc/PluginException.java +38 -0
  31. package/android/src/main/java/com/marianhello/bgloc/PostLocationTask.java +238 -0
  32. package/android/src/main/java/com/marianhello/bgloc/ResourceResolver.java +55 -0
  33. package/android/src/main/java/com/marianhello/bgloc/data/AbstractLocationTemplate.java +69 -0
  34. package/android/src/main/java/com/marianhello/bgloc/data/ArrayListLocationTemplate.java +88 -0
  35. package/android/src/main/java/com/marianhello/bgloc/data/BackgroundActivity.java +108 -0
  36. package/android/src/main/java/com/marianhello/bgloc/data/BackgroundLocation.java +1088 -0
  37. package/android/src/main/java/com/marianhello/bgloc/data/ConfigJsonMapper.java +211 -0
  38. package/android/src/main/java/com/marianhello/bgloc/data/ConfigurationDAO.java +13 -0
  39. package/android/src/main/java/com/marianhello/bgloc/data/DAOFactory.java +17 -0
  40. package/android/src/main/java/com/marianhello/bgloc/data/HashMapLocationTemplate.java +82 -0
  41. package/android/src/main/java/com/marianhello/bgloc/data/LocationDAO.java +27 -0
  42. package/android/src/main/java/com/marianhello/bgloc/data/LocationTemplate.java +12 -0
  43. package/android/src/main/java/com/marianhello/bgloc/data/LocationTemplateFactory.java +71 -0
  44. package/android/src/main/java/com/marianhello/bgloc/data/LocationTransform.java +19 -0
  45. package/android/src/main/java/com/marianhello/bgloc/data/SessionLocationDAO.java +18 -0
  46. package/android/src/main/java/com/marianhello/bgloc/data/provider/ContentProviderLocationDAO.java +406 -0
  47. package/android/src/main/java/com/marianhello/bgloc/data/provider/LocationContentProvider.java +321 -0
  48. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteConfigurationContract.java +94 -0
  49. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteConfigurationDAO.java +227 -0
  50. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteLocationContract.java +122 -0
  51. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteLocationDAO.java +550 -0
  52. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteOpenHelper.java +189 -0
  53. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteSessionContract.java +74 -0
  54. package/android/src/main/java/com/marianhello/bgloc/data/sqlite/SQLiteSessionLocationDAO.java +169 -0
  55. package/android/src/main/java/com/marianhello/bgloc/driving/DrivingEventsDetector.java +265 -0
  56. package/android/src/main/java/com/marianhello/bgloc/headless/AbstractTaskRunner.java +15 -0
  57. package/android/src/main/java/com/marianhello/bgloc/headless/ActivityTask.java +48 -0
  58. package/android/src/main/java/com/marianhello/bgloc/headless/JsCallback.java +10 -0
  59. package/android/src/main/java/com/marianhello/bgloc/headless/LocationTask.java +60 -0
  60. package/android/src/main/java/com/marianhello/bgloc/headless/StationaryTask.java +25 -0
  61. package/android/src/main/java/com/marianhello/bgloc/headless/Task.java +8 -0
  62. package/android/src/main/java/com/marianhello/bgloc/headless/TaskRunner.java +5 -0
  63. package/android/src/main/java/com/marianhello/bgloc/headless/TaskRunnerFactory.java +8 -0
  64. package/android/src/main/java/com/marianhello/bgloc/http/UrlTemplateResolver.java +115 -0
  65. package/android/src/main/java/com/marianhello/bgloc/oem/BatteryOemHelper.java +214 -0
  66. package/android/src/main/java/com/marianhello/bgloc/provider/AbstractLocationProvider.java +218 -0
  67. package/android/src/main/java/com/marianhello/bgloc/provider/ActivityRecognitionLocationProvider.java +385 -0
  68. package/android/src/main/java/com/marianhello/bgloc/provider/DistanceFilterLocationProvider.java +685 -0
  69. package/android/src/main/java/com/marianhello/bgloc/provider/LocationProvider.java +32 -0
  70. package/android/src/main/java/com/marianhello/bgloc/provider/LocationProviderFactory.java +47 -0
  71. package/android/src/main/java/com/marianhello/bgloc/provider/ProviderDelegate.java +12 -0
  72. package/android/src/main/java/com/marianhello/bgloc/provider/RawLocationProvider.java +175 -0
  73. package/android/src/main/java/com/marianhello/bgloc/sensor/SensorFusionDetector.java +199 -0
  74. package/android/src/main/java/com/marianhello/bgloc/service/LocationService.java +16 -0
  75. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceImpl.java +1531 -0
  76. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceInfo.java +6 -0
  77. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceInfoImpl.java +41 -0
  78. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceIntentBuilder.java +203 -0
  79. package/android/src/main/java/com/marianhello/bgloc/service/LocationServiceProxy.java +156 -0
  80. package/android/src/main/java/com/marianhello/bgloc/sync/AccountHelper.java +39 -0
  81. package/android/src/main/java/com/marianhello/bgloc/sync/Authenticator.java +68 -0
  82. package/android/src/main/java/com/marianhello/bgloc/sync/AuthenticatorService.java +28 -0
  83. package/android/src/main/java/com/marianhello/bgloc/sync/BatchManager.java +311 -0
  84. package/android/src/main/java/com/marianhello/bgloc/sync/NotificationHelper.java +148 -0
  85. package/android/src/main/java/com/marianhello/bgloc/sync/SyncAdapter.java +301 -0
  86. package/android/src/main/java/com/marianhello/bgloc/sync/SyncService.java +68 -0
  87. package/android/src/main/java/com/marianhello/logging/DBLogReader.java +208 -0
  88. package/android/src/main/java/com/marianhello/logging/LogEntry.java +99 -0
  89. package/android/src/main/java/com/marianhello/logging/LoggerManager.java +70 -0
  90. package/android/src/main/java/com/marianhello/logging/UncaughtExceptionLogger.java +36 -0
  91. package/android/src/main/java/com/marianhello/utils/CloneHelper.java +22 -0
  92. package/android/src/main/java/com/marianhello/utils/Convert.java +56 -0
  93. package/android/src/main/java/com/marianhello/utils/TextUtils.java +72 -0
  94. package/android/src/main/java/com/marianhello/utils/ToneGenerator.java +68 -0
  95. package/android/src/main/java/org/apache/commons/io/Charsets.java +153 -0
  96. package/android/src/main/java/org/apache/commons/io/input/ReversedLinesFileReader.java +344 -0
  97. package/android/src/main/java/org/chromium/content/browser/ThreadUtils.java +134 -0
  98. package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlExpression.java +398 -0
  99. package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlSelectStatement.java +671 -0
  100. package/android/src/main/java/ru/andremoniy/sqlbuilder/SqlStatement.java +29 -0
  101. package/android/src/main/java/ru/andremoniy/utils/TextUtils.java +61 -0
  102. package/android/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  103. package/android/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  104. package/android/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  105. package/android/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  106. package/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  107. package/android/src/main/res/values/strings.xml +15 -0
  108. package/android/src/main/res/xml/authenticator.xml +7 -0
  109. package/android/src/main/res/xml/syncadapter.xml +9 -0
  110. package/dist/esm/definitions.d.ts +1052 -0
  111. package/dist/esm/definitions.js +142 -0
  112. package/dist/esm/definitions.js.map +1 -0
  113. package/dist/esm/index.d.ts +8 -0
  114. package/dist/esm/index.js +23 -0
  115. package/dist/esm/index.js.map +1 -0
  116. package/dist/esm/web.d.ts +92 -0
  117. package/dist/esm/web.js +242 -0
  118. package/dist/esm/web.js.map +1 -0
  119. package/dist/plugin.cjs.js +415 -0
  120. package/dist/plugin.cjs.js.map +1 -0
  121. package/dist/plugin.js +418 -0
  122. package/dist/plugin.js.map +1 -0
  123. package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin-Bridging-Header.h +18 -0
  124. package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin.m +52 -0
  125. package/ios/Sources/BackgroundGeolocationPlugin/BackgroundGeolocationPlugin.swift +750 -0
  126. package/ios/Tests/BackgroundGeolocationPluginTests/BackgroundGeolocationPluginTests.swift +12 -0
  127. package/ios/common/BackgroundGeolocation/CocoaLumberjack.h +1945 -0
  128. package/ios/common/BackgroundGeolocation/CocoaLumberjack.m +5255 -0
  129. package/ios/common/BackgroundGeolocation/FMDB.h +2357 -0
  130. package/ios/common/BackgroundGeolocation/FMDB.m +2672 -0
  131. package/ios/common/BackgroundGeolocation/FMDBLogger.h +42 -0
  132. package/ios/common/BackgroundGeolocation/FMDBLogger.m +264 -0
  133. package/ios/common/BackgroundGeolocation/INTULocationManager/INTUHeadingRequest.h +41 -0
  134. package/ios/common/BackgroundGeolocation/INTULocationManager/INTUHeadingRequest.m +68 -0
  135. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager+Internal.h +33 -0
  136. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager.h +178 -0
  137. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationManager.m +1025 -0
  138. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequest.h +103 -0
  139. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequest.m +238 -0
  140. package/ios/common/BackgroundGeolocation/INTULocationManager/INTULocationRequestDefines.h +163 -0
  141. package/ios/common/BackgroundGeolocation/INTULocationManager/INTURequestIDGenerator.h +39 -0
  142. package/ios/common/BackgroundGeolocation/INTULocationManager/INTURequestIDGenerator.m +37 -0
  143. package/ios/common/BackgroundGeolocation/MAURAbstractLocationProvider.h +51 -0
  144. package/ios/common/BackgroundGeolocation/MAURAbstractLocationProvider.m +53 -0
  145. package/ios/common/BackgroundGeolocation/MAURActivity.h +23 -0
  146. package/ios/common/BackgroundGeolocation/MAURActivity.m +52 -0
  147. package/ios/common/BackgroundGeolocation/MAURActivityLocationProvider.h +18 -0
  148. package/ios/common/BackgroundGeolocation/MAURActivityLocationProvider.m +340 -0
  149. package/ios/common/BackgroundGeolocation/MAURBackgroundGeolocationFacade.h +88 -0
  150. package/ios/common/BackgroundGeolocation/MAURBackgroundGeolocationFacade.m +1193 -0
  151. package/ios/common/BackgroundGeolocation/MAURBackgroundSync.h +46 -0
  152. package/ios/common/BackgroundGeolocation/MAURBackgroundSync.m +283 -0
  153. package/ios/common/BackgroundGeolocation/MAURBackgroundTaskManager.h +25 -0
  154. package/ios/common/BackgroundGeolocation/MAURBackgroundTaskManager.m +105 -0
  155. package/ios/common/BackgroundGeolocation/MAURConfig.h +99 -0
  156. package/ios/common/BackgroundGeolocation/MAURConfig.m +636 -0
  157. package/ios/common/BackgroundGeolocation/MAURConfigurationContract.h +53 -0
  158. package/ios/common/BackgroundGeolocation/MAURConfigurationContract.m +54 -0
  159. package/ios/common/BackgroundGeolocation/MAURDistanceFilterLocationProvider.h +20 -0
  160. package/ios/common/BackgroundGeolocation/MAURDistanceFilterLocationProvider.m +550 -0
  161. package/ios/common/BackgroundGeolocation/MAURGeolocationOpenHelper.h +17 -0
  162. package/ios/common/BackgroundGeolocation/MAURGeolocationOpenHelper.m +124 -0
  163. package/ios/common/BackgroundGeolocation/MAURLocation.h +73 -0
  164. package/ios/common/BackgroundGeolocation/MAURLocation.m +392 -0
  165. package/ios/common/BackgroundGeolocation/MAURLocationContract.h +38 -0
  166. package/ios/common/BackgroundGeolocation/MAURLocationContract.m +39 -0
  167. package/ios/common/BackgroundGeolocation/MAURLocationManager.h +53 -0
  168. package/ios/common/BackgroundGeolocation/MAURLocationManager.m +305 -0
  169. package/ios/common/BackgroundGeolocation/MAURLogReader.h +26 -0
  170. package/ios/common/BackgroundGeolocation/MAURLogReader.m +122 -0
  171. package/ios/common/BackgroundGeolocation/MAURLogging.h +19 -0
  172. package/ios/common/BackgroundGeolocation/MAURPostLocationTask.h +53 -0
  173. package/ios/common/BackgroundGeolocation/MAURPostLocationTask.m +367 -0
  174. package/ios/common/BackgroundGeolocation/MAURProviderDelegate.h +52 -0
  175. package/ios/common/BackgroundGeolocation/MAURRawLocationProvider.h +18 -0
  176. package/ios/common/BackgroundGeolocation/MAURRawLocationProvider.m +138 -0
  177. package/ios/common/BackgroundGeolocation/MAURSQLiteConfigurationDAO.h +26 -0
  178. package/ios/common/BackgroundGeolocation/MAURSQLiteConfigurationDAO.m +335 -0
  179. package/ios/common/BackgroundGeolocation/MAURSQLiteHelper.h +57 -0
  180. package/ios/common/BackgroundGeolocation/MAURSQLiteHelper.m +93 -0
  181. package/ios/common/BackgroundGeolocation/MAURSQLiteLocationDAO.h +52 -0
  182. package/ios/common/BackgroundGeolocation/MAURSQLiteLocationDAO.m +520 -0
  183. package/ios/common/BackgroundGeolocation/MAURSQLiteOpenHelper.h +32 -0
  184. package/ios/common/BackgroundGeolocation/MAURSQLiteOpenHelper.m +276 -0
  185. package/ios/common/BackgroundGeolocation/MAURSensorFusionDetector.h +41 -0
  186. package/ios/common/BackgroundGeolocation/MAURSensorFusionDetector.m +137 -0
  187. package/ios/common/BackgroundGeolocation/MAURSessionLocationContract.h +29 -0
  188. package/ios/common/BackgroundGeolocation/MAURSessionLocationContract.m +31 -0
  189. package/ios/common/BackgroundGeolocation/MAURSessionLocationDAO.h +25 -0
  190. package/ios/common/BackgroundGeolocation/MAURSessionLocationDAO.m +153 -0
  191. package/ios/common/BackgroundGeolocation/MAURUncaughtExceptionLogger.h +20 -0
  192. package/ios/common/BackgroundGeolocation/MAURUncaughtExceptionLogger.m +62 -0
  193. package/ios/common/BackgroundGeolocation/MAURUrlTemplateResolver.h +31 -0
  194. package/ios/common/BackgroundGeolocation/MAURUrlTemplateResolver.m +107 -0
  195. package/ios/common/BackgroundGeolocation/Reachability.h +102 -0
  196. package/ios/common/BackgroundGeolocation/Reachability.m +475 -0
  197. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/README.md +170 -0
  198. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/ext/NSString+ZIMString.h +55 -0
  199. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/ext/NSString+ZIMString.m +47 -0
  200. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlDataManipulationCommand.h +27 -0
  201. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlExpression.h +250 -0
  202. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlExpression.m +259 -0
  203. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlSelectStatement.h +360 -0
  204. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlSelectStatement.m +427 -0
  205. package/ios/common/BackgroundGeolocation/SQLQueryBuilder/sql/ZIMSqlStatement.h +37 -0
  206. package/ios/common/BackgroundGeolocation/module.modulemap +16 -0
  207. package/package.json +82 -0
@@ -0,0 +1,406 @@
1
+ package com.marianhello.bgloc.data.provider;
2
+
3
+ import android.content.ContentProviderOperation;
4
+ import android.content.ContentResolver;
5
+ import android.content.ContentValues;
6
+ import android.content.Context;
7
+ import android.database.Cursor;
8
+ import android.net.Uri;
9
+ import android.text.TextUtils;
10
+
11
+ import com.marianhello.bgloc.ResourceResolver;
12
+ import com.marianhello.bgloc.data.BackgroundLocation;
13
+ import com.marianhello.bgloc.data.LocationDAO;
14
+ import com.marianhello.bgloc.data.sqlite.SQLiteLocationContract;
15
+ import com.marianhello.bgloc.data.sqlite.SQLiteLocationContract.LocationEntry;
16
+ import com.marianhello.logging.LoggerManager;
17
+
18
+ import java.util.ArrayList;
19
+ import java.util.Collection;
20
+
21
+ import ru.andremoniy.sqlbuilder.SqlExpression;
22
+ import ru.andremoniy.sqlbuilder.SqlSelectStatement;
23
+
24
+ public class ContentProviderLocationDAO implements LocationDAO {
25
+ private org.slf4j.Logger logger;
26
+ private ContentResolver mResolver;
27
+ private Uri mContentUri;
28
+ private String mAuthority;
29
+
30
+ public ContentProviderLocationDAO(Context context) {
31
+ logger = LoggerManager.getLogger(ContentProviderLocationDAO.class);
32
+ ResourceResolver resourceResolver = ResourceResolver.newInstance(context);
33
+ mAuthority = resourceResolver.getAuthority();
34
+ mContentUri = LocationContentProvider.getContentUri(mAuthority);
35
+ mResolver = context.getApplicationContext().getContentResolver();
36
+ }
37
+
38
+ /**
39
+ * Get locations that match whereClause
40
+ *
41
+ * @param whereClause
42
+ * @param whereArgs
43
+ * @return collection of locations
44
+ */
45
+ private Collection<BackgroundLocation> getLocations(String whereClause, String[] whereArgs) {
46
+ Collection<BackgroundLocation> locations = new ArrayList<BackgroundLocation>();
47
+ Cursor cursor = null;
48
+
49
+ try {
50
+ cursor = mResolver.query(
51
+ mContentUri,
52
+ null,
53
+ whereClause,
54
+ whereArgs,
55
+ LocationEntry.COLUMN_NAME_TIME + " ASC"
56
+ );
57
+ while (cursor.moveToNext()) {
58
+ locations.add(BackgroundLocation.fromCursor(cursor));
59
+ }
60
+ } finally {
61
+ if (cursor != null) {
62
+ cursor.close();
63
+ }
64
+ }
65
+
66
+ return locations;
67
+ }
68
+
69
+ @Override
70
+ public Collection<BackgroundLocation> getAllLocations() {
71
+ return getLocations(null, null);
72
+ }
73
+
74
+ @Override
75
+ public Collection<BackgroundLocation> getValidLocations() {
76
+ String whereClause = LocationEntry.COLUMN_NAME_STATUS + " <> ?";
77
+ String[] whereArgs = { String.valueOf(BackgroundLocation.DELETED) };
78
+
79
+ return getLocations(whereClause, whereArgs);
80
+ }
81
+
82
+ @Override
83
+ public Collection<BackgroundLocation> getValidLocationsAndDelete() {
84
+ // HM TODO: should be in a transaction but I'm not sure how to implement this...
85
+ Collection<BackgroundLocation> locations = getValidLocations();
86
+ deleteAllLocations();
87
+ return locations;
88
+ }
89
+
90
+ @Override
91
+ public BackgroundLocation getLocationById(long id) {
92
+ BackgroundLocation location = null;
93
+
94
+ Cursor cursor = null;
95
+ try {
96
+ cursor = mResolver.query(
97
+ LocationContentProvider.buildUriWithId(mAuthority, id),
98
+ null,
99
+ null,
100
+ null,
101
+ null
102
+ );
103
+ while (cursor.moveToNext()) {
104
+ location = BackgroundLocation.fromCursor(cursor);
105
+ if (!cursor.isLast()) {
106
+ throw new RuntimeException("Location " + id + " is not unique");
107
+ }
108
+ }
109
+ } finally {
110
+ if (cursor != null) {
111
+ cursor.close();
112
+ }
113
+ }
114
+
115
+ return location;
116
+
117
+ }
118
+
119
+ public int getLocationsCount() {
120
+ Cursor cursor = mResolver.query(
121
+ mContentUri,
122
+ null,
123
+ null,
124
+ null,
125
+ ""
126
+ );
127
+
128
+ int count = cursor.getCount();
129
+ cursor.close();
130
+ return count;
131
+ }
132
+
133
+ @Override
134
+ public BackgroundLocation getFirstUnpostedLocation() {
135
+ SqlSelectStatement subsql = new SqlSelectStatement();
136
+ subsql.column(new SqlExpression(String.format("MIN(%s)", LocationEntry._ID)), LocationEntry._ID);
137
+ subsql.from(LocationEntry.TABLE_NAME);
138
+ subsql.where(LocationEntry.COLUMN_NAME_STATUS, SqlExpression.SqlOperatorEqualTo, BackgroundLocation.POST_PENDING);
139
+ subsql.orderBy(LocationEntry.COLUMN_NAME_TIME);
140
+
141
+ String substmt = subsql.statement();
142
+ substmt = com.marianhello.utils.TextUtils.removeLastChar(substmt, ";");
143
+
144
+ BackgroundLocation location = null;
145
+ Cursor cursor = null;
146
+ try {
147
+ cursor = mResolver.query(
148
+ mContentUri,
149
+ null,
150
+ LocationEntry._ID + " = (" + substmt + ")",
151
+ null,
152
+ null
153
+ );
154
+
155
+ while (cursor.moveToNext()) {
156
+ location = BackgroundLocation.fromCursor(cursor);
157
+ if (!cursor.isLast()) {
158
+ throw new RuntimeException("Expected single location");
159
+ }
160
+ }
161
+ } finally {
162
+ if (cursor != null) {
163
+ cursor.close();
164
+ }
165
+ }
166
+
167
+ return location;
168
+ }
169
+
170
+ @Override
171
+ public BackgroundLocation getNextUnpostedLocation(long fromId) {
172
+ SqlSelectStatement subsql = new SqlSelectStatement();
173
+ subsql.column(new SqlExpression(String.format("MIN(%s)", LocationEntry._ID)), LocationEntry._ID);
174
+ subsql.from(LocationEntry.TABLE_NAME);
175
+ subsql.where(LocationEntry.COLUMN_NAME_STATUS, SqlExpression.SqlOperatorEqualTo, BackgroundLocation.POST_PENDING);
176
+ subsql.where(LocationEntry._ID, SqlExpression.SqlOperatorNotEqualTo, fromId);
177
+ subsql.orderBy(LocationEntry.COLUMN_NAME_TIME);
178
+
179
+ String substmt = subsql.statement();
180
+ substmt = com.marianhello.utils.TextUtils.removeLastChar(substmt, ";");
181
+
182
+ BackgroundLocation location = null;
183
+ Cursor cursor = null;
184
+ try {
185
+ cursor = mResolver.query(
186
+ mContentUri,
187
+ null,
188
+ LocationEntry._ID + " = (" + substmt + ")",
189
+ null,
190
+ null
191
+ );
192
+
193
+ while (cursor.moveToNext()) {
194
+ location = BackgroundLocation.fromCursor(cursor);
195
+ if (!cursor.isLast()) {
196
+ throw new RuntimeException("Expected single location");
197
+ }
198
+ }
199
+ } finally {
200
+ if (cursor != null) {
201
+ cursor.close();
202
+ }
203
+ }
204
+
205
+ return location;
206
+ }
207
+
208
+ @Override
209
+ public long getUnpostedLocationsCount() {
210
+ String whereClause = SQLiteLocationContract.LocationEntry.COLUMN_NAME_STATUS + " = ?";
211
+ String[] whereArgs = { String.valueOf(BackgroundLocation.POST_PENDING) };
212
+
213
+ Cursor cursor = mResolver.query(
214
+ mContentUri,
215
+ null,
216
+ whereClause,
217
+ whereArgs,
218
+ null);
219
+
220
+ int count = cursor.getCount();
221
+ cursor.close();
222
+ return count;
223
+ }
224
+
225
+ @Override
226
+ public long getLocationsForSyncCount(long millisSinceLastBatch) {
227
+ String whereClause = TextUtils.join("", new String[]{
228
+ SQLiteLocationContract.LocationEntry.COLUMN_NAME_STATUS + " = ? AND ( ",
229
+ SQLiteLocationContract.LocationEntry.COLUMN_NAME_BATCH_START_MILLIS + " IS NULL OR ",
230
+ SQLiteLocationContract.LocationEntry.COLUMN_NAME_BATCH_START_MILLIS + " < ? )",
231
+ });
232
+ String[] whereArgs = {
233
+ String.valueOf(BackgroundLocation.SYNC_PENDING),
234
+ String.valueOf(millisSinceLastBatch)
235
+ };
236
+
237
+ Cursor cursor = mResolver.query(
238
+ mContentUri,
239
+ null,
240
+ whereClause,
241
+ whereArgs,
242
+ null);
243
+
244
+ int count = cursor.getCount();
245
+ cursor.close();
246
+ return count;
247
+ }
248
+
249
+ public Uri getOldestLocationUri() {
250
+ Cursor cursor = null;
251
+ try {
252
+ cursor = mResolver.query(
253
+ mContentUri,
254
+ new String[]{"min(" + LocationEntry._ID + ")"},
255
+ TextUtils.join("", new String[]{
256
+ LocationEntry.COLUMN_NAME_TIME,
257
+ "= (SELECT min(",
258
+ LocationEntry.COLUMN_NAME_TIME,
259
+ ") FROM ",
260
+ LocationEntry.TABLE_NAME,
261
+ ")"
262
+ }),
263
+ null,
264
+ null
265
+ );
266
+
267
+ cursor.moveToFirst();
268
+ return LocationContentProvider.buildUriWithId(mAuthority, cursor.getLong(0));
269
+ } finally {
270
+ if (cursor != null) {
271
+ cursor.close();
272
+ }
273
+ }
274
+ }
275
+
276
+ /**
277
+ * Persist location into database
278
+ *
279
+ * @param location
280
+ * @return rowId or -1 when error occured
281
+ */
282
+ @Override
283
+ public long persistLocation(BackgroundLocation location) {
284
+ Uri locationUri = mResolver.insert(mContentUri, location.toContentValues());
285
+ return Integer.valueOf(locationUri.getLastPathSegment());
286
+ }
287
+
288
+ @Override
289
+ public long persistLocation(BackgroundLocation location, int maxRows) {
290
+ if (maxRows == 0) {
291
+ return -1;
292
+ }
293
+
294
+ long rowCount = getLocationsCount();
295
+
296
+ if (rowCount < maxRows) {
297
+ return persistLocation(location);
298
+ }
299
+
300
+ ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
301
+
302
+ // TODO: move this logic as separate action somewhere else
303
+ // TODO: add db vaccum
304
+ if (rowCount > maxRows) {
305
+ // delete some locations to reduce their count to maxRows
306
+ String selection = new StringBuilder()
307
+ .append(LocationEntry._ID)
308
+ .append(" IN (SELECT ").append(LocationEntry._ID)
309
+ .append(" FROM ").append(LocationEntry.TABLE_NAME)
310
+ .append(" ORDER BY ").append(LocationEntry.COLUMN_NAME_TIME)
311
+ .append(" LIMIT ?)")
312
+ .toString();
313
+
314
+ operations.add(
315
+ ContentProviderOperation.newDelete(mContentUri)
316
+ .withSelection(selection, new String[] {(String.valueOf(rowCount - maxRows))})
317
+ .build()
318
+ );
319
+ }
320
+
321
+ operations.add(
322
+ ContentProviderOperation.newUpdate(getOldestLocationUri())
323
+ .withValues(location.toContentValues())
324
+ .build()
325
+ );
326
+
327
+ try {
328
+ mResolver.applyBatch(mAuthority, operations);
329
+ } catch (Exception e) {
330
+ logger.error("Error persisting location (maxRows: {}): {}", maxRows, e.getMessage());
331
+ return -1;
332
+ }
333
+
334
+ return 0;
335
+ }
336
+
337
+ @Override
338
+ public long persistLocationForSync(BackgroundLocation location, int maxRows) {
339
+ Long locationId = location.getLocationId();
340
+
341
+ if (locationId == null) {
342
+ location.setStatus(BackgroundLocation.SYNC_PENDING);
343
+ return persistLocation(location, maxRows);
344
+ } else {
345
+ ContentValues values = new ContentValues();
346
+ values.put(LocationEntry.COLUMN_NAME_STATUS, BackgroundLocation.SYNC_PENDING);
347
+
348
+ String whereClause = LocationEntry._ID + " = ?";
349
+ String[] whereArgs = { String.valueOf(locationId) };
350
+
351
+ mResolver.update(mContentUri, values, whereClause, whereArgs);
352
+ return locationId;
353
+ }
354
+ }
355
+
356
+ @Override
357
+ public void updateLocationForSync(long locationId) {
358
+ ContentValues values = new ContentValues();
359
+ values.put(LocationEntry.COLUMN_NAME_STATUS, BackgroundLocation.SYNC_PENDING);
360
+
361
+ String whereClause = LocationEntry._ID + " = ?";
362
+ String[] whereArgs = { String.valueOf(locationId) };
363
+
364
+ mResolver.update(mContentUri, values, whereClause, whereArgs);
365
+ }
366
+
367
+ @Override
368
+ public void deleteLocationById(long locationId) {
369
+ mResolver.delete(LocationContentProvider.buildUriWithId(mAuthority, locationId), null, null);
370
+ }
371
+
372
+ @Override
373
+ public BackgroundLocation deleteFirstUnpostedLocation() {
374
+ BackgroundLocation location = getFirstUnpostedLocation();
375
+ deleteLocationById(location.getLocationId());
376
+
377
+ return location;
378
+ }
379
+
380
+ @Override
381
+ public int deleteAllLocations() {
382
+ return mResolver.delete(mContentUri, null, null);
383
+ }
384
+
385
+ @Override
386
+ public int deleteUnpostedLocations() {
387
+ ContentValues values = new ContentValues();
388
+ values.put(LocationEntry.COLUMN_NAME_STATUS, BackgroundLocation.SYNC_PENDING);
389
+
390
+ String whereClause = LocationEntry.COLUMN_NAME_STATUS + " = ?";
391
+ String[] whereArgs = { String.valueOf(BackgroundLocation.POST_PENDING) };
392
+
393
+ return mResolver.update(mContentUri, values, whereClause, whereArgs);
394
+ }
395
+
396
+ @Override
397
+ public int deletePendingSyncLocations() {
398
+ ContentValues values = new ContentValues();
399
+ values.put(LocationEntry.COLUMN_NAME_STATUS, BackgroundLocation.DELETED);
400
+
401
+ String whereClause = LocationEntry.COLUMN_NAME_STATUS + " = ?";
402
+ String[] whereArgs = { String.valueOf(BackgroundLocation.SYNC_PENDING) };
403
+
404
+ return mResolver.update(mContentUri, values, whereClause, whereArgs);
405
+ }
406
+ }