Сравнить коммиты

..
64 Коммитов
Автор SHA1 Сообщение Дата
Anton Tananaev 1b0559c98a Update version number 2018-10-18 16:05:48 +13:00
Anton Tananaev 2e0e7ea453 Fix merge issues 2018-10-18 15:44:58 +13:00
Anton Tananaev ac6d677ff4 Explicitly select location providers 2018-10-18 15:43:07 +13:00
Anton Tananaev cbfe90757d Disable advertising id collection 2018-09-22 08:51:41 +12:00
Anton Tananaev a9f4390ae4 Update app version 2018-09-15 08:54:32 +12:00
Anton Tananaev 8a938701c8 Improve service handling 2018-09-15 08:54:09 +12:00
Anton Tananaev 2319834c5b Handle runtime exceptions 2018-09-15 08:48:37 +12:00
Anton Tananaev 1b93619e64 Update app version 2018-09-13 12:08:05 +12:00
Anton Tananaev 2a36e1aa6d Remove Lost library 2018-09-12 13:55:30 +12:00
Anton Tananaev 64687b26c2 Merge pull request #357 from oliv3/bug_350
Gracefully handle package downgrade (fix #350)
2018-09-06 08:17:42 +12:00
Olivier Girondel dcb60ab75e Gracefully handle package downgrade (fix #350) 2018-09-04 14:30:09 +02:00
Anton Tananaev 0b4c4cccc6 Merge pull request #347 from oliv3/statusSeconds
Display seconds in the status activity
2018-08-28 08:40:57 +12:00
Olivier Girondel ef5bfff70a Display seconds in the status activity 2018-08-25 15:11:57 +02:00
Anton Tananaev 855efc7acb Merge pull request #345 from oliv3/distance
Remove DistanceCalculator class
2018-08-21 08:46:33 +12:00
Olivier Girondel 0ae47e65d4 Remove DistanceCalculator class 2018-08-20 15:57:01 +02:00
Anton Tananaev e8d5e5c99b Update robolectric library 2018-08-09 14:46:02 +12:00
Anton Tananaev c3980780d8 Update project and dependencies 2018-08-09 14:33:05 +12:00
Anton Tananaev 3c11216334 Check API version 2018-05-06 16:44:56 -07:00
Anton Tananaev bcde8388d6 Update database version 2018-05-01 10:01:57 +12:00
Anton Tananaev 7f18915514 Merge pull request #327 from oliv3/mock_locations
Report mock locations
2018-04-30 13:54:15 +12:00
Olivier Girondel 42ad669fca Tell if a location is a mock 2018-04-30 02:16:10 +02:00
Anton Tananaev 3e2b508ea7 Update version number 2018-03-19 22:23:05 +13:00
Anton Tananaev fd4d616812 Check permissions in service 2018-03-19 22:22:45 +13:00
Anton Tananaev 4f6571e572 Update app version number 2018-03-18 21:28:11 +13:00
Anton Tananaev d3025b437b Replace firebase old crash reporting 2018-03-18 21:27:27 +13:00
Anton Tananaev 1e861ef0ac Fix hidden app URL open issue (fix #321) 2018-02-19 09:49:50 +13:00
Anton Tananaev 43afc57114 Merge pull request #318 from garyvdm/online_status
Show online/offline in connection changed status messages
2018-02-15 23:03:55 +13:00
Gary van der Merwe d47783808f Show online/offline in connection changed status messages. 2018-02-15 12:03:09 +02:00
Anton Tananaev 3ef2272227 Merge pull request #320 from garyvdm/revert-301-vector
Revert "Use vector icons"
2018-02-15 22:24:54 +13:00
Gary van der Merwe 3625ee42db Revert "Use vector icons." 2018-02-15 11:04:38 +02:00
Anton Tananaev 385826c3c1 Merge pull request #301 from garyvdm/vector
Use vector icons
2018-02-14 09:42:29 +13:00
Gary van der Merwe 1426926c8e Use vector icons. 2018-02-13 18:33:01 +02:00
Anton Tananaev 4f680d33c9 Merge pull request #311 from Bubu/patch-1
Add google maven repo
2018-01-23 08:20:51 +13:00
Marcus Hoffmann 2dad912da5 Add google() repo
This is required to build the app outside of Android Studio.

Fixes:
 > Could not find com.android.tools.build:gradle:3.0.1.
     Searched in the following locations:
         https://jcenter.bintray.com/com/android/tools/build/gradle/3.0.1/gradle-3.0.1.pom
         https://jcenter.bintray.com/com/android/tools/build/gradle/3.0.1/gradle-3.0.1.jar
2018-01-22 20:15:20 +01:00
Anton Tananaev 290a7d80eb Update app version number 2018-01-19 17:43:43 +13:00
Anton Tananaev 44228feb2f Fix SOS functionality 2018-01-19 17:43:18 +13:00
Anton Tananaev d887bc4119 Update version number 2018-01-09 08:26:19 +13:00
Anton Tananaev c892a20104 Fix lost API connection logic 2018-01-09 08:25:57 +13:00
Anton Tananaev 2719b57f7c Use color code directly 2018-01-07 09:26:55 +13:00
Anton Tananaev cc6c8a23f6 Update project files 2018-01-07 09:23:14 +13:00
Anton Tananaev 1e82cbbbf6 Merge pull request #305 from Alpha200/fixAccuracy
Fix reading accuracy property
2017-12-30 10:40:06 +13:00
Daniel Sendzik 4b8fde36d7 Fix reading accuracy property 2017-12-29 19:34:14 +01:00
Anton Tananaev b8cd56439a Merge pull request #304 from garyvdm/restore_startWakefulForegroundService
Restore fix auto-start issue on Android O
2017-12-21 23:03:37 +13:00
Gary van der Merwe edb1f696df Restore fix auto-start issue on Android O.
Also rename startWakefulService to startWakefulForegroundService to highlight
that it's different to the SDK version.
2017-12-21 11:54:14 +02:00
Anton Tananaev 56d2f2ef53 Merge pull request #303 from garyvdm/cleanup
Remove unnecessary code
2017-12-21 09:52:43 +13:00
Gary van der Merwe 59e6a5ae65 Remove code that was originally included for supporting older SDK APIs that are now older than our minSdkVersion. 2017-12-20 14:17:51 +02:00
Anton Tananaev 319fab647b Merge pull request #302 from garyvdm/hidden_notification
For hidden flavor, make notificaion not open the app when clicked, use different icon
2017-12-16 09:47:04 +13:00
Gary van der Merwe 42429f3496 For hidden flavor, make notification open system settings activity. 2017-12-15 12:38:56 +02:00
Gary van der Merwe 841d3e581c For hidden flavor, make notificaion not open the app when clicked, use different icon.
This only apply to when the notificaion can't be hidden, i.e. SDK >= 25.
2017-12-15 09:09:25 +02:00
Anton Tananaev dac43ccbc1 Merge pull request #300 from garyvdm/notification
Get service notification to show. Tweek settings.
2017-12-14 13:53:22 +13:00
Gary van der Merwe 3c9ae512bd Get service notification to show. Tweek settings. 2017-12-13 08:11:11 +02:00
Anton Tananaev d3e600d81d Gracefully stop location updates 2017-11-23 00:03:17 +13:00
Anton Tananaev e0296a9c65 Use fused location provider 2017-11-22 23:59:52 +13:00
Anton Tananaev e51f590e19 Merge pull request #297 from Mantas0726/master
Update PositionProvider.java
2017-11-15 09:57:45 +13:00
Mantas0726 6e3812320c Update PositionProvider.java 2017-11-14 22:20:11 +02:00
Anton Tananaev c45c8ea797 Update version number 2017-09-25 15:08:10 +13:00
Anton Tananaev ed0aa53aa3 Fix null pointer crash 2017-09-25 15:04:19 +13:00
Anton Tananaev f88891be2b Add another hidden intent filter 2017-09-25 15:01:56 +13:00
Anton Tananaev 3f83684d02 Update version number 2017-09-20 05:23:51 +12:00
Anton Tananaev a9d772bfda Restart service after upgrade 2017-09-20 05:23:27 +12:00
Anton Tananaev 2bc3c78a91 Update version number 2017-09-12 23:22:33 +12:00
Anton Tananaev 8fab55552d Handle no network provider 2017-09-12 23:21:58 +12:00
Anton Tananaev 979963f6a2 Fix auto-start issue on Android O 2017-09-07 19:04:10 +12:00
Anton Tananaev 70d6dfec4e Fix issue with URL migration 2017-09-02 20:01:13 +12:00
26 изменённых файлов: 361 добавлений и 377 удалений
+16 -15
Просмотреть файл
@@ -1,22 +1,23 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion '26.0.1'
compileSdkVersion 28
buildToolsVersion '28.0.2'
defaultConfig {
applicationId "org.traccar.client"
buildConfigField "boolean", "HIDDEN_APP", "false"
minSdkVersion 14
targetSdkVersion 26
versionCode 38
versionName '5.1'
minSdkVersion 15
targetSdkVersion 28
versionCode 52
versionName '5.15'
}
lintOptions {
checkReleaseBuilds false
}
flavorDimensions "default"
productFlavors {
regular
google
@@ -26,24 +27,24 @@ android {
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt')
testOptions {
unitTests {
includeAndroidResources = true
}
}
}
dependencies {
compile 'com.android.support:design:26.0.1'
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.4.2'
googleCompile 'com.google.firebase:firebase-core:11.2.0'
googleCompile 'com.google.firebase:firebase-crash:11.2.0'
implementation 'com.android.support:design:28.0.0-rc02'
testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:3.8'
googleImplementation 'com.google.firebase:firebase-core:16.0.3'
googleImplementation 'com.crashlytics.sdk.android:crashlytics:2.9.5'
}
if (getGradle().getStartParameter().getTaskRequests().toString().contains("Google")) {
apply plugin: 'com.google.gms.google-services'
apply plugin: 'io.fabric'
task copyJson(type: Copy) {
from '../../traccar-shared/google-services'
+10
Просмотреть файл
@@ -8,6 +8,16 @@
android:label="@string/hidden_app_name"
tools:replace="android:label">
<activity
android:name="org.traccar.client.MainActivity">
<intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="www.traccar.org" android:pathPrefix="/hidden" />
</intent-filter>
</activity>
<receiver android:name="org.traccar.client.DialLaunchReceiver" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
+9
Просмотреть файл
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.11,0 2,-0.9 2,-2L21,5c0,-1.1 -0.89,-2 -2,-2zM17.25,12c0,0.23 -0.02,0.46 -0.05,0.68l1.48,1.16c0.13,0.11 0.17,0.3 0.08,0.45l-1.4,2.42c-0.09,0.15 -0.27,0.21 -0.43,0.15l-1.74,-0.7c-0.36,0.28 -0.76,0.51 -1.18,0.69l-0.26,1.85c-0.03,0.17 -0.18,0.3 -0.35,0.3h-2.8c-0.17,0 -0.32,-0.13 -0.35,-0.29l-0.26,-1.85c-0.43,-0.18 -0.82,-0.41 -1.18,-0.69l-1.74,0.7c-0.16,0.06 -0.34,0 -0.43,-0.15l-1.4,-2.42c-0.09,-0.15 -0.05,-0.34 0.08,-0.45l1.48,-1.16c-0.03,-0.23 -0.05,-0.46 -0.05,-0.69 0,-0.23 0.02,-0.46 0.05,-0.68l-1.48,-1.16c-0.13,-0.11 -0.17,-0.3 -0.08,-0.45l1.4,-2.42c0.09,-0.15 0.27,-0.21 0.43,-0.15l1.74,0.7c0.36,-0.28 0.76,-0.51 1.18,-0.69l0.26,-1.85c0.03,-0.17 0.18,-0.3 0.35,-0.3h2.8c0.17,0 0.32,0.13 0.35,0.29l0.26,1.85c0.43,0.18 0.82,0.41 1.18,0.69l1.74,-0.7c0.16,-0.06 0.34,0 0.43,0.15l1.4,2.42c0.09,0.15 0.05,0.34 -0.08,0.45l-1.48,1.16c0.03,0.23 0.05,0.46 0.05,0.69z"/>
</vector>
+9
Просмотреть файл
@@ -9,15 +9,21 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<application
android:allowBackup="true"
android:networkSecurityConfig="@xml/network_security_config"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name=".MainApplication">
<meta-data
android:name="google_analytics_adid_collection_enabled"
android:value="false" />
<activity
android:name=".MainActivity"
android:launchMode="singleTask" />
@@ -55,6 +61,9 @@
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
</application>
+2 -3
Просмотреть файл
@@ -1,5 +1,5 @@
/*
* Copyright 2013 Anton Tananaev (anton.tananaev@gmail.com)
* Copyright 2013 - 2017 Anton Tananaev (anton.tananaev@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v4.content.WakefulBroadcastReceiver;
public class AutostartReceiver extends WakefulBroadcastReceiver {
@@ -27,7 +26,7 @@ public class AutostartReceiver extends WakefulBroadcastReceiver {
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedPreferences.getBoolean(MainFragment.KEY_STATUS, false)) {
startWakefulService(context, new Intent(context, TrackingService.class));
startWakefulForegroundService(context, new Intent(context, TrackingService.class));
}
}
+11 -3
Просмотреть файл
@@ -27,7 +27,7 @@ import java.util.Date;
public class DatabaseHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 2;
public static final int DATABASE_VERSION = 3;
public static final String DATABASE_NAME = "traccar.db";
public interface DatabaseHandler<T> {
@@ -80,7 +80,8 @@ public class DatabaseHelper extends SQLiteOpenHelper {
"speed REAL," +
"course REAL," +
"accuracy REAL," +
"battery REAL)");
"battery REAL," +
"mock INTEGER)");
}
@Override
@@ -89,6 +90,11 @@ public class DatabaseHelper extends SQLiteOpenHelper {
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS position;");
onCreate(db);
}
public void insertPosition(Position position) {
ContentValues values = new ContentValues();
values.put("deviceId", position.getDeviceId());
@@ -98,8 +104,9 @@ public class DatabaseHelper extends SQLiteOpenHelper {
values.put("altitude", position.getAltitude());
values.put("speed", position.getSpeed());
values.put("course", position.getCourse());
values.put("accuracy", position.getCourse());
values.put("accuracy", position.getAccuracy());
values.put("battery", position.getBattery());
values.put("mock", position.getMock() ? 1 : 0);
db.insertOrThrow("position", null, values);
}
@@ -133,6 +140,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
position.setCourse(cursor.getDouble(cursor.getColumnIndex("course")));
position.setAccuracy(cursor.getDouble(cursor.getColumnIndex("accuracy")));
position.setBattery(cursor.getDouble(cursor.getColumnIndex("battery")));
position.setMock(cursor.getInt(cursor.getColumnIndex("mock")) > 0);
} else {
return null;
-33
Просмотреть файл
@@ -1,33 +0,0 @@
/*
* Copyright 2017 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.traccar.client;
public final class DistanceCalculator {
private static final double EQUATORIAL_EARTH_RADIUS = 6378.1370;
private static final double DEG_TO_RAD = Math.PI / 180;
public static double distance(double lat1, double lon1, double lat2, double lon2) {
double dlong = (lon2 - lon1) * DEG_TO_RAD;
double dlat = (lat2 - lat1) * DEG_TO_RAD;
double a = Math.pow(Math.sin(dlat / 2), 2)
+ Math.cos(lat1 * DEG_TO_RAD) * Math.cos(lat2 * DEG_TO_RAD) * Math.pow(Math.sin(dlong / 2), 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double d = EQUATORIAL_EARTH_RADIUS * c;
return d * 1000;
}
}
+23
Просмотреть файл
@@ -21,8 +21,11 @@ import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.preference.PreferenceManager;
public class MainApplication extends Application {
@@ -33,6 +36,8 @@ public class MainApplication extends Application {
super.onCreate();
System.setProperty("http.keepAliveDuration", String.valueOf(30 * 60 * 1000));
migrateLegacyPreferences(PreferenceManager.getDefaultSharedPreferences(this));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
registerChannel();
}
@@ -47,4 +52,22 @@ public class MainApplication extends Application {
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
}
private void migrateLegacyPreferences(SharedPreferences preferences) {
String port = preferences.getString("port", null);
if (port != null) {
String host = preferences.getString("address", getString(R.string.settings_url_default_value));
String scheme = preferences.getBoolean("secure", false) ? "https" : "http";
Uri.Builder builder = new Uri.Builder();
builder.scheme(scheme).encodedAuthority(host + ":" + port).build();
SharedPreferences.Editor editor = preferences.edit();
editor.putString(MainFragment.KEY_URL, builder.toString());
editor.remove("port");
editor.remove("address");
editor.remove("secure");
editor.apply();
}
}
}
+6 -39
Просмотреть файл
@@ -58,7 +58,7 @@ public class MainFragment extends PreferenceFragment implements OnSharedPreferen
public static final String KEY_INTERVAL = "interval";
public static final String KEY_DISTANCE = "distance";
public static final String KEY_ANGLE = "angle";
public static final String KEY_PROVIDER = "provider";
public static final String KEY_ACCURACY = "accuracy";
public static final String KEY_STATUS = "status";
private static final int PERMISSIONS_REQUEST_LOCATION = 2;
@@ -78,7 +78,6 @@ public class MainFragment extends PreferenceFragment implements OnSharedPreferen
setHasOptionsMenu(true);
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
migrateLegacyPreferences(sharedPreferences);
addPreferencesFromResource(R.xml.preferences);
initPreferences();
@@ -151,13 +150,6 @@ public class MainFragment extends PreferenceFragment implements OnSharedPreferen
}
}
private boolean hasPermission(String permission) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
return true;
}
return ContextCompat.checkSelfPermission(getActivity(), permission) == PackageManager.PERMISSION_GRANTED;
}
@Override
public void onResume() {
super.onResume();
@@ -176,7 +168,7 @@ public class MainFragment extends PreferenceFragment implements OnSharedPreferen
findPreference(KEY_INTERVAL).setEnabled(enabled);
findPreference(KEY_DISTANCE).setEnabled(enabled);
findPreference(KEY_ANGLE).setEnabled(enabled);
findPreference(KEY_PROVIDER).setEnabled(enabled);
findPreference(KEY_ACCURACY).setEnabled(enabled);
}
@Override
@@ -224,10 +216,10 @@ public class MainFragment extends PreferenceFragment implements OnSharedPreferen
private void startTrackingService(boolean checkPermission, boolean permission) {
if (checkPermission) {
Set<String> missingPermissions = new HashSet<>();
if (!hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
missingPermissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (!hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION)) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
missingPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (missingPermissions.isEmpty()) {
@@ -248,13 +240,8 @@ public class MainFragment extends PreferenceFragment implements OnSharedPreferen
ALARM_MANAGER_INTERVAL, ALARM_MANAGER_INTERVAL, alarmIntent);
} else {
sharedPreferences.edit().putBoolean(KEY_STATUS, false).apply();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
TwoStatePreference preference = (TwoStatePreference) findPreference(KEY_STATUS);
preference.setChecked(false);
} else {
CheckBoxPreference preference = (CheckBoxPreference) findPreference(KEY_STATUS);
preference.setChecked(false);
}
TwoStatePreference preference = (TwoStatePreference) findPreference(KEY_STATUS);
preference.setChecked(false);
}
}
@@ -288,24 +275,4 @@ public class MainFragment extends PreferenceFragment implements OnSharedPreferen
return false;
}
private void migrateLegacyPreferences(SharedPreferences preferences) {
String port = preferences.getString("port", null);
if (port != null) {
Log.d(TAG, "Migrating to URL preference");
String host = preferences.getString("address", getString(R.string.settings_url_default_value));
String scheme = preferences.getBoolean("secure", false) ? "https" : "http";
Uri.Builder builder = new Uri.Builder();
builder.scheme(scheme).encodedAuthority(host + ":" + port).build();
SharedPreferences.Editor editor = preferences.edit();
editor.putString(KEY_URL, builder.toString());
editor.remove("port");
editor.remove("address");
editor.remove("secure");
editor.apply();
}
}
}
-122
Просмотреть файл
@@ -1,122 +0,0 @@
/*
* Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.traccar.client;
import android.content.Context;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
@SuppressWarnings("MissingPermission")
public class MixedPositionProvider extends PositionProvider implements LocationListener, GpsStatus.Listener {
private static final int FIX_TIMEOUT = 30 * 1000;
private LocationListener backupListener;
private long lastFixTime;
public MixedPositionProvider(Context context, PositionListener listener) {
super(context, listener);
}
public void startUpdates() {
lastFixTime = System.currentTimeMillis();
locationManager.addGpsStatusListener(this);
try {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, requestInterval, 0, this);
} catch (IllegalArgumentException e) {
Log.w(TAG, e);
}
}
public void stopUpdates() {
locationManager.removeUpdates(this);
locationManager.removeGpsStatusListener(this);
stopBackupProvider();
}
private void startBackupProvider() {
Log.i(TAG, "backup provider start");
if (backupListener == null) {
backupListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.i(TAG, "backup provider location");
updateLocation(location);
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
};
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, requestInterval, 0, backupListener);
}
}
private void stopBackupProvider() {
Log.i(TAG, "backup provider stop");
if (backupListener != null) {
locationManager.removeUpdates(backupListener);
backupListener = null;
}
}
@Override
public void onLocationChanged(Location location) {
Log.i(TAG, "provider location");
stopBackupProvider();
lastFixTime = System.currentTimeMillis();
updateLocation(location);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
Log.i(TAG, "provider enabled");
stopBackupProvider();
}
@Override
public void onProviderDisabled(String provider) {
Log.i(TAG, "provider disabled");
startBackupProvider();
}
@Override
public void onGpsStatusChanged(int event) {
if (backupListener == null && System.currentTimeMillis() - lastFixTime - requestInterval > FIX_TIMEOUT) {
startBackupProvider();
}
}
}
+15 -1
Просмотреть файл
@@ -1,5 +1,5 @@
/*
* Copyright 2015 - 2017 Anton Tananaev (anton.tananaev@gmail.com)
* Copyright 2015 - 2018 Anton Tananaev (anton.tananaev@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package org.traccar.client;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import java.util.Date;
@@ -37,6 +38,9 @@ public class Position {
accuracy = location.getAccuracy();
}
this.battery = battery;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
this.mock = location.isFromMockProvider();
}
}
private long id;
@@ -139,4 +143,14 @@ public class Position {
this.battery = battery;
}
private boolean mock;
public boolean getMock() {
return mock;
}
public void setMock(boolean mock) {
this.mock = mock;
}
}
+58 -24
Просмотреть файл
@@ -15,19 +15,23 @@
*/
package org.traccar.client;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.BatteryManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
public abstract class PositionProvider {
public class PositionProvider implements LocationListener {
protected static final String TAG = PositionProvider.class.getSimpleName();
private static final String TAG = PositionProvider.class.getSimpleName();
private static final int MINIMUM_INTERVAL = 1000;
@@ -38,14 +42,13 @@ public abstract class PositionProvider {
private final PositionListener listener;
private final Context context;
protected final LocationManager locationManager;
private SharedPreferences preferences;
private LocationManager locationManager;
private String deviceId;
protected String type;
protected long requestInterval;
protected long interval;
protected double distance;
protected double angle;
private long interval;
private double distance;
private double angle;
private Location lastLocation;
@@ -53,31 +56,43 @@ public abstract class PositionProvider {
this.context = context;
this.listener = listener;
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
preferences = PreferenceManager.getDefaultSharedPreferences(context);
deviceId = preferences.getString(MainFragment.KEY_DEVICE, "undefined");
interval = Long.parseLong(preferences.getString(MainFragment.KEY_INTERVAL, "600")) * 1000;
distance = Integer.parseInt(preferences.getString(MainFragment.KEY_DISTANCE, "0"));
angle = Integer.parseInt(preferences.getString(MainFragment.KEY_ANGLE, "0"));
if (distance > 0 || angle > 0) {
requestInterval = MINIMUM_INTERVAL;
} else {
requestInterval = interval;
}
type = preferences.getString(MainFragment.KEY_PROVIDER, "gps");
}
public abstract void startUpdates();
@SuppressLint("MissingPermission")
public void startUpdates() {
try {
locationManager.requestLocationUpdates(
getProvider(preferences.getString(MainFragment.KEY_ACCURACY, "medium")),
distance > 0 || angle > 0 ? MINIMUM_INTERVAL : interval, 0, this);
} catch (RuntimeException e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
public abstract void stopUpdates();
public static String getProvider(String accuracy) {
switch (accuracy) {
case "high":
return LocationManager.GPS_PROVIDER;
case "low":
return LocationManager.PASSIVE_PROVIDER;
default:
return LocationManager.NETWORK_PROVIDER;
}
}
protected void updateLocation(Location location) {
@Override
public void onLocationChanged(Location location) {
if (location != null && (lastLocation == null
|| location.getTime() - lastLocation.getTime() >= interval
|| distance > 0 && DistanceCalculator.distance(location.getLatitude(), location.getLongitude(), lastLocation.getLatitude(), location.getLongitude()) >= distance
|| distance > 0 && location.distanceTo(lastLocation) >= distance
|| angle > 0 && Math.abs(location.getBearing() - lastLocation.getBearing()) >= angle)) {
Log.i(TAG, "location new");
lastLocation = location;
@@ -87,11 +102,30 @@ public abstract class PositionProvider {
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
public void stopUpdates() {
locationManager.removeUpdates(this);
}
public static double getBatteryLevel(Context context) {
Intent batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);
return (level * 100.0) / scale;
if (batteryIntent != null) {
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);
return (level * 100.0) / scale;
}
return 0;
}
}
+4
Просмотреть файл
@@ -36,6 +36,10 @@ public class ProtocolFormatter {
.appendQueryParameter("accuracy", String.valueOf(position.getAccuracy()))
.appendQueryParameter("batt", String.valueOf(position.getBattery()));
if (position.getMock()) {
builder.appendQueryParameter("mock", String.valueOf(position.getMock()));
}
if (alarm != null) {
builder.appendQueryParameter("alarm", alarm);
}
+58 -26
Просмотреть файл
@@ -18,9 +18,13 @@ package org.traccar.client;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.support.annotation.DrawableRes;
import android.support.v4.content.ContextCompat;
@@ -102,39 +106,62 @@ public class ShortcutActivity extends AppCompatActivity {
@SuppressWarnings("MissingPermission")
private void sendAlarm() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location == null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
String provider = PositionProvider.getProvider(
preferences.getString(MainFragment.KEY_ACCURACY, "medium"));
if (location != null) {
Position position = new Position(
preferences.getString(MainFragment.KEY_DEVICE, null),
location, PositionProvider.getBatteryLevel(this));
String request = ProtocolFormatter.formatRequest(
preferences.getString(MainFragment.KEY_URL, null), position, ALARM_SOS);
RequestManager.sendRequestAsync(request, new RequestManager.RequestHandler() {
@Override
public void onComplete(boolean success) {
if (success) {
Toast.makeText(ShortcutActivity.this, R.string.status_send_success, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ShortcutActivity.this, R.string.status_send_fail, Toast.LENGTH_SHORT).show();
try {
Location location = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
if (location != null) {
sendAlarmLocation(location);
} else {
locationManager.requestSingleUpdate(provider, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
sendAlarmLocation(location);
}
}
});
} else {
Toast.makeText(this, R.string.status_send_fail, Toast.LENGTH_SHORT).show();
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}, Looper.myLooper());
}
} catch (RuntimeException e) {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
private void sendAlarmLocation(Location location) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
Position position = new Position(
preferences.getString(MainFragment.KEY_DEVICE, null),
location, PositionProvider.getBatteryLevel(this));
String request = ProtocolFormatter.formatRequest(
preferences.getString(MainFragment.KEY_URL, null), position, ALARM_SOS);
RequestManager.sendRequestAsync(request, new RequestManager.RequestHandler() {
@Override
public void onComplete(boolean success) {
if (success) {
Toast.makeText(ShortcutActivity.this, R.string.status_send_success, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ShortcutActivity.this, R.string.status_send_fail, Toast.LENGTH_SHORT).show();
}
}
});
}
private boolean executeAction(Intent intent) {
String action;
if (intent.hasExtra("shortcutAction")) {
@@ -158,7 +185,12 @@ public class ShortcutActivity extends AppCompatActivity {
Toast.makeText(this, R.string.status_service_destroy, Toast.LENGTH_SHORT).show();
break;
case ACTION_SOS:
sendAlarm();
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
sendAlarm();
} else {
Toast.makeText(this, R.string.status_send_fail, Toast.LENGTH_SHORT).show();
}
break;
}
finish();
-64
Просмотреть файл
@@ -1,64 +0,0 @@
/*
* Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.traccar.client;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
@SuppressWarnings("MissingPermission")
public class SimplePositionProvider extends PositionProvider implements LocationListener {
public SimplePositionProvider(Context context, PositionListener listener) {
super(context, listener);
if (!type.equals(LocationManager.NETWORK_PROVIDER)) {
type = LocationManager.GPS_PROVIDER;
}
}
public void startUpdates() {
try {
locationManager.requestLocationUpdates(type, requestInterval, 0, this);
} catch (IllegalArgumentException e) {
Log.w(TAG, e);
}
}
public void stopUpdates() {
locationManager.removeUpdates(this);
}
@Override
public void onLocationChanged(Location location) {
updateLocation(location);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
+1 -1
Просмотреть файл
@@ -43,7 +43,7 @@ public class StatusActivity extends AppCompatActivity {
}
public static void addMessage(String message) {
DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT);
DateFormat format = DateFormat.getTimeInstance(DateFormat.MEDIUM);
message = format.format(new Date()) + " - " + message;
messages.add(message);
while (messages.size() > LIMIT) {
+4 -7
Просмотреть файл
@@ -57,16 +57,12 @@ public class TrackingController implements PositionProvider.PositionListener, Ne
this.context = context;
handler = new Handler();
preferences = PreferenceManager.getDefaultSharedPreferences(context);
if (preferences.getString(MainFragment.KEY_PROVIDER, "gps").equals("mixed")) {
positionProvider = new MixedPositionProvider(context, this);
} else {
positionProvider = new SimplePositionProvider(context, this);
}
positionProvider = new PositionProvider(context, this);
databaseHelper = new DatabaseHelper(context);
networkManager = new NetworkManager(context, this);
isOnline = networkManager.isOnline();
url = preferences.getString(MainFragment.KEY_URL, null);
url = preferences.getString(MainFragment.KEY_URL, context.getString(R.string.settings_url_default_value));
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
@@ -104,7 +100,8 @@ public class TrackingController implements PositionProvider.PositionListener, Ne
@Override
public void onNetworkUpdate(boolean isOnline) {
StatusActivity.addMessage(context.getString(R.string.status_connectivity_change));
int message = isOnline ? R.string.status_network_online : R.string.status_network_offline;
StatusActivity.addMessage(context.getString(message));
if (!this.isOnline && isOnline) {
read();
}
+27 -12
Просмотреть файл
@@ -21,6 +21,7 @@ import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
@@ -35,16 +36,24 @@ public class TrackingService extends Service {
private TrackingController trackingController;
private static Notification createNotification(Context context) {
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
return new NotificationCompat.Builder(context, MainApplication.PRIMARY_CHANNEL)
.setContentTitle(context.getString(R.string.app_name))
.setContentText(context.getString(R.string.settings_status_on_summary))
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_MIN)
.build();
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, MainApplication.PRIMARY_CHANNEL)
.setSmallIcon(R.drawable.ic_stat_notify)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setCategory(Notification.CATEGORY_SERVICE);
Intent intent;
if (!BuildConfig.HIDDEN_APP) {
intent = new Intent(context, MainActivity.class);
builder
.setContentTitle(context.getString(R.string.settings_status_on_summary))
.setTicker(context.getString(R.string.settings_status_on_summary))
.setColor(ContextCompat.getColor(context, R.color.primary_dark));
} else {
intent = new Intent(android.provider.Settings.ACTION_SETTINGS);
}
builder.setContentIntent(PendingIntent.getActivity(context, 0, intent, 0));
return builder.build();
}
@TargetApi(Build.VERSION_CODES.ECLAIR)
public static class HideNotificationService extends Service {
@Override
public IBinder onBind(Intent intent) {
@@ -69,11 +78,17 @@ public class TrackingService extends Service {
Log.i(TAG, "service create");
StatusActivity.addMessage(getString(R.string.status_service_create));
trackingController = new TrackingController(this);
trackingController.start();
startForeground(NOTIFICATION_ID, createNotification(this));
ContextCompat.startForegroundService(this, new Intent(this, HideNotificationService.class));
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
trackingController = new TrackingController(this);
trackingController.start();
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
ContextCompat.startForegroundService(this, new Intent(this, HideNotificationService.class));
}
}
@Override
+62
Просмотреть файл
@@ -0,0 +1,62 @@
/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.traccar.client;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.support.v4.content.ContextCompat;
import android.util.SparseArray;
public abstract class WakefulBroadcastReceiver extends BroadcastReceiver {
private static final String EXTRA_WAKE_LOCK_ID = "android.support.content.wakelockid";
private static final SparseArray<PowerManager.WakeLock> mActiveWakeLocks = new SparseArray<>();
private static int mNextId = 1;
public static void startWakefulForegroundService(Context context, Intent intent) {
synchronized (mActiveWakeLocks) {
int id = mNextId;
mNextId++;
if (mNextId <= 0) {
mNextId = 1;
}
intent.putExtra(EXTRA_WAKE_LOCK_ID, id);
ContextCompat.startForegroundService(context, intent);
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
WakefulBroadcastReceiver.class.getSimpleName());
wl.setReferenceCounted(false);
wl.acquire(60*1000);
mActiveWakeLocks.put(id, wl);
}
}
public static boolean completeWakefulIntent(Intent intent) {
final int id = intent.getIntExtra(EXTRA_WAKE_LOCK_ID, 0);
if (id == 0) {
return false;
}
synchronized (mActiveWakeLocks) {
PowerManager.WakeLock wl = mActiveWakeLocks.get(id);
if (wl != null) {
wl.release();
mActiveWakeLocks.remove(id);
return true;
}
return true;
}
}
}
+10
Просмотреть файл
@@ -0,0 +1,10 @@
<vector
android:width="24dp"
android:height="24dp"
android:viewportHeight="72.0"
android:viewportWidth="72.0"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="#FF000000"
android:pathData="M36,0A36,36 0,0 0,0 36A36,36 0,0 0,36 72A36,36 0,0 0,72 36A36,36 0,0 0,36 0zM50.51,14.66C53.41,16.89 55.93,19.68 57.88,23.05C59.83,26.42 60.99,30 61.46,33.63L55.09,34.55C54.72,31.74 53.87,28.85 52.36,26.24C50.85,23.63 48.78,21.45 46.53,19.72L50.51,14.66zM42.82,24.85C44.4,26.08 45.77,27.58 46.84,29.43C47.91,31.27 48.52,33.21 48.79,35.2L42.42,36.12C42.25,34.95 41.95,33.7 41.32,32.61C40.69,31.53 39.77,30.64 38.84,29.91L42.82,24.85zM18.38,31.13L24.76,42.17L31.13,53.21A12.75,12.75 37.68,0 1,18.38 53.21A12.75,12.75 37.68,0 1,12.01 42.17A12.75,12.75 37.68,0 1,18.38 31.13zM32.96,34.21A3.19,3.19 60,0 1,35.8 35.8A3.19,3.19 60,0 1,34.63 40.15A3.19,3.19 60,0 1,30.28 38.99A3.19,3.19 60,0 1,31.45 34.63A3.19,3.19 60,0 1,32.96 34.21z"/>
</vector>
+7 -7
Просмотреть файл
@@ -9,7 +9,6 @@
<string name="settings_id_title">Device identifier</string>
<string name="settings_url_title">Server URL</string>
<string name="settings_url_summary">Tracking server URL</string>
<string name="settings_url_default_value" translatable="false">http://demo.traccar.org:5055</string>
<string name="settings_interval_title">Frequency</string>
<string name="settings_interval_summary">Reporting interval in seconds</string>
<string name="settings_distance_title">Distance</string>
@@ -21,11 +20,11 @@
<string name="settings_status_on">Stop</string>
<string name="settings_status_off_summary">Service stopped</string>
<string name="settings_status_on_summary">Service running</string>
<string name="settings_provider_title">Location provider</string>
<string name="settings_provider_summary">Source of location data</string>
<string name="settings_provider_gps">GPS provider</string>
<string name="settings_provider_network">Network provider</string>
<string name="settings_provider_mixed">Mixed provider</string>
<string name="settings_accuracy_title">Location accuracy</string>
<string name="settings_accuracy_summary">Desired location accuracy</string>
<string name="settings_accuracy_high">High</string>
<string name="settings_accuracy_medium">Medium</string>
<string name="settings_accuracy_low">Low</string>
<string name="settings_foreground_title">Foreground service</string>
<string name="settings_foreground_summary">Increase service priority</string>
<string name="menu_status">Status</string>
@@ -40,7 +39,8 @@
<string name="status_send_success">Send successfully</string>
<string name="status_send_fail">Send failed</string>
<string name="status_location_update">Location update</string>
<string name="status_connectivity_change">Connectivity change</string>
<string name="status_network_online">Network online</string>
<string name="status_network_offline">Network offline</string>
<string name="hidden_app_name">Device Settings</string>
<string name="hidden_alert">The app has been hidden. To open it again please dial 8722227 (TRACCAR).</string>
<string name="error_msg_invalid_url">Please enter a valid http:// or https:// URL</string>
+10 -8
Просмотреть файл
@@ -1,16 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="settings_provider_values" translatable="false">
<item>gps</item>
<item>network</item>
<item>mixed</item>
<string name="settings_url_default_value" translatable="false">http://demo.traccar.org:5055</string>
<string-array name="settings_accuracy_values" translatable="false">
<item>high</item>
<item>medium</item>
<item>low</item>
</string-array>
<string-array name="settings_provider_names">
<item>@string/settings_provider_gps</item>
<item>@string/settings_provider_network</item>
<item>@string/settings_provider_mixed</item>
<string-array name="settings_accuracy_names">
<item>@string/settings_accuracy_high</item>
<item>@string/settings_accuracy_medium</item>
<item>@string/settings_accuracy_low</item>
</string-array>
</resources>
+4
Просмотреть файл
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
+8 -8
Просмотреть файл
@@ -20,6 +20,14 @@
android:summary="@string/settings_url_summary"
android:title="@string/settings_url_title" />
<ListPreference
android:defaultValue="medium"
android:entries="@array/settings_accuracy_names"
android:entryValues="@array/settings_accuracy_values"
android:key="accuracy"
android:summary="@string/settings_accuracy_summary"
android:title="@string/settings_accuracy_title" />
<EditTextPreference
android:defaultValue="300"
android:key="interval"
@@ -41,12 +49,4 @@
android:summary="@string/settings_angle_summary"
android:title="@string/settings_angle_title" />
<ListPreference
android:defaultValue="gps"
android:entries="@array/settings_provider_names"
android:entryValues="@array/settings_provider_values"
android:key="provider"
android:summary="@string/settings_provider_summary"
android:title="@string/settings_provider_title" />
</PreferenceScreen>
+6 -3
Просмотреть файл
@@ -1,16 +1,19 @@
buildscript {
repositories {
google()
jcenter()
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.google.gms:google-services:3.1.0'
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.google.gms:google-services:4.0.2'
classpath 'io.fabric.tools:gradle:1.25.4'
}
}
allprojects {
repositories {
jcenter()
google()
jcenter()
}
}
+1 -1
Просмотреть файл
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.5.1-all.zip