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

...
12 Коммитов
Автор SHA1 Сообщение Дата
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
8 изменённых файлов: 124 добавлений и 119 удалений
+5 -6
Просмотреть файл
@@ -9,8 +9,8 @@ android {
buildConfigField "boolean", "HIDDEN_APP", "false" buildConfigField "boolean", "HIDDEN_APP", "false"
minSdkVersion 15 minSdkVersion 15
targetSdkVersion 28 targetSdkVersion 28
versionCode 48 versionCode 51
versionName '5.11' versionName '5.14'
} }
lintOptions { lintOptions {
@@ -35,12 +35,11 @@ android {
} }
dependencies { dependencies {
implementation 'com.android.support:design:28.0.0-rc01' implementation 'com.android.support:design:28.0.0-rc02'
implementation 'com.mapzen.android:lost:3.0.4'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:3.8' testImplementation 'org.robolectric:robolectric:3.8'
googleImplementation 'com.google.firebase:firebase-core:16.0.1' googleImplementation 'com.google.firebase:firebase-core:16.0.3'
googleImplementation 'com.crashlytics.sdk.android:crashlytics:2.9.4' googleImplementation 'com.crashlytics.sdk.android:crashlytics:2.9.5'
} }
if (getGradle().getStartParameter().getTaskRequests().toString().contains("Google")) { if (getGradle().getStartParameter().getTaskRequests().toString().contains("Google")) {
+4
Просмотреть файл
@@ -20,6 +20,10 @@
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
android:name=".MainApplication"> android:name=".MainApplication">
<meta-data
android:name="google_analytics_adid_collection_enabled"
android:value="false" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:launchMode="singleTask" /> android:launchMode="singleTask" />
+5
Просмотреть файл
@@ -90,6 +90,11 @@ public class DatabaseHelper extends SQLiteOpenHelper {
onCreate(db); 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) { public void insertPosition(Position position) {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put("deviceId", position.getDeviceId()); values.put("deviceId", position.getDeviceId());
-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;
}
}
+42 -37
Просмотреть файл
@@ -20,17 +20,18 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location; import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.BatteryManager; import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Looper;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.widget.Toast;
import com.mapzen.android.lost.api.LocationListener; public class PositionProvider implements LocationListener {
import com.mapzen.android.lost.api.LocationRequest;
import com.mapzen.android.lost.api.LocationServices;
import com.mapzen.android.lost.api.LostApiClient;
public class PositionProvider implements LostApiClient.ConnectionCallbacks, LocationListener {
private static final String TAG = PositionProvider.class.getSimpleName(); private static final String TAG = PositionProvider.class.getSimpleName();
@@ -44,7 +45,7 @@ public class PositionProvider implements LostApiClient.ConnectionCallbacks, Loca
private final Context context; private final Context context;
private SharedPreferences preferences; private SharedPreferences preferences;
private LostApiClient apiClient; private LocationManager locationManager;
private String deviceId; private String deviceId;
private long interval; private long interval;
@@ -53,12 +54,12 @@ public class PositionProvider implements LostApiClient.ConnectionCallbacks, Loca
private Location lastLocation; private Location lastLocation;
private boolean started;
public PositionProvider(Context context, PositionListener listener) { public PositionProvider(Context context, PositionListener listener) {
this.context = context; this.context = context;
this.listener = listener; this.listener = listener;
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
preferences = PreferenceManager.getDefaultSharedPreferences(context); preferences = PreferenceManager.getDefaultSharedPreferences(context);
deviceId = preferences.getString(MainFragment.KEY_DEVICE, "undefined"); deviceId = preferences.getString(MainFragment.KEY_DEVICE, "undefined");
@@ -67,41 +68,42 @@ public class PositionProvider implements LostApiClient.ConnectionCallbacks, Loca
angle = Integer.parseInt(preferences.getString(MainFragment.KEY_ANGLE, "0")); angle = Integer.parseInt(preferences.getString(MainFragment.KEY_ANGLE, "0"));
} }
@SuppressLint("MissingPermission")
public void startUpdates() { public void startUpdates() {
started = true; try {
apiClient = new LostApiClient.Builder(context).addConnectionCallbacks(this).build(); locationManager.requestLocationUpdates(
apiClient.connect(); distance > 0 || angle > 0 ? MINIMUM_INTERVAL : interval, 0,
getCriteria(preferences.getString(MainFragment.KEY_ACCURACY, "medium")),
this, Looper.myLooper());
} catch (RuntimeException e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
}
} }
private int getPriority(String accuracy) { public static Criteria getCriteria(String accuracy) {
Criteria criteria = new Criteria();
switch (accuracy) { switch (accuracy) {
case "high": case "high":
return LocationRequest.PRIORITY_HIGH_ACCURACY; criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);
criteria.setPowerRequirement(Criteria.POWER_HIGH);
break;
case "low": case "low":
return LocationRequest.PRIORITY_LOW_POWER; criteria.setHorizontalAccuracy(Criteria.ACCURACY_LOW);
criteria.setPowerRequirement(Criteria.POWER_LOW);
break;
default: default:
return LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY; criteria.setHorizontalAccuracy(Criteria.ACCURACY_MEDIUM);
} criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
} break;
@SuppressLint("MissingPermission")
@Override
public void onConnected() {
if (started) {
LocationRequest request = LocationRequest.create()
.setPriority(getPriority(preferences.getString(MainFragment.KEY_ACCURACY, "medium")))
.setInterval(distance > 0 || angle > 0 ? MINIMUM_INTERVAL : interval);
LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, request, this);
} else {
apiClient.disconnect();
} }
return criteria;
} }
@Override @Override
public void onLocationChanged(Location location) { public void onLocationChanged(Location location) {
if (location != null && (lastLocation == null if (location != null && (lastLocation == null
|| location.getTime() - lastLocation.getTime() >= interval || location.getTime() - lastLocation.getTime() >= interval
|| distance > 0 && DistanceCalculator.distance(location.getLatitude(), location.getLongitude(), lastLocation.getLatitude(), lastLocation.getLongitude()) >= distance || distance > 0 && location.distanceTo(lastLocation) >= distance
|| angle > 0 && Math.abs(location.getBearing() - lastLocation.getBearing()) >= angle)) { || angle > 0 && Math.abs(location.getBearing() - lastLocation.getBearing()) >= angle)) {
Log.i(TAG, "location new"); Log.i(TAG, "location new");
lastLocation = location; lastLocation = location;
@@ -112,16 +114,19 @@ public class PositionProvider implements LostApiClient.ConnectionCallbacks, Loca
} }
@Override @Override
public void onConnectionSuspended() { public void onStatusChanged(String provider, int status, Bundle extras) {
Log.i(TAG, "lost client suspended"); }
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
} }
public void stopUpdates() { public void stopUpdates() {
if (apiClient.isConnected()) { locationManager.removeUpdates(this);
LocationServices.FusedLocationApi.removeLocationUpdates(apiClient, this);
apiClient.disconnect();
}
started = false;
} }
public static double getBatteryLevel(Context context) { public static double getBatteryLevel(Context context) {
+62 -40
Просмотреть файл
@@ -15,10 +15,16 @@
*/ */
package org.traccar.client; package org.traccar.client;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location; import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.Looper;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.DrawableRes; import android.support.annotation.DrawableRes;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
@@ -32,10 +38,7 @@ import android.widget.ArrayAdapter;
import android.widget.ListView; import android.widget.ListView;
import android.widget.Toast; import android.widget.Toast;
import com.mapzen.android.lost.api.LocationServices; public class ShortcutActivity extends AppCompatActivity {
import com.mapzen.android.lost.api.LostApiClient;
public class ShortcutActivity extends AppCompatActivity implements LostApiClient.ConnectionCallbacks {
public static final String EXTRA_ACTION = "action"; public static final String EXTRA_ACTION = "action";
public static final String ACTION_START = "start"; public static final String ACTION_START = "start";
@@ -44,8 +47,6 @@ public class ShortcutActivity extends AppCompatActivity implements LostApiClient
private static final String ALARM_SOS = "sos"; private static final String ALARM_SOS = "sos";
private LostApiClient apiClient;
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@@ -102,47 +103,63 @@ public class ShortcutActivity extends AppCompatActivity implements LostApiClient
setResult(RESULT_OK, ShortcutManagerCompat.createShortcutResultIntent(this, shortcut)); setResult(RESULT_OK, ShortcutManagerCompat.createShortcutResultIntent(this, shortcut));
} }
@SuppressWarnings("MissingPermission")
private void sendAlarm() { private void sendAlarm() {
apiClient = new LostApiClient.Builder(this).addConnectionCallbacks(this).build(); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
apiClient.connect(); LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = PositionProvider.getCriteria(
preferences.getString(MainFragment.KEY_ACCURACY, "medium"));
try {
Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, true));
if (location != null) {
sendAlarmLocation(location);
} else {
locationManager.requestSingleUpdate(criteria, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
sendAlarmLocation(location);
}
@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();
}
} }
@SuppressWarnings("MissingPermission") private void sendAlarmLocation(Location location) {
@Override
public void onConnected() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
Location location = LocationServices.FusedLocationApi.getLastLocation(apiClient); Position position = new Position(
preferences.getString(MainFragment.KEY_DEVICE, null),
location, PositionProvider.getBatteryLevel(this));
if (location != null) { String request = ProtocolFormatter.formatRequest(
preferences.getString(MainFragment.KEY_URL, null), position, ALARM_SOS);
Position position = new Position( RequestManager.sendRequestAsync(request, new RequestManager.RequestHandler() {
preferences.getString(MainFragment.KEY_DEVICE, null), @Override
location, PositionProvider.getBatteryLevel(this)); public void onComplete(boolean success) {
if (success) {
String request = ProtocolFormatter.formatRequest( Toast.makeText(ShortcutActivity.this, R.string.status_send_success, Toast.LENGTH_SHORT).show();
preferences.getString(MainFragment.KEY_URL, null), position, ALARM_SOS); } else {
Toast.makeText(ShortcutActivity.this, R.string.status_send_fail, Toast.LENGTH_SHORT).show();
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();
}
} }
}); }
});
} else {
Toast.makeText(this, R.string.status_send_fail, Toast.LENGTH_SHORT).show();
}
apiClient.disconnect();
}
@Override
public void onConnectionSuspended() {
} }
private boolean executeAction(Intent intent) { private boolean executeAction(Intent intent) {
@@ -168,7 +185,12 @@ public class ShortcutActivity extends AppCompatActivity implements LostApiClient
Toast.makeText(this, R.string.status_service_destroy, Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.status_service_destroy, Toast.LENGTH_SHORT).show();
break; break;
case ACTION_SOS: 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; break;
} }
finish(); finish();
+1 -1
Просмотреть файл
@@ -43,7 +43,7 @@ public class StatusActivity extends AppCompatActivity {
} }
public static void addMessage(String message) { public static void addMessage(String message) {
DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT); DateFormat format = DateFormat.getTimeInstance(DateFormat.MEDIUM);
message = format.format(new Date()) + " - " + message; message = format.format(new Date()) + " - " + message;
messages.add(message); messages.add(message);
while (messages.size() > LIMIT) { while (messages.size() > LIMIT) {
+5 -2
Просмотреть файл
@@ -78,14 +78,17 @@ public class TrackingService extends Service {
Log.i(TAG, "service create"); Log.i(TAG, "service create");
StatusActivity.addMessage(getString(R.string.status_service_create)); StatusActivity.addMessage(getString(R.string.status_service_create));
startForeground(NOTIFICATION_ID, createNotification(this));
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED 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) { && ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
trackingController = new TrackingController(this); trackingController = new TrackingController(this);
trackingController.start(); trackingController.start();
} }
startForeground(NOTIFICATION_ID, createNotification(this)); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
ContextCompat.startForegroundService(this, new Intent(this, HideNotificationService.class)); ContextCompat.startForegroundService(this, new Intent(this, HideNotificationService.class));
}
} }
@Override @Override