From 6e398d12fe7d4d859b0e9b4eaa2f46a60cb04988 Mon Sep 17 00:00:00 2001 From: BrianBlade Date: Tue, 13 Jun 2017 12:40:32 +0200 Subject: [PATCH] add ServerURL preference (replaces address, port, encryption) --- .../java/org/traccar/client/MainActivity.java | 81 ++++++++++++------- .../java/org/traccar/client/Patterns.java | 58 ------------- .../org/traccar/client/ProtocolFormatter.java | 26 +++--- .../org/traccar/client/ShortcutActivity.java | 5 +- .../traccar/client/TrackingController.java | 10 +-- app/src/main/res/values/strings.xml | 17 ++-- app/src/main/res/xml-v14/preferences.xml | 24 +----- app/src/main/res/xml/preferences.xml | 22 +---- .../traccar/client/ProtocolFormatterTest.java | 15 +++- 9 files changed, 97 insertions(+), 161 deletions(-) delete mode 100644 app/src/main/java/org/traccar/client/Patterns.java diff --git a/app/src/main/java/org/traccar/client/MainActivity.java b/app/src/main/java/org/traccar/client/MainActivity.java index 03f39f3..e07f50c 100644 --- a/app/src/main/java/org/traccar/client/MainActivity.java +++ b/app/src/main/java/org/traccar/client/MainActivity.java @@ -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(); + } + } + } } diff --git a/app/src/main/java/org/traccar/client/Patterns.java b/app/src/main/java/org/traccar/client/Patterns.java deleted file mode 100644 index 84f8857..0000000 --- a/app/src/main/java/org/traccar/client/Patterns.java +++ /dev/null @@ -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); - -} diff --git a/app/src/main/java/org/traccar/client/ProtocolFormatter.java b/app/src/main/java/org/traccar/client/ProtocolFormatter.java index 17e47a1..aecf737 100644 --- a/app/src/main/java/org/traccar/client/ProtocolFormatter.java +++ b/app/src/main/java/org/traccar/client/ProtocolFormatter.java @@ -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(); } } diff --git a/app/src/main/java/org/traccar/client/ShortcutActivity.java b/app/src/main/java/org/traccar/client/ShortcutActivity.java index 27fcb68..ac3ddd8 100644 --- a/app/src/main/java/org/traccar/client/ShortcutActivity.java +++ b/app/src/main/java/org/traccar/client/ShortcutActivity.java @@ -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 diff --git a/app/src/main/java/org/traccar/client/TrackingController.java b/app/src/main/java/org/traccar/client/TrackingController.java index 6e42ef8..9ffbf3d 100644 --- a/app/src/main/java/org/traccar/client/TrackingController.java +++ b/app/src/main/java/org/traccar/client/TrackingController.java @@ -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) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 790d8c0..f317354 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,10 +6,9 @@ Traccar - Stop Traccar - SOS Device identifier - Server address - Domain name or IP address - Server port - Tracking server TCP port + Server URL + Tracking server URL + http://demo.traccar.org Frequency Reporting interval in seconds Distance @@ -21,11 +20,6 @@ Stop Service stopped Service running - Encryption - Enable - Disable - Encryption disabled - Encryption enabled Location provider Source of location data GPS provider @@ -33,9 +27,7 @@ Mixed provider Foreground service Increase service priority - Invalid server address - Invalid server port - Invalid frequency value + Invalid server URL Status About Add shortcuts @@ -51,4 +43,5 @@ Connectivity change Device Settings The app has been hidden. To open it again please dial 8722227 (TRACCAR). + Please enter a valid http:// or https:// URL diff --git a/app/src/main/res/xml-v14/preferences.xml b/app/src/main/res/xml-v14/preferences.xml index a402b81..941eae5 100644 --- a/app/src/main/res/xml-v14/preferences.xml +++ b/app/src/main/res/xml-v14/preferences.xml @@ -15,26 +15,10 @@ android:title="@string/settings_id_title" /> - - - - + android:defaultValue="@string/settings_url_default_value" + android:key="url" + android:summary="@string/settings_url_summary" + android:title="@string/settings_url_title" /> - - - - + android:defaultValue="@string/settings_url_default_value" + android:key="url" + android:summary="@string/settings_url_summary" + android:title="@string/settings_url_title" />