add ServerURL preference (replaces address, port, encryption)
Этот коммит содержится в:
@@ -24,6 +24,7 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
@@ -35,7 +36,11 @@ import android.preference.TwoStatePreference;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.webkit.URLUtil;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
@@ -46,9 +51,7 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
|
||||
private static final String TAG = MainActivity.class.getSimpleName();
|
||||
|
||||
public static final String KEY_DEVICE = "id";
|
||||
public static final String KEY_ADDRESS = "address";
|
||||
public static final String KEY_PORT = "port";
|
||||
public static final String KEY_SECURE = "secure";
|
||||
public static final String KEY_URL = "url";
|
||||
public static final String KEY_INTERVAL = "interval";
|
||||
public static final String KEY_DISTANCE = "distance";
|
||||
public static final String KEY_ANGLE = "angle";
|
||||
@@ -65,12 +68,12 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (BuildConfig.HIDDEN_APP) {
|
||||
removeLauncherIcon();
|
||||
}
|
||||
|
||||
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
migratePreferencesIfNecessary(sharedPreferences);
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
initPreferences();
|
||||
|
||||
@@ -80,30 +83,13 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
|
||||
return newValue != null && !newValue.equals("");
|
||||
}
|
||||
});
|
||||
findPreference(KEY_ADDRESS).setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
findPreference(KEY_URL).setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
|
||||
return newValue != null && Patterns.DOMAIN_NAME.matcher((String) newValue).matches();
|
||||
} else {
|
||||
return newValue != null && !((String) newValue).isEmpty();
|
||||
}
|
||||
}
|
||||
});
|
||||
findPreference(KEY_PORT).setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (newValue != null) {
|
||||
try {
|
||||
int value = Integer.parseInt((String) newValue);
|
||||
return value > 0 && value <= 65536;
|
||||
} catch (NumberFormatException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return (newValue != null) && setServerURL(newValue.toString());
|
||||
}
|
||||
});
|
||||
|
||||
findPreference(KEY_INTERVAL).setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
@@ -194,9 +180,7 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
|
||||
|
||||
private void setPreferencesEnabled(boolean enabled) {
|
||||
findPreference(KEY_DEVICE).setEnabled(enabled);
|
||||
findPreference(KEY_ADDRESS).setEnabled(enabled);
|
||||
findPreference(KEY_PORT).setEnabled(enabled);
|
||||
findPreference(KEY_SECURE).setEnabled(enabled);
|
||||
findPreference(KEY_URL).setEnabled(enabled);
|
||||
findPreference(KEY_INTERVAL).setEnabled(enabled);
|
||||
findPreference(KEY_DISTANCE).setEnabled(enabled);
|
||||
findPreference(KEY_ANGLE).setEnabled(enabled);
|
||||
@@ -307,4 +291,47 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen
|
||||
}
|
||||
}
|
||||
|
||||
private boolean setServerURL(String userUrl) {
|
||||
EditTextPreference preference = (EditTextPreference) findPreference(KEY_URL);
|
||||
|
||||
if (userUrl == null || userUrl.trim().length() == 0) {
|
||||
preference.setText(getString(R.string.settings_url_default_value));
|
||||
preference.setSummary(R.string.settings_url_summary);
|
||||
findPreference(KEY_STATUS).setEnabled(true);
|
||||
return false;
|
||||
}
|
||||
if (URLUtil.isValidUrl(userUrl) && (URLUtil.isHttpUrl(userUrl) || URLUtil.isHttpsUrl(userUrl))) {
|
||||
preference.setSummary(R.string.settings_url_summary);
|
||||
findPreference(KEY_STATUS).setEnabled(true);
|
||||
} else {
|
||||
preference.setSummary(R.string.settings_invalid_url_summary);
|
||||
findPreference(KEY_STATUS).setEnabled(false);
|
||||
Toast.makeText(MainActivity.this, R.string.msg_invalid_url, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void migratePreferencesIfNecessary(SharedPreferences preferences) {
|
||||
String port = preferences.getString("port", null);
|
||||
if (port != null) {
|
||||
Log.d(TAG, "migratePreferencesIfNecessary: 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");
|
||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD) {
|
||||
editor.commit();
|
||||
} else {
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
* 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.regex.Pattern;
|
||||
|
||||
public class Patterns {
|
||||
|
||||
private static final String IP_ADDRESS_STRING =
|
||||
"((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
|
||||
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
|
||||
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
|
||||
+ "|[1-9][0-9]|[0-9]))";
|
||||
|
||||
private static final String UCS_CHAR = "[" +
|
||||
"\u00A0-\uD7FF" +
|
||||
"\uF900-\uFDCF" +
|
||||
"\uFDF0-\uFFEF" +
|
||||
"\uD800\uDC00-\uD83F\uDFFD" +
|
||||
"\uD840\uDC00-\uD87F\uDFFD" +
|
||||
"\uD880\uDC00-\uD8BF\uDFFD" +
|
||||
"\uD8C0\uDC00-\uD8FF\uDFFD" +
|
||||
"\uD900\uDC00-\uD93F\uDFFD" +
|
||||
"\uD940\uDC00-\uD97F\uDFFD" +
|
||||
"\uD980\uDC00-\uD9BF\uDFFD" +
|
||||
"\uD9C0\uDC00-\uD9FF\uDFFD" +
|
||||
"\uDA00\uDC00-\uDA3F\uDFFD" +
|
||||
"\uDA40\uDC00-\uDA7F\uDFFD" +
|
||||
"\uDA80\uDC00-\uDABF\uDFFD" +
|
||||
"\uDAC0\uDC00-\uDAFF\uDFFD" +
|
||||
"\uDB00\uDC00-\uDB3F\uDFFD" +
|
||||
"\uDB44\uDC00-\uDB7F\uDFFD" +
|
||||
"&&[^\u00A0[\u2000-\u200A]\u2028\u2029\u202F\u3000]]";
|
||||
|
||||
private static final String LABEL_CHAR = "a-zA-Z0-9" + UCS_CHAR;
|
||||
|
||||
private static final String IRI_LABEL =
|
||||
"[" + LABEL_CHAR + "](?:[" + LABEL_CHAR + "\\-]{0,61}[" + LABEL_CHAR + "]){0,1}";
|
||||
|
||||
private static final String RELAXED_DOMAIN_NAME =
|
||||
"(?:" + "(?:" + IRI_LABEL + "(?:\\.(?=\\S))" +"?)+" + "|" + IP_ADDRESS_STRING + ")";
|
||||
|
||||
public static final Pattern DOMAIN_NAME = Pattern.compile(RELAXED_DOMAIN_NAME);
|
||||
|
||||
}
|
||||
@@ -19,14 +19,12 @@ import android.net.Uri;
|
||||
|
||||
public class ProtocolFormatter {
|
||||
|
||||
public static String formatRequest(String address, int port, boolean secure, Position position) {
|
||||
return formatRequest(address, port, secure, position, null);
|
||||
public static String formatRequest(String url, Position position) {
|
||||
return formatRequest(url, position, null);
|
||||
}
|
||||
|
||||
public static String formatRequest(String address, int port, boolean secure, Position position, String alarm) {
|
||||
|
||||
Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(secure ? "https" : "http").encodedAuthority(address + ':' + port)
|
||||
public static String formatRequest(String url, Position position, String alarm) {
|
||||
Uri serverUrl = Uri.parse(url).buildUpon()
|
||||
.appendQueryParameter("id", position.getDeviceId())
|
||||
.appendQueryParameter("timestamp", String.valueOf(position.getTime().getTime() / 1000))
|
||||
.appendQueryParameter("lat", String.valueOf(position.getLatitude()))
|
||||
@@ -34,13 +32,19 @@ public class ProtocolFormatter {
|
||||
.appendQueryParameter("speed", String.valueOf(position.getSpeed()))
|
||||
.appendQueryParameter("bearing", String.valueOf(position.getCourse()))
|
||||
.appendQueryParameter("altitude", String.valueOf(position.getAltitude()))
|
||||
.appendQueryParameter("batt", String.valueOf(position.getBattery()));
|
||||
.appendQueryParameter("batt", String.valueOf(position.getBattery()))
|
||||
.build();
|
||||
|
||||
if (alarm != null) {
|
||||
builder.appendQueryParameter("alarm", alarm);
|
||||
if (alarm != null && alarm.trim().length() != 0) {
|
||||
serverUrl = serverUrl.buildUpon().appendQueryParameter("alarm", alarm).build();
|
||||
}
|
||||
|
||||
return builder.build().toString();
|
||||
int port = serverUrl.getPort();
|
||||
if (port < 0 || port > 65535) {
|
||||
port = 5055;
|
||||
String host = serverUrl.getHost();
|
||||
serverUrl = serverUrl.buildUpon().encodedAuthority(host + ":" + port).build();
|
||||
}
|
||||
return serverUrl.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -64,10 +64,7 @@ public class ShortcutActivity extends Activity {
|
||||
location, PositionProvider.getBatteryLevel(this));
|
||||
|
||||
String request = ProtocolFormatter.formatRequest(
|
||||
preferences.getString(MainActivity.KEY_ADDRESS, null),
|
||||
Integer.parseInt(preferences.getString(MainActivity.KEY_PORT, null)),
|
||||
preferences.getBoolean(MainActivity.KEY_SECURE, false),
|
||||
position, ALARM_SOS);
|
||||
preferences.getString(MainActivity.KEY_URL, null), position, ALARM_SOS);
|
||||
|
||||
RequestManager.sendRequestAsync(request, new RequestManager.RequestHandler() {
|
||||
@Override
|
||||
|
||||
@@ -36,9 +36,7 @@ public class TrackingController implements PositionProvider.PositionListener, Ne
|
||||
private Handler handler;
|
||||
private SharedPreferences preferences;
|
||||
|
||||
private String address;
|
||||
private int port;
|
||||
private boolean secure;
|
||||
private String url;
|
||||
|
||||
private PositionProvider positionProvider;
|
||||
private DatabaseHelper databaseHelper;
|
||||
@@ -73,9 +71,7 @@ public class TrackingController implements PositionProvider.PositionListener, Ne
|
||||
networkManager = new NetworkManager(context, this);
|
||||
isOnline = networkManager.isOnline();
|
||||
|
||||
address = preferences.getString(MainActivity.KEY_ADDRESS, null);
|
||||
port = Integer.parseInt(preferences.getString(MainActivity.KEY_PORT, null));
|
||||
secure = preferences.getBoolean(MainActivity.KEY_SECURE, false);
|
||||
url = preferences.getString(MainActivity.KEY_URL, null);
|
||||
|
||||
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
|
||||
@@ -199,7 +195,7 @@ public class TrackingController implements PositionProvider.PositionListener, Ne
|
||||
private void send(final Position position) {
|
||||
log("send", position);
|
||||
lock();
|
||||
String request = ProtocolFormatter.formatRequest(address, port, secure, position);
|
||||
String request = ProtocolFormatter.formatRequest(url, position);
|
||||
RequestManager.sendRequestAsync(request, new RequestManager.RequestHandler() {
|
||||
@Override
|
||||
public void onComplete(boolean success) {
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
<string name="shortcut_stop">Traccar - Stop</string>
|
||||
<string name="shortcut_sos">Traccar - SOS</string>
|
||||
<string name="settings_id_title">Device identifier</string>
|
||||
<string name="settings_address_title">Server address</string>
|
||||
<string name="settings_address_summary">Domain name or IP address</string>
|
||||
<string name="settings_port_title">Server port</string>
|
||||
<string name="settings_port_summary">Tracking server TCP port</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</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,6 @@
|
||||
<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_secure_title">Encryption</string>
|
||||
<string name="settings_secure_off">Enable</string>
|
||||
<string name="settings_secure_on">Disable</string>
|
||||
<string name="settings_secure_off_summary">Encryption disabled</string>
|
||||
<string name="settings_secure_on_summary">Encryption enabled</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>
|
||||
@@ -33,9 +27,7 @@
|
||||
<string name="settings_provider_mixed">Mixed provider</string>
|
||||
<string name="settings_foreground_title">Foreground service</string>
|
||||
<string name="settings_foreground_summary">Increase service priority</string>
|
||||
<string name="error_invalid_address">Invalid server address</string>
|
||||
<string name="error_invalid_port">Invalid server port</string>
|
||||
<string name="error_invalid_frequency">Invalid frequency value</string>
|
||||
<string name="settings_invalid_url_summary">Invalid server URL</string>
|
||||
<string name="menu_status">Status</string>
|
||||
<string name="menu_about">About</string>
|
||||
<string name="menu_shortcuts">Add shortcuts</string>
|
||||
@@ -51,4 +43,5 @@
|
||||
<string name="status_connectivity_change">Connectivity change</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="msg_invalid_url">Please enter a valid http:// or https:// URL</string>
|
||||
</resources>
|
||||
|
||||
@@ -15,26 +15,10 @@
|
||||
android:title="@string/settings_id_title" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="demo.traccar.org"
|
||||
android:key="address"
|
||||
android:summary="@string/settings_address_summary"
|
||||
android:title="@string/settings_address_title" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="5055"
|
||||
android:key="port"
|
||||
android:numeric="integer"
|
||||
android:summary="@string/settings_port_summary"
|
||||
android:title="@string/settings_port_title" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="secure"
|
||||
android:summaryOff="@string/settings_secure_off_summary"
|
||||
android:summaryOn="@string/settings_secure_on_summary"
|
||||
android:switchTextOff="@string/settings_secure_off"
|
||||
android:switchTextOn="@string/settings_secure_on"
|
||||
android:title="@string/settings_secure_title" />
|
||||
android:defaultValue="@string/settings_url_default_value"
|
||||
android:key="url"
|
||||
android:summary="@string/settings_url_summary"
|
||||
android:title="@string/settings_url_title" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="300"
|
||||
|
||||
@@ -13,24 +13,10 @@
|
||||
android:title="@string/settings_id_title" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="demo.traccar.org"
|
||||
android:key="address"
|
||||
android:summary="@string/settings_address_summary"
|
||||
android:title="@string/settings_address_title" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="5055"
|
||||
android:key="port"
|
||||
android:numeric="integer"
|
||||
android:summary="@string/settings_port_summary"
|
||||
android:title="@string/settings_port_title" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="secure"
|
||||
android:summaryOff="@string/settings_secure_off_summary"
|
||||
android:summaryOn="@string/settings_secure_on_summary"
|
||||
android:title="@string/settings_secure_title" />
|
||||
android:defaultValue="@string/settings_url_default_value"
|
||||
android:key="url"
|
||||
android:summary="@string/settings_url_summary"
|
||||
android:title="@string/settings_url_title" />
|
||||
|
||||
<EditTextPreference
|
||||
android:defaultValue="300"
|
||||
|
||||
@@ -22,10 +22,17 @@ public class ProtocolFormatterTest {
|
||||
Position position = new Position("123456789012345", new Location("gps"), 0);
|
||||
position.setTime(new Date(0));
|
||||
|
||||
String url = ProtocolFormatter.formatRequest("localhost", 5055, false, position);
|
||||
|
||||
assertEquals("http://localhost:5055?id=123456789012345×tamp=0&lat=0.0&lon=0.0&speed=0.0&bearing=0.0&altitude=0.0&batt=0.0", url);
|
||||
|
||||
String url = ProtocolFormatter.formatRequest("http://localhost:5055/path", position);
|
||||
assertEquals("http://localhost:5055/path?id=123456789012345×tamp=0&lat=0.0&lon=0.0&speed=0.0&bearing=0.0&altitude=0.0&batt=0.0", url);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatAlarmRequest() throws Exception {
|
||||
|
||||
Position position = new Position("123456789012345", new Location("gps"), 0);
|
||||
position.setTime(new Date(0));
|
||||
|
||||
String url = ProtocolFormatter.formatRequest("http://localhost:5055/path", position, "alert message");
|
||||
assertEquals("http://localhost:5055/path?id=123456789012345×tamp=0&lat=0.0&lon=0.0&speed=0.0&bearing=0.0&altitude=0.0&batt=0.0&alarm=alert%20message", url);
|
||||
}
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user