Completely rewrite application
Этот коммит содержится в:
@@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="TraccarActivity"
|
android:name="TraccarActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name">
|
||||||
android:windowSoftInputMode="stateHidden">
|
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
@@ -24,7 +23,17 @@
|
|||||||
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<service android:name=".TraccarService" />
|
<activity
|
||||||
|
android:name="StatusActivity"
|
||||||
|
android:label="@string/app_name">
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="AboutActivity"
|
||||||
|
android:label="@string/app_name">
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<service android:name="TraccarService" />
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent" >
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/logo"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_marginLeft="@dimen/about_margin"
|
||||||
|
android:layout_marginTop="@dimen/about_margin"
|
||||||
|
android:src="@drawable/ic_launcher"
|
||||||
|
android:contentDescription="@string/app_logo" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_margin="@dimen/about_margin"
|
||||||
|
android:layout_toRightOf="@+id/logo"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="@dimen/about_spacing"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="@dimen/about_spacing"
|
||||||
|
android:text="@string/about_description" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="@dimen/about_spacing"
|
||||||
|
android:text="@string/about_license" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="@dimen/about_spacing"
|
||||||
|
android:text="@string/about_web"
|
||||||
|
android:autoLink="web" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
<LinearLayout
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:padding="20sp"
|
|
||||||
>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Server address"
|
|
||||||
/>
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/edit_address"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:inputType="textUri"
|
|
||||||
/>
|
|
||||||
<View
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="10sp"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Server port"
|
|
||||||
/>
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/edit_port"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:inputType="number"
|
|
||||||
/>
|
|
||||||
<View
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="10sp"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Frequency in seconds"
|
|
||||||
/>
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/edit_period"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:inputType="number"
|
|
||||||
/>
|
|
||||||
<View
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="10sp"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Device identifier"
|
|
||||||
/>
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/edit_device"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:inputType="none"
|
|
||||||
android:editable="false"
|
|
||||||
android:focusable="false"
|
|
||||||
/>
|
|
||||||
<View
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="10sp"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Service status"
|
|
||||||
/>
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/edit_service"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:inputType="none"
|
|
||||||
android:editable="false"
|
|
||||||
android:focusable="false"
|
|
||||||
/>
|
|
||||||
<View
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="10sp"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Connection status"
|
|
||||||
/>
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/edit_connection"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:inputType="none"
|
|
||||||
android:editable="false"
|
|
||||||
android:focusable="false"
|
|
||||||
/>
|
|
||||||
<View
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="20sp"
|
|
||||||
/>
|
|
||||||
<ToggleButton
|
|
||||||
android:id="@+id/button"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textOn="ON"
|
|
||||||
android:textOff="OFF"
|
|
||||||
android:onClick="onButtonClick"
|
|
||||||
/>
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent">
|
||||||
|
|
||||||
|
<ListView
|
||||||
|
android:id="@android:id/list"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
@@ -1,7 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:id="@+id/about"
|
|
||||||
android:title="@string/about_option"
|
|
||||||
android:showAsAction="ifRoom" />
|
|
||||||
</menu>
|
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/status"
|
||||||
|
android:title="@string/menu_status"
|
||||||
|
android:showAsAction="always" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/about"
|
||||||
|
android:title="@string/menu_about"
|
||||||
|
android:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
</menu>
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/clear"
|
||||||
|
android:title="@string/menu_clear"
|
||||||
|
android:showAsAction="always" />
|
||||||
|
|
||||||
|
</menu>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<dimen name="about_margin">20dp</dimen>
|
||||||
|
<dimen name="about_spacing">15dp</dimen>
|
||||||
|
</resources>
|
||||||
@@ -1,8 +1,39 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<string name="app_name">Traccar Client</string>
|
<string name="app_name">Traccar Client</string>
|
||||||
<string name="error_input">Invalid input parameters.</string>
|
<string name="app_logo">Traccar</string>
|
||||||
<string name="about_option">About</string>
|
|
||||||
<string name="about_text">Android software GPS tracker. For more information visit:\n\nhttp://www.traccar.org</string>
|
<string name="settings_id_title">Device identifier</string>
|
||||||
<string name="about_close">Close</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_interval_title">Frequency</string>
|
||||||
|
<string name="settings_interval_summary">Messages interval in seconds</string>
|
||||||
|
<string name="settings_debug_title">Debug mode</string>
|
||||||
|
<string name="settings_debug_summary">Additional status messages</string>
|
||||||
|
<string name="settings_status_title">Service status</string>
|
||||||
|
<string name="settings_status_off">Start</string>
|
||||||
|
<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="menu_status">Status</string>
|
||||||
|
<string name="menu_about">About</string>
|
||||||
|
<string name="menu_clear">Clear</string>
|
||||||
|
|
||||||
|
<string name="about_description">Real time GPS tracker for Android devices. Compatible with Traccar Server and other tracking systems.</string>
|
||||||
|
<string name="about_license">This application is free and open source, source code is licensed under Apache License Version 2.0 and available on GitHub.</string>
|
||||||
|
<string name="about_web">For more information visit\nwww.traccar.org/client</string>
|
||||||
|
|
||||||
|
<string name="status_service_create">Service created</string>
|
||||||
|
<string name="status_service_start">Service started</string>
|
||||||
|
<string name="status_service_destroy">Service destroyed</string>
|
||||||
|
<string name="status_connection_success">Connection succeeded</string>
|
||||||
|
<string name="status_connection_fail">Connection failed</string>
|
||||||
|
<string name="status_send_fail">Send failed</string>
|
||||||
|
<string name="status_location_update">Location update</string>
|
||||||
|
<string name="status_preference_update">Preference update</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="id"
|
||||||
|
android:title="@string/settings_id_title"
|
||||||
|
android:enabled="false" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="address"
|
||||||
|
android:title="@string/settings_address_title"
|
||||||
|
android:summary="@string/settings_address_summary"
|
||||||
|
android:defaultValue="193.193.165.166" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="port"
|
||||||
|
android:title="@string/settings_port_title"
|
||||||
|
android:summary="@string/settings_port_summary"
|
||||||
|
android:numeric="integer"
|
||||||
|
android:defaultValue="20100" />
|
||||||
|
|
||||||
|
<EditTextPreference
|
||||||
|
android:key="interval"
|
||||||
|
android:title="@string/settings_interval_title"
|
||||||
|
android:summary="@string/settings_interval_summary"
|
||||||
|
android:numeric="integer"
|
||||||
|
android:defaultValue="60" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="debug"
|
||||||
|
android:title="@string/settings_debug_title"
|
||||||
|
android:summary="@string/settings_debug_summary"
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:enabled="false" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="status"
|
||||||
|
android:title="@string/settings_status_title"
|
||||||
|
android:summaryOff="@string/settings_status_off_summary"
|
||||||
|
android:summaryOn="@string/settings_status_on_summary"
|
||||||
|
android:switchTextOff="@string/settings_status_off"
|
||||||
|
android:switchTextOn="@string/settings_status_on"
|
||||||
|
android:defaultValue="false" />
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 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.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
public class AboutActivity extends Activity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.about);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,139 +15,119 @@
|
|||||||
*/
|
*/
|
||||||
package org.traccar.client;
|
package org.traccar.client;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.net.SocketAddress;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.os.AsyncTask;
|
||||||
import android.content.Intent;
|
import android.util.Log;
|
||||||
import android.os.Handler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connection with autoreconnect
|
* Asynchronous connection
|
||||||
|
*
|
||||||
|
* All methods should be called from UI thread only.
|
||||||
*/
|
*/
|
||||||
public class Connection {
|
public class Connection implements Closeable {
|
||||||
|
|
||||||
private String address;
|
public static final String LOG_TAG = "Traccar.Connection";
|
||||||
private int port;
|
public static final int SOCKET_TIMEOUT = 10 * 1000;
|
||||||
|
|
||||||
private String connectMessage;
|
/**
|
||||||
|
* Callback interface
|
||||||
|
*/
|
||||||
|
public interface ConnectionHandler {
|
||||||
|
void onConnected(boolean result);
|
||||||
|
void onSent(boolean result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConnectionHandler handler;
|
||||||
|
|
||||||
private Socket socket;
|
private Socket socket;
|
||||||
private OutputStream socketStream;
|
private OutputStream socketStream;
|
||||||
|
|
||||||
private String status;
|
public Connection(ConnectionHandler handler) {
|
||||||
|
this.handler = handler;
|
||||||
private Context context;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize connection parameters
|
|
||||||
*/
|
|
||||||
public Connection(String address, int port, String message) {
|
|
||||||
this.address = address;
|
|
||||||
this.port = port;
|
|
||||||
connectMessage = message;
|
|
||||||
setStatus(Traccar.STATUS_DISCONNECTED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void connect(String address, int port) {
|
||||||
* Get address
|
|
||||||
*/
|
|
||||||
public String getAddress() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
new AsyncTask<SocketAddress, Void, Boolean>() {
|
||||||
* Get port
|
|
||||||
*/
|
|
||||||
public int getPort() {
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Set context
|
protected Boolean doInBackground(SocketAddress... params) {
|
||||||
*/
|
try {
|
||||||
public void setContext(Context context) {
|
socket = new Socket();
|
||||||
this.context = context;
|
socket.connect(params[0]);
|
||||||
}
|
socket.setSoTimeout(SOCKET_TIMEOUT);
|
||||||
|
socketStream = socket.getOutputStream();
|
||||||
/**
|
handler.onConnected(true);
|
||||||
* Set connection status
|
} catch (Exception e) {
|
||||||
*/
|
close();
|
||||||
private void setStatus(String status) {
|
return false;
|
||||||
if (!status.equals(this.status)) {
|
}
|
||||||
this.status = status;
|
return true;
|
||||||
if (context != null) {
|
|
||||||
Intent intent = new Intent(Traccar.MSG_CONNECTION_STATUS);
|
|
||||||
intent.putExtra(Traccar.EXTRA_STATUS, status);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
protected void onCancelled(Boolean result) {
|
||||||
|
handler.onConnected(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
handler.onConnected(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}.execute(InetSocketAddress.createUnresolved(address, port));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get connection status
|
|
||||||
*/
|
|
||||||
public String getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Establish connection
|
|
||||||
*/
|
|
||||||
public void connect() {
|
|
||||||
try {
|
|
||||||
socket = new Socket(address, port);
|
|
||||||
socket.setSoTimeout(Traccar.SOCKET_TIMEOUT);
|
|
||||||
socketStream = socket.getOutputStream();
|
|
||||||
setStatus(Traccar.STATUS_CONNECTED);
|
|
||||||
send(connectMessage);
|
|
||||||
} catch (Exception e) {
|
|
||||||
reconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send message
|
|
||||||
*/
|
|
||||||
public void send(String message) {
|
public void send(String message) {
|
||||||
|
|
||||||
|
new AsyncTask<String, Void, Boolean>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean doInBackground(String... params) {
|
||||||
|
try {
|
||||||
|
socketStream.write(params[0].getBytes());
|
||||||
|
socketStream.flush();
|
||||||
|
} catch (Exception e) {
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCancelled(Boolean result) {
|
||||||
|
handler.onSent(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
handler.onSent(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}.execute(message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
try {
|
try {
|
||||||
if (socketStream != null) {
|
if (socketStream != null) {
|
||||||
socketStream.write(message.getBytes());
|
socketStream.close();
|
||||||
socketStream.flush();
|
socketStream = null;
|
||||||
|
}
|
||||||
|
if (socket != null) {
|
||||||
|
socket.close();
|
||||||
|
socket = null;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
reconnect();
|
Log.e(LOG_TAG, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Close connection
|
|
||||||
*/
|
|
||||||
public void close() {
|
|
||||||
handler.removeCallbacks(task);
|
|
||||||
if (socket != null) {
|
|
||||||
try {
|
|
||||||
socket.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
socket = null;
|
|
||||||
}
|
|
||||||
socketStream = null;
|
|
||||||
setStatus(Traccar.STATUS_DISCONNECTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reconnect() {
|
|
||||||
close();
|
|
||||||
handler.postDelayed(task, Traccar.RECONNECT_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Handler handler = new Handler();
|
|
||||||
private ReconnectTask task = new ReconnectTask();
|
|
||||||
|
|
||||||
class ReconnectTask implements Runnable {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
connect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class Protocol {
|
|||||||
/**
|
/**
|
||||||
* Format device id message
|
* Format device id message
|
||||||
*/
|
*/
|
||||||
public static String createId(String id) {
|
public static String createLoginMessage(String id) {
|
||||||
StringBuilder s = new StringBuilder("$PGID,");
|
StringBuilder s = new StringBuilder("$PGID,");
|
||||||
Formatter f = new Formatter(s, Locale.ENGLISH);
|
Formatter f = new Formatter(s, Locale.ENGLISH);
|
||||||
|
|
||||||
@@ -47,9 +47,9 @@ public class Protocol {
|
|||||||
/**
|
/**
|
||||||
* Format location message
|
* Format location message
|
||||||
*/
|
*/
|
||||||
public static String createNmea(Location l) {
|
public static String createLocationMessage(Location l) {
|
||||||
StringBuilder s = new StringBuilder("$GPRMC,");
|
StringBuilder s = new StringBuilder("$GPRMC,");
|
||||||
Formatter f = new Formatter(s, Locale.ENGLISH); // Should use DecimalFormat instead
|
Formatter f = new Formatter(s, Locale.ENGLISH);
|
||||||
|
|
||||||
f.format("%1$tH%1$tM%1$tS.%1$tL,A,", l.getTime());
|
f.format("%1$tH%1$tM%1$tS.%1$tL,A,", l.getTime());
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 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.text.DateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import android.app.ListActivity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
|
||||||
|
public class StatusActivity extends ListActivity {
|
||||||
|
|
||||||
|
private static final List<String> messages = new LinkedList<String>();
|
||||||
|
private static final Set<ArrayAdapter<String>> adapters = new HashSet<ArrayAdapter<String>>();
|
||||||
|
|
||||||
|
private static void notifyAdapters() {
|
||||||
|
for (ArrayAdapter<String> adapter : adapters) {
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addMessage(String message) {
|
||||||
|
DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT);
|
||||||
|
message = format.format(new Date()) + " - " + message;
|
||||||
|
messages.add(message);
|
||||||
|
notifyAdapters();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearMessages() {
|
||||||
|
messages.clear();
|
||||||
|
notifyAdapters();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayAdapter<String> adapter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.status);
|
||||||
|
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, messages);
|
||||||
|
setListAdapter(adapter);
|
||||||
|
adapters.add(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
adapters.remove(adapter);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.status, menu);
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
if (item.getItemId() == R.id.clear) {
|
||||||
|
clearMessages();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,209 +15,106 @@
|
|||||||
*/
|
*/
|
||||||
package org.traccar.client;
|
package org.traccar.client;
|
||||||
|
|
||||||
import java.util.*;
|
import android.app.ActivityManager;
|
||||||
import android.app.*;
|
import android.app.ActivityManager.RunningServiceInfo;
|
||||||
import android.content.*;
|
import android.content.Context;
|
||||||
import android.os.*;
|
import android.content.Intent;
|
||||||
import android.text.*;
|
import android.content.SharedPreferences;
|
||||||
import android.text.method.*;
|
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||||
import android.text.util.*;
|
import android.os.Bundle;
|
||||||
import android.view.*;
|
import android.preference.PreferenceActivity;
|
||||||
import android.widget.*;
|
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.view.Menu;
|
||||||
/**
|
import android.view.MenuInflater;
|
||||||
* Global parameters
|
import android.view.MenuItem;
|
||||||
*/
|
|
||||||
class Traccar {
|
|
||||||
public static final String EXTRA_ADDRESS = "address";
|
|
||||||
public static final String EXTRA_PORT = "port";
|
|
||||||
public static final String EXTRA_PERIOD = "period";
|
|
||||||
public static final String EXTRA_STATUS = "status";
|
|
||||||
|
|
||||||
public static final String DEFAULT_ADDRESS = "193.193.165.166";
|
|
||||||
public static final String DEFAULT_PORT = "20100";
|
|
||||||
public static final String DEFAULT_PERIOD = "60";
|
|
||||||
|
|
||||||
public static final String TRACCAR_SETTINGS = "traccar_settings";
|
|
||||||
|
|
||||||
public static final long RECONNECT_DELAY = 10 * 1000;
|
|
||||||
public static final int SOCKET_TIMEOUT = 2000;
|
|
||||||
|
|
||||||
public static final String MSG_UPDATE = "org.traccar.client.MSG_UPDATE";
|
|
||||||
public static final String MSG_SERVICE_CONFIG = "org.traccar.client.MSG_SERVICE_CONFIG";
|
|
||||||
public static final String MSG_SERVICE_STATUS = "org.traccar.client.SERVICE_STATUS";
|
|
||||||
public static final String MSG_CONNECTION_STATUS = "org.traccar.client.CONNECTION_STATUS";
|
|
||||||
|
|
||||||
public static final String STATUS_STOPPED = "Stopped";
|
|
||||||
public static final String STATUS_RUNNING = "Running";
|
|
||||||
|
|
||||||
public static final String STATUS_CONNECTED = "Connected";
|
|
||||||
public static final String STATUS_DISCONNECTED = "Disconnected";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main user interface
|
* Main user interface
|
||||||
*/
|
*/
|
||||||
public class TraccarActivity extends Activity {
|
@SuppressWarnings("deprecation")
|
||||||
|
public class TraccarActivity extends PreferenceActivity {
|
||||||
|
|
||||||
private EditText editAddress;
|
public static final String KEY_ID = "id";
|
||||||
private EditText editPort;
|
public static final String KEY_ADDRESS = "address";
|
||||||
private EditText editPeriod;
|
public static final String KEY_PORT = "port";
|
||||||
private EditText editDevice;
|
public static final String KEY_INTERVAL = "interval";
|
||||||
private EditText editService;
|
public static final String KEY_DEBUG = "debug";
|
||||||
private EditText editConnection;
|
public static final String KEY_STATUS = "status";
|
||||||
private ToggleButton button;
|
|
||||||
|
|
||||||
public boolean isServiceRunning() {
|
@Override
|
||||||
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
|
super.onCreate(savedInstanceState);
|
||||||
for (ActivityManager.RunningServiceInfo runningServiceInfo : services) {
|
addPreferencesFromResource(R.xml.preferences);
|
||||||
if (runningServiceInfo.service.getClassName().equals(TraccarService.class.getName())){
|
initPreferences();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(
|
||||||
|
preferenceChangeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(
|
||||||
|
preferenceChangeListener);
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
OnSharedPreferenceChangeListener preferenceChangeListener = new OnSharedPreferenceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||||
|
if (key.equals(KEY_STATUS)) {
|
||||||
|
if (sharedPreferences.getBoolean(KEY_STATUS, false)) {
|
||||||
|
startService(new Intent(TraccarActivity.this, TraccarService.class));
|
||||||
|
} else {
|
||||||
|
stopService(new Intent(TraccarActivity.this, TraccarService.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
MenuInflater inflater = getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.main, menu);
|
||||||
|
return super.onCreateOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
if (item.getItemId() == R.id.status) {
|
||||||
|
startActivity(new Intent(this, StatusActivity.class));
|
||||||
|
return true;
|
||||||
|
} else if (item.getItemId() == R.id.about) {
|
||||||
|
startActivity(new Intent(this, AboutActivity.class));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isServiceRunning() {
|
||||||
|
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
|
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
|
||||||
|
if (TraccarService.class.getName().equals(service.service.getClassName())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void initPreferences() {
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.main);
|
|
||||||
|
|
||||||
// DO SOMETHING WITH IT
|
|
||||||
try {
|
|
||||||
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
|
|
||||||
StrictMode.setThreadPolicy(policy);
|
|
||||||
} catch(Throwable e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind elements
|
|
||||||
editAddress = (EditText) findViewById(R.id.edit_address);
|
|
||||||
editPort = (EditText) findViewById(R.id.edit_port);
|
|
||||||
editPeriod = (EditText) findViewById(R.id.edit_period);
|
|
||||||
editDevice = (EditText) findViewById(R.id.edit_device);
|
|
||||||
editService = (EditText) findViewById(R.id.edit_service);
|
|
||||||
editConnection = (EditText) findViewById(R.id.edit_connection);
|
|
||||||
button = (ToggleButton) findViewById(R.id.button);
|
|
||||||
|
|
||||||
// Set device identifier
|
|
||||||
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
|
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
editDevice.setText(telephonyManager.getDeviceId());
|
String id = telephonyManager.getDeviceId();
|
||||||
|
|
||||||
editService.setText(Traccar.STATUS_STOPPED);
|
SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
|
||||||
editConnection.setText(Traccar.STATUS_DISCONNECTED);
|
|
||||||
button.setChecked(isServiceRunning());
|
sharedPreferences.edit().putString(KEY_ID, id).commit();
|
||||||
|
findPreference(KEY_ID).setSummary(id);
|
||||||
|
|
||||||
|
sharedPreferences.edit().putBoolean(KEY_STATUS, isServiceRunning()).commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
//super.onCreateOptionsMenu(menu);
|
|
||||||
MenuInflater inflater = getMenuInflater();
|
|
||||||
inflater.inflate(R.menu.main, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
if(item.getItemId() == R.id.about){
|
|
||||||
showAboutDialog();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showAboutDialog() {
|
|
||||||
TextView message = new TextView(this);
|
|
||||||
SpannableString str = new SpannableString(getString(R.string.about_text));
|
|
||||||
Linkify.addLinks(str, Linkify.WEB_URLS);
|
|
||||||
message.setText(str);
|
|
||||||
message.setMovementMethod(LinkMovementMethod.getInstance());
|
|
||||||
int padding = (int) (10 * getResources().getDisplayMetrics().scaledDensity);
|
|
||||||
message.setPadding(padding, padding, padding, padding);
|
|
||||||
|
|
||||||
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
|
|
||||||
dialog.setTitle(R.string.about_option);
|
|
||||||
dialog.setView(message);
|
|
||||||
dialog.setPositiveButton(R.string.about_close, null);
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private BroadcastReceiver serviceConfigReceiver = new BroadcastReceiver() {
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
editAddress.setText(intent.getStringExtra(Traccar.EXTRA_ADDRESS));
|
|
||||||
editPort.setText(String.valueOf(intent.getIntExtra(Traccar.EXTRA_PORT, 0)));
|
|
||||||
editPeriod.setText(String.valueOf(intent.getIntExtra(Traccar.EXTRA_PERIOD, 0)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private BroadcastReceiver serviceStatusReceiver = new BroadcastReceiver() {
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
editService.setText(intent.getStringExtra(Traccar.EXTRA_STATUS));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private BroadcastReceiver connectionStatusReceiver = new BroadcastReceiver() {
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
editConnection.setText(intent.getStringExtra(Traccar.EXTRA_STATUS));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
loadSettings();
|
|
||||||
|
|
||||||
// Register receivers
|
|
||||||
registerReceiver(serviceConfigReceiver, new IntentFilter(Traccar.MSG_SERVICE_CONFIG));
|
|
||||||
registerReceiver(serviceStatusReceiver, new IntentFilter(Traccar.MSG_SERVICE_STATUS));
|
|
||||||
registerReceiver(connectionStatusReceiver, new IntentFilter(Traccar.MSG_CONNECTION_STATUS));
|
|
||||||
|
|
||||||
// Request update
|
|
||||||
sendBroadcast(new Intent(Traccar.MSG_UPDATE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
saveSettings();
|
|
||||||
|
|
||||||
// Unregister receivers
|
|
||||||
unregisterReceiver(serviceConfigReceiver);
|
|
||||||
unregisterReceiver(serviceStatusReceiver);
|
|
||||||
unregisterReceiver(connectionStatusReceiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onButtonClick(View v) {
|
|
||||||
if (button.isChecked()) {
|
|
||||||
try {
|
|
||||||
Intent serviceIntent = new Intent(this, TraccarService.class);
|
|
||||||
serviceIntent.putExtra(Traccar.EXTRA_ADDRESS, editAddress.getText().toString());
|
|
||||||
serviceIntent.putExtra(Traccar.EXTRA_PORT, Integer.parseInt(editPort.getText().toString()));
|
|
||||||
serviceIntent.putExtra(Traccar.EXTRA_PERIOD, Integer.parseInt(editPeriod.getText().toString()));
|
|
||||||
startService(serviceIntent);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
Toast.makeText(this, R.string.error_input, Toast.LENGTH_SHORT).show();
|
|
||||||
button.setChecked(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stopService(new Intent(this, TraccarService.class));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveSettings() {
|
|
||||||
SharedPreferences settings = getSharedPreferences(Traccar.TRACCAR_SETTINGS, 0);
|
|
||||||
SharedPreferences.Editor editor = settings.edit();
|
|
||||||
editor.putString(Traccar.EXTRA_ADDRESS, editAddress.getText().toString());
|
|
||||||
editor.putString(Traccar.EXTRA_PORT, editPort.getText().toString());
|
|
||||||
editor.putString(Traccar.EXTRA_PERIOD, editPeriod.getText().toString());
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadSettings() {
|
|
||||||
SharedPreferences settings = getSharedPreferences(Traccar.TRACCAR_SETTINGS, 0);
|
|
||||||
editAddress.setText(settings.getString(Traccar.EXTRA_ADDRESS, Traccar.DEFAULT_ADDRESS));
|
|
||||||
editPort.setText(settings.getString(Traccar.EXTRA_PORT, Traccar.DEFAULT_PORT));
|
|
||||||
editPeriod.setText(settings.getString(Traccar.EXTRA_PERIOD, Traccar.DEFAULT_PERIOD));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,133 +16,193 @@
|
|||||||
package org.traccar.client;
|
package org.traccar.client;
|
||||||
|
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.location.LocationListener;
|
import android.location.LocationListener;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.telephony.TelephonyManager;
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Background service
|
* Background service
|
||||||
*/
|
*/
|
||||||
public class TraccarService extends Service implements LocationListener {
|
public class TraccarService extends Service {
|
||||||
|
|
||||||
private int period;
|
public static final long RECONNECT_DELAY = 10 * 1000;
|
||||||
private String deviceId;
|
|
||||||
|
private String id;
|
||||||
|
private String address;
|
||||||
|
private int port;
|
||||||
|
private int interval;
|
||||||
|
|
||||||
|
private Handler handler;
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
private LocationManager locationManager;
|
LocationManager locationManager;
|
||||||
|
|
||||||
/*
|
private void statusMessage(int message) {
|
||||||
* Location methods
|
StatusActivity.addMessage(getString(message));
|
||||||
*/
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLocationChanged(Location location) {
|
|
||||||
connection.send(Protocol.createNmea(location));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onProviderDisabled(String provider) {
|
public void onCreate() {
|
||||||
|
statusMessage(R.string.status_service_create);
|
||||||
|
|
||||||
|
handler = new Handler();
|
||||||
|
connection = new Connection(connectionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onProviderEnabled(String provider) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStatusChanged(String provider, int status, Bundle extras) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Status methods
|
|
||||||
*/
|
|
||||||
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
private void setStatus(String status) {
|
|
||||||
if (!status.equals(this.status)) {
|
|
||||||
this.status = status;
|
|
||||||
Intent intent = new Intent(Traccar.MSG_SERVICE_STATUS);
|
|
||||||
intent.putExtra(Traccar.EXTRA_STATUS, status);
|
|
||||||
sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private BroadcastReceiver updateReceiver = new BroadcastReceiver() {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
// Send config
|
|
||||||
intent = new Intent(Traccar.MSG_SERVICE_CONFIG);
|
|
||||||
intent.putExtra(Traccar.EXTRA_ADDRESS, connection.getAddress());
|
|
||||||
intent.putExtra(Traccar.EXTRA_PORT, connection.getPort());
|
|
||||||
intent.putExtra(Traccar.EXTRA_PERIOD, period);
|
|
||||||
sendBroadcast(intent);
|
|
||||||
|
|
||||||
// Send service status
|
|
||||||
intent = new Intent(Traccar.MSG_SERVICE_STATUS);
|
|
||||||
intent.putExtra(Traccar.EXTRA_STATUS, status);
|
|
||||||
sendBroadcast(intent);
|
|
||||||
|
|
||||||
// Send connection status
|
|
||||||
intent = new Intent(Traccar.MSG_CONNECTION_STATUS);
|
|
||||||
intent.putExtra(Traccar.EXTRA_STATUS, connection.getStatus());
|
|
||||||
sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Service methods
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
// Read device id
|
statusMessage(R.string.status_service_start);
|
||||||
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
|
|
||||||
deviceId = telephonyManager.getDeviceId();
|
|
||||||
|
|
||||||
// Create connection
|
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
connection = new Connection(
|
sharedPreferences.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
|
||||||
intent.getStringExtra(Traccar.EXTRA_ADDRESS),
|
updateServerPreferences(sharedPreferences);
|
||||||
intent.getIntExtra(Traccar.EXTRA_PORT, 0),
|
updateIntervalPreferences(sharedPreferences);
|
||||||
Protocol.createId(deviceId));
|
updateOtherPreferences(sharedPreferences);
|
||||||
connection.setContext(this);
|
|
||||||
connection.connect();
|
connection.close();
|
||||||
|
connection.connect(address, port);
|
||||||
|
|
||||||
// Request location updates
|
|
||||||
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
||||||
period = intent.getIntExtra(Traccar.EXTRA_PERIOD, 0);
|
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, interval * 1000, 0, locationListener);
|
||||||
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, period * 1000, 0, this);
|
|
||||||
|
|
||||||
// Report status
|
|
||||||
registerReceiver(updateReceiver, new IntentFilter(Traccar.MSG_UPDATE));
|
|
||||||
setStatus(Traccar.STATUS_RUNNING);
|
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
// Close connection
|
|
||||||
if (connection != null) {
|
|
||||||
connection.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop location updates
|
|
||||||
if (locationManager != null) {
|
|
||||||
locationManager.removeUpdates(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Report status
|
|
||||||
unregisterReceiver(updateReceiver);
|
|
||||||
setStatus(Traccar.STATUS_STOPPED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
statusMessage(R.string.status_service_destroy);
|
||||||
|
|
||||||
|
locationManager.removeUpdates(locationListener);
|
||||||
|
|
||||||
|
handler.removeCallbacksAndMessages(null);
|
||||||
|
connection.close();
|
||||||
|
connection = null;
|
||||||
|
|
||||||
|
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
sharedPreferences.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateServerPreferences(SharedPreferences sharedPreferences) {
|
||||||
|
boolean changed = false;
|
||||||
|
|
||||||
|
String address = sharedPreferences.getString(TraccarActivity.KEY_ADDRESS, null);
|
||||||
|
if (!address.equals(this.address)) {
|
||||||
|
this.address = address;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int port = Integer.valueOf(sharedPreferences.getString(TraccarActivity.KEY_PORT, null));
|
||||||
|
if (port != this.port) {
|
||||||
|
this.port = port;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateIntervalPreferences(SharedPreferences sharedPreferences) {
|
||||||
|
boolean changed = false;
|
||||||
|
|
||||||
|
int interval = Integer.valueOf(sharedPreferences.getString(TraccarActivity.KEY_INTERVAL, null));
|
||||||
|
if (interval != this.interval) {
|
||||||
|
this.interval = interval;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateOtherPreferences(SharedPreferences sharedPreferences) {
|
||||||
|
id = sharedPreferences.getString(TraccarActivity.KEY_ID, null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reconnect() {
|
||||||
|
handler.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
connection.close();
|
||||||
|
connection.connect(address, port);
|
||||||
|
}
|
||||||
|
}, RECONNECT_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Connection.ConnectionHandler connectionHandler = new Connection.ConnectionHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnected(boolean result) {
|
||||||
|
if (result) {
|
||||||
|
statusMessage(R.string.status_connection_success);
|
||||||
|
connection.send(Protocol.createLoginMessage(id));
|
||||||
|
} else {
|
||||||
|
statusMessage(R.string.status_connection_fail);
|
||||||
|
reconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSent(boolean result) {
|
||||||
|
if (!result) {
|
||||||
|
statusMessage(R.string.status_send_fail);
|
||||||
|
reconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
private LocationListener locationListener = new LocationListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLocationChanged(Location location) {
|
||||||
|
statusMessage(R.string.status_location_update);
|
||||||
|
connection.send(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) {
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
OnSharedPreferenceChangeListener preferenceChangeListener = new OnSharedPreferenceChangeListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||||
|
statusMessage(R.string.status_preference_update);
|
||||||
|
|
||||||
|
if (updateServerPreferences(sharedPreferences)) {
|
||||||
|
connection.close();
|
||||||
|
connection.connect(address, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateIntervalPreferences(sharedPreferences)) {
|
||||||
|
locationManager.removeUpdates(locationListener);
|
||||||
|
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, interval * 1000, 0, locationListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOtherPreferences(sharedPreferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user