diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 045c318..f7f4b0a 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -23,11 +23,8 @@
- Proveedor GPS
- Proveedor de red
-
-
- - gps
- - red
-
+ - Proveedor mixto
+
Estado
Acerca de…
@@ -44,7 +41,6 @@
Fallo en la conexión
Erro en el envío
Posición actualizada
- Estado proveedor cambiado
Preferencias actualizadas
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 01579e4..b6f2fb9 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -23,10 +23,7 @@
- GPS провайдер
- Сетевой провайдер
-
-
- - gps
- - network
+ - Смешанный провайдер
Состояние
@@ -44,7 +41,6 @@
Ошибка установки соединения
Ошибка отправки
Обновление местоположения
- Изменилось состояние провайдера
Обновление настроек
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 280a3d6..6e11689 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -23,12 +23,9 @@
- GPS provider
- Network provider
+ - Mixed provider
-
- - gps
- - network
-
-
+
Status
About
Clear
@@ -44,7 +41,6 @@
Connection failed
Send failed
Location update
- Provider status changed
Preference update
diff --git a/res/values/values.xml b/res/values/values.xml
new file mode 100644
index 0000000..6a7ddb1
--- /dev/null
+++ b/res/values/values.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ - gps
+ - network
+ - mixed
+
+
+
diff --git a/res/xml-v14/preferences.xml b/res/xml-v14/preferences.xml
index 5163775..bcb6d2f 100644
--- a/res/xml-v14/preferences.xml
+++ b/res/xml-v14/preferences.xml
@@ -1,52 +1,52 @@
-
+
-
-
-
+ android:title="@string/settings_address_title" />
-
-
-
+ android:title="@string/settings_port_title" />
-
+
+
-
+ android:key="provider"
+ android:summary="@string/settings_provider_summary"
+ android:title="@string/settings_provider_title" />
+
+ android:enabled="false"
+ android:key="debug"
+ android:summary="@string/settings_debug_summary"
+ android:title="@string/settings_debug_title" />
+ android:summaryOn="@string/settings_status_on_summary"
+ android:switchTextOff="@string/settings_status_off"
+ android:switchTextOn="@string/settings_status_on"
+ android:title="@string/settings_status_title" />
-
+
\ No newline at end of file
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index 366aaf2..6ebf83c 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -1,50 +1,50 @@
-
+
-
-
-
+ android:title="@string/settings_address_title" />
-
-
-
+ android:title="@string/settings_port_title" />
-
+
+
+ android:key="provider"
+ android:summary="@string/settings_provider_summary"
+ android:title="@string/settings_provider_title" />
+ android:enabled="false"
+ android:key="debug"
+ android:summary="@string/settings_debug_summary"
+ android:title="@string/settings_debug_title" />
+ android:summaryOn="@string/settings_status_on_summary"
+ android:title="@string/settings_status_title" />
diff --git a/src/org/traccar/client/ClientController.java b/src/org/traccar/client/ClientController.java
index 5c7c856..f6cba03 100644
--- a/src/org/traccar/client/ClientController.java
+++ b/src/org/traccar/client/ClientController.java
@@ -95,10 +95,10 @@ public class ClientController implements Connection.ConnectionHandler {
@Override
public void onConnected(boolean result) {
if (result) {
- StatusActivity.addMessage(context.getString((R.string.status_connection_success)));
+ StatusActivity.addMessage(context.getString(R.string.status_connection_success));
connection.send(loginMessage);
} else {
- StatusActivity.addMessage(context.getString((R.string.status_connection_fail)));
+ StatusActivity.addMessage(context.getString(R.string.status_connection_fail));
delayedReconnect();
}
}
@@ -110,7 +110,7 @@ public class ClientController implements Connection.ConnectionHandler {
connection.send(messageQueue.poll());
}
} else {
- StatusActivity.addMessage(context.getString((R.string.status_send_fail)));
+ StatusActivity.addMessage(context.getString(R.string.status_send_fail));
delayedReconnect();
}
}
diff --git a/src/org/traccar/client/PositionProvider.java b/src/org/traccar/client/PositionProvider.java
new file mode 100644
index 0000000..5bfb5e5
--- /dev/null
+++ b/src/org/traccar/client/PositionProvider.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2013 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 java.util.Date;
+
+import android.content.Context;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+import android.os.Bundle;
+import android.os.Handler;
+
+public class PositionProvider {
+
+ public static final String PROVIDER_MIXED = "mixed";
+ public static final long PERIOD_DELTA = 10 * 1000;
+ public static final long RETRY_PERIOD = 60 * 1000;
+
+ public interface PositionListener {
+ public void onPositionUpdate(Location location);
+ }
+
+ private final Handler handler;
+ private final LocationManager locationManager;
+ private final long period;
+ private final PositionListener listener;
+
+ private boolean useFine;
+ private boolean useCoarse;
+
+ public PositionProvider(Context context, String type, long period, PositionListener listener) {
+ handler = new Handler(context.getMainLooper());
+ locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+ this.period = period;
+ this.listener = listener;
+
+ // Determine providers
+ if (type.equals(PROVIDER_MIXED)) {
+ useFine = true;
+ useCoarse = true;
+ } else if (type.equals(LocationManager.GPS_PROVIDER)) {
+ useFine = true;
+ } else if (type.equals(LocationManager.NETWORK_PROVIDER)) {
+ useCoarse = true;
+ }
+ }
+
+ public void startUpdates() {
+ if (useFine) {
+ locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, period, 0, fineLocationListener);
+ }
+ if (useCoarse) {
+ locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, period, 0, coarseLocationListener);
+ }
+ handler.postDelayed(updateTask, period);
+ }
+
+ public void stopUpdates() {
+ handler.removeCallbacks(updateTask);
+ locationManager.removeUpdates(fineLocationListener);
+ locationManager.removeUpdates(coarseLocationListener);
+ }
+
+ private final Runnable updateTask = new Runnable() {
+
+ private boolean tryProvider(String provider) {
+ Location location = locationManager.getLastKnownLocation(provider);
+
+ if (location != null && new Date().getTime() - location.getTime() <= period + PERIOD_DELTA) {
+ listener.onPositionUpdate(location);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public void run() {
+ if (useFine && tryProvider(LocationManager.GPS_PROVIDER)) {
+ } else if (useCoarse && tryProvider(LocationManager.NETWORK_PROVIDER)) {
+ } else {
+ listener.onPositionUpdate(null);
+ }
+ handler.postDelayed(this, period);
+ }
+
+ };
+
+ private final InternalLocationListener fineLocationListener = new InternalLocationListener();
+ private final InternalLocationListener coarseLocationListener = new InternalLocationListener();
+
+ private class InternalLocationListener implements LocationListener {
+
+ @Override
+ public void onLocationChanged(Location location) {
+ }
+
+ @Override
+ public void onProviderDisabled(String provider) {
+ }
+
+ @Override
+ public void onProviderEnabled(String provider) {
+ }
+
+ @Override
+ public void onStatusChanged(final String provider, int status, Bundle extras) {
+ if (status == LocationProvider.TEMPORARILY_UNAVAILABLE || status == LocationProvider.OUT_OF_SERVICE) {
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ locationManager.removeUpdates(InternalLocationListener.this);
+ locationManager.requestLocationUpdates(provider, period, 0, InternalLocationListener.this);
+ }
+ }, RETRY_PERIOD);
+ }
+ }
+
+ }
+
+}
diff --git a/src/org/traccar/client/TraccarActivity.java b/src/org/traccar/client/TraccarActivity.java
index f8dd33a..3ffa547 100644
--- a/src/org/traccar/client/TraccarActivity.java
+++ b/src/org/traccar/client/TraccarActivity.java
@@ -23,6 +23,7 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
import android.telephony.TelephonyManager;
import android.view.Menu;
import android.view.MenuInflater;
@@ -110,6 +111,8 @@ public class TraccarActivity extends PreferenceActivity {
}
private void initPreferences() {
+ PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
+
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String id = telephonyManager.getDeviceId();
diff --git a/src/org/traccar/client/TraccarService.java b/src/org/traccar/client/TraccarService.java
index c94b433..deb2b8a 100644
--- a/src/org/traccar/client/TraccarService.java
+++ b/src/org/traccar/client/TraccarService.java
@@ -16,15 +16,10 @@
package org.traccar.client;
import android.app.Service;
-import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.location.LocationProvider;
-import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
@@ -44,7 +39,7 @@ public class TraccarService extends Service {
private SharedPreferences sharedPreferences;
private ClientController clientController;
- private LocationManager locationManager;
+ private PositionProvider positionProvider;
@Override
public void onCreate() {
@@ -70,8 +65,8 @@ public class TraccarService extends Service {
clientController = new ClientController(this, address, port, Protocol.createLoginMessage(id));
clientController.start();
- locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
- locationManager.requestLocationUpdates(provider, interval * 1000, 0, locationListener);
+ positionProvider = new PositionProvider(this, provider, interval * 1000, positionListener);
+ positionProvider.startUpdates();
sharedPreferences.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
@@ -89,35 +84,18 @@ public class TraccarService extends Service {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
- locationManager.removeUpdates(locationListener);
+ positionProvider.stopUpdates();
clientController.stop();
}
- private LocationListener locationListener = new LocationListener() {
+ private PositionProvider.PositionListener positionListener = new PositionProvider.PositionListener() {
@Override
- public void onLocationChanged(Location location) {
- StatusActivity.addMessage(getString(R.string.status_location_update));
- clientController.setNewLocation(Protocol.createLocationMessage(location));
- }
-
- @Override
- public void onProviderDisabled(String provider) {
- }
-
- @Override
- public void onProviderEnabled(String provider) {
- }
-
- @Override
- public void onStatusChanged(String provider, int status, Bundle extras) {
- StatusActivity.addMessage(getString(R.string.status_location_status));
-
- if (status == LocationProvider.TEMPORARILY_UNAVAILABLE ||
- status == LocationProvider.OUT_OF_SERVICE) {
- locationManager.removeUpdates(locationListener);
- locationManager.requestLocationUpdates(provider, interval * 1000, 0, locationListener);
+ public void onPositionUpdate(Location location) {
+ if (location != null) {
+ StatusActivity.addMessage(getString(R.string.status_location_update));
+ clientController.setNewLocation(Protocol.createLocationMessage(location));
}
}
@@ -130,22 +108,34 @@ public class TraccarService extends Service {
StatusActivity.addMessage(getString(R.string.status_preference_update));
try {
if (key.equals(TraccarActivity.KEY_ADDRESS)) {
+
address = sharedPreferences.getString(TraccarActivity.KEY_ADDRESS, null);
clientController.setNewServer(address, port);
+
} else if (key.equals(TraccarActivity.KEY_PORT)) {
+
port = Integer.valueOf(sharedPreferences.getString(TraccarActivity.KEY_PORT, null));
clientController.setNewServer(address, port);
+
} else if (key.equals(TraccarActivity.KEY_INTERVAL)) {
+
interval = Integer.valueOf(sharedPreferences.getString(TraccarActivity.KEY_INTERVAL, null));
- locationManager.removeUpdates(locationListener);
- locationManager.requestLocationUpdates(provider, interval * 1000, 0, locationListener);
+ positionProvider.stopUpdates();
+ positionProvider = new PositionProvider(TraccarService.this, provider, interval * 1000, positionListener);
+ positionProvider.startUpdates();
+
} else if (key.equals(TraccarActivity.KEY_ID)) {
+
id = sharedPreferences.getString(TraccarActivity.KEY_ID, null);
clientController.setNewLogin(Protocol.createLoginMessage(id));
+
} else if (key.equals(TraccarActivity.KEY_PROVIDER)) {
+
provider = sharedPreferences.getString(TraccarActivity.KEY_PROVIDER, null);
- locationManager.removeUpdates(locationListener);
- locationManager.requestLocationUpdates(provider, interval * 1000, 0, locationListener);
+ positionProvider.stopUpdates();
+ positionProvider = new PositionProvider(TraccarService.this, provider, interval * 1000, positionListener);
+ positionProvider.startUpdates();
+
}
} catch (Exception error) {
Log.w(LOG_TAG, error);