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

...
67 Коммитов
Автор SHA1 Сообщение Дата
Anton Tananaev 77213ecc91 Update gradle project file 2015-08-17 14:48:02 +12:00
Anton Tananaev 3214944d69 Fix wake lock release issue 2015-08-17 14:40:54 +12:00
Anton Tananaev 3e786e474d Fix null service intent issue 2015-08-17 14:35:24 +12:00
Anton Tananaev 0850ac09b0 Ensure that provider is correct 2015-08-17 14:22:13 +12:00
Anton Tananaev 50e6c00bd0 Remove unused string resources 2015-08-16 12:45:07 +12:00
Anton Tananaev 0e4918ba22 Change keystore location to relative 2015-08-16 12:37:08 +12:00
Anton Tananaev 8027c5be9f Update app version number 2015-08-16 12:33:25 +12:00
Anton Tananaev 6084bfdfbe Implement optional foreground service 2015-08-16 12:15:04 +12:00
Anton Tananaev b560577d96 Simplify position provider class 2015-08-15 21:55:53 +12:00
Anton Tananaev 92137c83bd Move wake lock to controller 2015-08-15 20:53:51 +12:00
Anton Tananaev 3617700351 Add wake lock to receiver 2015-08-14 19:49:17 +12:00
Anton Tananaev c803eb7bff Reduce default send frequency 2015-08-14 19:16:17 +12:00
Anton Tananaev 7fe765d124 Re-implement status logging 2015-08-14 18:52:28 +12:00
Anton Tananaev 3235229d1e Implement connectivity listener 2015-08-14 16:53:43 +12:00
Anton Tananaev 25e035e59d Implement buffering logic 2015-08-13 16:00:57 +12:00
Anton Tananaev b63bf4779e Implement async database calls 2015-08-13 13:29:03 +12:00
Anton Tananaev 2cf1213535 Create sync version of request 2015-08-13 11:58:59 +12:00
Anton Tananaev 03266a8c78 Implement database for buffer 2015-08-13 11:49:46 +12:00
Anton Tananaev 3782fd0003 Rename id to device id 2015-08-13 10:53:53 +12:00
Anton Tananaev fc83e7525a Start service as sticky 2015-08-12 22:30:39 +12:00
Anton Tananaev 596ede019c Use position in formatter 2015-08-12 22:14:24 +12:00
Anton Tananaev 2593ec7d2e Add port change dialog box 2015-08-12 21:53:39 +12:00
Anton Tananaev 14894c294e Change default port to 5055 2015-08-12 21:28:03 +12:00
Anton Tananaev fe9132e46a Remove old unused code 2015-08-12 20:32:42 +12:00
Anton Tananaev 26bc00f5fd Create new tracking controller 2015-08-12 20:31:09 +12:00
Anton Tananaev d5e2a3155c Refactor tracking service more 2015-08-12 20:13:04 +12:00
Anton Tananaev d49bc6ad28 Remove extended client protocol 2015-08-12 20:06:18 +12:00
Anton Tananaev c008c5f65e Refactor position provider class 2015-08-12 20:00:21 +12:00
Anton Tananaev e4f167f17b Create position model class 2015-08-12 19:52:49 +12:00
Anton Tananaev 346ad93ca0 Minor cleanup of service class 2015-08-12 19:44:04 +12:00
Anton Tananaev 3f4663c570 Remove preferences listener from service 2015-08-12 19:41:38 +12:00
Anton Tananaev 7396e9c436 Rename tracking service class 2015-08-12 19:39:10 +12:00
Anton Tananaev 59037d5fb1 Rename main activity class 2015-08-12 19:36:31 +12:00
Anton Tananaev 5591bec9e9 Minor activity class cleanup 2015-08-12 19:29:50 +12:00
Anton Tananaev e4151ac228 Disable settings when running 2015-08-12 19:28:47 +12:00
Anton Tananaev 630cf8eb86 Rename protocol formatter class 2015-08-12 19:17:18 +12:00
Anton Tananaev 222497d6ff Add new protocol formatter 2015-08-12 19:11:10 +12:00
Anton Tananaev 0f9645120b Use robolectric for unit tests 2015-08-12 16:54:47 +12:00
Anton Tananaev 9ffc0aa773 Rename main app module 2015-08-12 13:52:38 +12:00
Anton Tananaev 9d93c1d001 Update gradle wrapper props 2015-08-12 13:42:26 +12:00
Anton Tananaev ac6f648062 Create dummy request manager 2015-08-12 13:42:08 +12:00
Anton Tananaev 06c741e6b5 Add missing gradle files 2015-08-11 13:38:24 +12:00
Anton Tananaev ceaf4d526c Update gradle files 2015-08-11 13:12:48 +12:00
Anton Tananaev 6d4d0d74cd Add gradle wrapper properties 2015-08-11 13:05:55 +12:00
Anton Tananaev 0186b8fc6e Update git ignore list 2015-08-11 12:54:38 +12:00
Anton Tananaev 16c634b9f5 Cleanup project repository 2015-08-11 11:50:29 +12:00
Anton Tananaev 4aac812c8a Version 3.2 release 2015-05-05 22:54:44 +12:00
Anton Tananaev 9a2388011e Update Traccar logo icon 2015-05-05 22:51:58 +12:00
Anton Tananaev cd2277c3fd Change location check logic 2015-05-05 22:42:52 +12:00
Anton Tananaev 88d4ff69b7 Add app project file back 2015-05-02 12:48:32 +12:00
Anton Tananaev 4e7082bed6 Ignore lint in release build 2015-05-02 12:42:14 +12:00
Anton Tananaev d5224546c5 Fix some lint warnings 2015-05-02 12:39:33 +12:00
Anton Tananaev 29a0cd03ae Update tools and themes 2015-05-02 12:29:21 +12:00
Anton Tananaev 56f4534485 Update project description 2015-03-03 18:14:56 +13:00
Anton Tananaev 82ce44b64d Handle missing provider (fix #127) 2015-02-06 10:01:13 +13:00
Anton Tananaev 4f94c51e11 Update project files 2015-02-06 09:59:10 +13:00
Anton Tananaev 63b7566296 Merge pull request #114 from Rengaraj/master
Spelling mistake is corrected
2014-11-07 17:58:45 +13:00
Rengaraj af48a89874 Spelling mistake is corrected.
"In" is changed to "It"
2014-11-07 09:39:07 +05:30
Anton Tananaev 2266bab317 Merge pull request #107 from Armagetron/master
Fix a crash on missing provider
2014-10-10 17:35:03 +13:00
Armagetron 01060cf454 Fix a crash on unavailability of a location provider 2014-10-08 12:54:55 +02:00
Anton Tananaev 1d6da0c9d9 Merge pull request #105 from Armagetron/translation-german
Updated german translation
2014-08-20 19:04:14 +12:00
Armagetron be4f842a79 Updated german translation 2014-08-20 07:54:18 +02:00
Anton Tananaev f611b1b597 Add debugging code 2014-07-01 22:51:42 +12:00
Anton Tananaev 30412eb7b8 Change theme to light 2014-06-21 15:59:24 +12:00
Anton Tananaev d2399a5fed Merge branch 'krieger-od-fix-startup' 2014-06-21 15:12:40 +12:00
Anton Tananaev 026c3e1534 Merge branch fix-startup 2014-06-21 15:12:04 +12:00
Andrey Utkin 6d0db55b60 Launch Service on app start if preferences say so 2013-09-30 13:12:19 +03:00
81 изменённых файлов: 1421 добавлений и 1453 удалений
+6 -3
Просмотреть файл
@@ -1,4 +1,7 @@
.gradle
/local.properties
/.idea/workspace.xml
.DS_Store
.idea/
local.properties
traccar-client-android.iml
app/app.iml
build/
app/build/
Generated
-1
Просмотреть файл
@@ -1 +0,0 @@
traccar-client-android
-23
Просмотреть файл
@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>
-3
Просмотреть файл
@@ -1,3 +0,0 @@
<component name="CopyrightManager">
<settings default="" />
</component>
-5
Просмотреть файл
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>
-18
Просмотреть файл
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/traccar-client" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
-10
Просмотреть файл
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
</project>
-10
Просмотреть файл
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/traccar-client/traccar-client.iml" filepath="$PROJECT_DIR$/traccar-client/traccar-client.iml" />
<module fileurl="file://$PROJECT_DIR$/traccar-client-android.iml" filepath="$PROJECT_DIR$/traccar-client-android.iml" />
</modules>
</component>
</project>
-5
Просмотреть файл
@@ -1,5 +0,0 @@
<component name="DependencyValidationManager">
<state>
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</state>
</component>
Generated
-7
Просмотреть файл
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="" />
</component>
</project>
+27
Просмотреть файл
@@ -0,0 +1,27 @@
# [Traccar Client for Android](https://www.traccar.org/client)
## Contacts
Author - Anton Tananaev ([anton.tananaev@gmail.com](mailto:anton.tananaev@gmail.com))
Website - [https://www.traccar.org/client](https://www.traccar.org/client)
## Overview
Traccar Client is an Android GPS tracking application. It can work with Traccar open source server software.
## License
Apache License, Version 2.0
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.
-27
Просмотреть файл
@@ -1,27 +0,0 @@
traccar-client
Web page - http://www.traccar.org
Author - Anton Tananaev (anton.tananaev@gmail.com)
SUMMARY:
Traccar Client is Android GPS tracking application. In can work with
Traccar open source server software.
LICENSE:
Apache License, Version 2.0
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.
+34
Просмотреть файл
@@ -0,0 +1,34 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 3
targetSdkVersion 22
versionCode 24
versionName "3.4"
}
signingConfigs {
release {
storeFile file('../../android.keystore')
keyAlias "tananaev"
storePassword System.console().readLine("Enter store password: ")
keyPassword System.console().readLine("Enter key password: ")
}
}
buildTypes {
release {
minifyEnabled false
signingConfig signingConfigs.release
}
}
}
dependencies {
testCompile 'junit:junit:4.12'
testCompile "org.robolectric:robolectric:3.0"
}
+7 -6
Просмотреть файл
@@ -5,28 +5,29 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:allowBackup="true">
<application android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:allowBackup="true" android:theme="@style/TraccarTheme">
<activity android:name="TraccarActivity">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="StatusActivity">
<activity android:name=".StatusActivity">
</activity>
<activity android:name="AboutActivity">
<activity android:name=".AboutActivity">
</activity>
<service android:name="TraccarService" />
<service android:name=".TrackingService" />
<receiver android:name="AutostartReceiver">
<receiver android:name=".AutostartReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
+134
Просмотреть файл
@@ -0,0 +1,134 @@
/*
* Copyright (C) 2013 The Android Open Source Project
*
* 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 android.support.v4.content;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import android.util.Log;
import android.util.SparseArray;
/**
* Helper for the common pattern of implementing a {@link BroadcastReceiver}
* that receives a device wakeup event and then passes the work off
* to a {@link android.app.Service}, while ensuring that the
* device does not go back to sleep during the transition.
*
* <p>This class takes care of creating and managing a partial wake lock
* for you; you must request the {@link android.Manifest.permission#WAKE_LOCK}
* permission to use it.</p>
*
* <h3>Example</h3>
*
* <p>A {@link WakefulBroadcastReceiver} uses the method
* {@link WakefulBroadcastReceiver#startWakefulService startWakefulService()}
* to start the service that does the work. This method is comparable to
* {@link android.content.Context#startService startService()}, except that
* the {@link WakefulBroadcastReceiver} is holding a wake lock when the service
* starts. The intent that is passed with
* {@link WakefulBroadcastReceiver#startWakefulService startWakefulService()}
* holds an extra identifying the wake lock.</p>
*
* {@sample development/samples/Support4Demos/src/com/example/android/supportv4/content/SimpleWakefulReceiver.java complete}
*
* <p>The service (in this example, an {@link android.app.IntentService}) does
* some work. When it is finished, it releases the wake lock by calling
* {@link WakefulBroadcastReceiver#completeWakefulIntent
* completeWakefulIntent(intent)}. The intent it passes as a parameter
* is the same intent that the {@link WakefulBroadcastReceiver} originally
* passed in.</p>
*
* {@sample development/samples/Support4Demos/src/com/example/android/supportv4/content/SimpleWakefulService.java complete}
*/
public abstract class WakefulBroadcastReceiver extends BroadcastReceiver {
private static final String EXTRA_WAKE_LOCK_ID = "android.support.content.wakelockid";
private static final SparseArray<PowerManager.WakeLock> mActiveWakeLocks
= new SparseArray<PowerManager.WakeLock>();
private static int mNextId = 1;
/**
* Do a {@link android.content.Context#startService(android.content.Intent)
* Context.startService}, but holding a wake lock while the service starts.
* This will modify the Intent to hold an extra identifying the wake lock;
* when the service receives it in {@link android.app.Service#onStartCommand
* Service.onStartCommand}, it should pass back the Intent it receives there to
* {@link #completeWakefulIntent(android.content.Intent)} in order to release
* the wake lock.
*
* @param context The Context in which it operate.
* @param intent The Intent with which to start the service, as per
* {@link android.content.Context#startService(android.content.Intent)
* Context.startService}.
*/
public static ComponentName startWakefulService(Context context, Intent intent) {
synchronized (mActiveWakeLocks) {
int id = mNextId;
mNextId++;
if (mNextId <= 0) {
mNextId = 1;
}
intent.putExtra(EXTRA_WAKE_LOCK_ID, id);
ComponentName comp = context.startService(intent);
if (comp == null) {
return null;
}
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"wake:" + comp.flattenToShortString());
wl.setReferenceCounted(false);
wl.acquire(60*1000);
mActiveWakeLocks.put(id, wl);
return comp;
}
}
/**
* Finish the execution from a previous {@link #startWakefulService}. Any wake lock
* that was being held will now be released.
*
* @param intent The Intent as originally generated by {@link #startWakefulService}.
* @return Returns true if the intent is associated with a wake lock that is
* now released; returns false if there was no wake lock specified for it.
*/
public static boolean completeWakefulIntent(Intent intent) {
final int id = intent.getIntExtra(EXTRA_WAKE_LOCK_ID, 0);
if (id == 0) {
return false;
}
synchronized (mActiveWakeLocks) {
PowerManager.WakeLock wl = mActiveWakeLocks.get(id);
if (wl != null) {
wl.release();
mActiveWakeLocks.remove(id);
return true;
}
// We return true whether or not we actually found the wake lock
// the return code is defined to indicate whether the Intent contained
// an identifier for a wake lock that it was supposed to match.
// We just log a warning here if there is no wake lock found, which could
// happen for example if this function is called twice on the same
// intent or the process is killed and restarted before processing the intent.
Log.w("WakefulBroadcastReceive", "No active wake lock id #" + id);
return true;
}
}
}
@@ -15,22 +15,20 @@
*/
package org.traccar.client;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v4.content.WakefulBroadcastReceiver;
public class AutostartReceiver extends BroadcastReceiver {
public static final String LOG_TAG = "Traccar.AutostartReceiver";
public class AutostartReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedPreferences.getBoolean(TraccarActivity.KEY_STATUS, false)) {
context.startService(new Intent(context, TraccarService.class));
}
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (sharedPreferences.getBoolean(MainActivity.KEY_STATUS, false)) {
startWakefulService(context, new Intent(context, TrackingService.class));
}
}
}
+174
Просмотреть файл
@@ -0,0 +1,174 @@
/*
* Copyright 2015 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.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.AsyncTask;
import java.util.Date;
public class DatabaseHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "traccar.db";
public interface DatabaseHandler<T> {
void onSuccess(T result);
void onFailure(RuntimeException error);
}
private static abstract class DatabaseAsyncTask<T> extends AsyncTask<Void, Void, T> {
private DatabaseHandler<T> handler;
private RuntimeException error;
public DatabaseAsyncTask(DatabaseHandler<T> handler) {
this.handler = handler;
}
@Override
protected T doInBackground(Void... params) {
try {
return executeMethod();
} catch (RuntimeException error) {
this.error = error;
return null;
}
}
protected abstract T executeMethod();
@Override
protected void onPostExecute(T result) {
if (error == null) {
handler.onSuccess(result);
} else {
handler.onFailure(error);
}
}
}
private SQLiteDatabase db;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
db = getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE position (" +
"id INTEGER PRIMARY KEY AUTOINCREMENT," +
"deviceId TEXT," +
"time INTEGER," +
"latitude REAL," +
"longitude REAL," +
"altitude REAL," +
"speed REAL," +
"course REAL," +
"battery REAL)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS position;");
onCreate(db);
}
public void insertPosition(Position position) {
ContentValues values = new ContentValues();
values.put("deviceId", position.getDeviceId());
values.put("time", position.getTime().getTime());
values.put("latitude", position.getLatitude());
values.put("longitude", position.getLongitude());
values.put("altitude", position.getAltitude());
values.put("speed", position.getSpeed());
values.put("course", position.getCourse());
values.put("battery", position.getBattery());
db.insertOrThrow("position", null, values);
}
public void insertPositionAsync(final Position position, DatabaseHandler<Void> handler) {
new DatabaseAsyncTask<Void>(handler) {
@Override
protected Void executeMethod() {
insertPosition(position);
return null;
}
}.execute();
}
public Position selectPosition() {
Position position = new Position();
Cursor cursor = db.rawQuery("SELECT * FROM position ORDER BY id LIMIT 1", null);
try {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
position.setId(cursor.getLong(cursor.getColumnIndex("id")));
position.setDeviceId(cursor.getString(cursor.getColumnIndex("deviceId")));
position.setTime(new Date(cursor.getLong(cursor.getColumnIndex("time"))));
position.setLatitude(cursor.getDouble(cursor.getColumnIndex("latitude")));
position.setLongitude(cursor.getDouble(cursor.getColumnIndex("longitude")));
position.setAltitude(cursor.getDouble(cursor.getColumnIndex("altitude")));
position.setSpeed(cursor.getDouble(cursor.getColumnIndex("speed")));
position.setCourse(cursor.getDouble(cursor.getColumnIndex("course")));
position.setBattery(cursor.getDouble(cursor.getColumnIndex("battery")));
} else {
return null;
}
} finally {
cursor.close();
}
return position;
}
public void selectPositionAsync(DatabaseHandler<Position> handler) {
new DatabaseAsyncTask<Position>(handler) {
@Override
protected Position executeMethod() {
return selectPosition();
}
}.execute();
}
public void deletePosition(long id) {
if (db.delete("position", "id = ?", new String[] { String.valueOf(id) }) != 1) {
throw new SQLException();
}
}
public void deletePositionAsync(final long id, DatabaseHandler<Void> handler) {
new DatabaseAsyncTask<Void>(handler) {
@Override
protected Void executeMethod() {
deletePosition(id);
return null;
}
}.execute();
}
}
+166
Просмотреть файл
@@ -0,0 +1,166 @@
/*
* Copyright 2012 - 2015 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.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.telephony.TelephonyManager;
import android.view.Menu;
import android.view.MenuItem;
@SuppressWarnings("deprecation")
public class MainActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
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_INTERVAL = "interval";
public static final String KEY_PROVIDER = "provider";
public static final String KEY_STATUS = "status";
public static final String KEY_FOREGROUND = "foreground";
private boolean firstLaunch; // DELME
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
firstLaunch = !PreferenceManager.getDefaultSharedPreferences(this).contains(KEY_PORT);
addPreferencesFromResource(R.xml.preferences);
initPreferences();
// DELME
if (PreferenceManager.getDefaultSharedPreferences(this).getString(KEY_PROVIDER, null).equals("mixed")) {
PreferenceManager.getDefaultSharedPreferences(this).edit().putString(KEY_PROVIDER, LocationManager.GPS_PROVIDER).commit();
}
if (getPreferenceScreen().getSharedPreferences().getBoolean(KEY_STATUS, false)) {
setPreferencesEnabled(false);
startService(new Intent(this, TrackingService.class));
}
}
@Override
protected void onResume() {
super.onResume();
checkAndShowPortDialog(); // DELME
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
private void setPreferencesEnabled(boolean enabled) {
PreferenceScreen preferenceScreen = getPreferenceScreen();
preferenceScreen.findPreference(KEY_DEVICE).setEnabled(enabled);
preferenceScreen.findPreference(KEY_ADDRESS).setEnabled(enabled);
preferenceScreen.findPreference(KEY_PORT).setEnabled(enabled);
preferenceScreen.findPreference(KEY_INTERVAL).setEnabled(enabled);
preferenceScreen.findPreference(KEY_PROVIDER).setEnabled(enabled);
preferenceScreen.findPreference(KEY_FOREGROUND).setEnabled(enabled);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(KEY_STATUS)) {
if (sharedPreferences.getBoolean(KEY_STATUS, false)) {
setPreferencesEnabled(false);
startService(new Intent(this, TrackingService.class));
} else {
stopService(new Intent(this, TrackingService.class));
setPreferencesEnabled(true);
}
} else if (key.equals(KEY_DEVICE)) {
findPreference(KEY_DEVICE).setSummary(sharedPreferences.getString(KEY_DEVICE, null));
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().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 void initPreferences() {
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String id = telephonyManager.getDeviceId();
SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
if (!sharedPreferences.contains(KEY_DEVICE)) {
sharedPreferences.edit().putString(KEY_DEVICE, id).commit();
}
findPreference(KEY_DEVICE).setSummary(sharedPreferences.getString(KEY_DEVICE, id));
}
// TEMPORARY PORT CHANGE DIALOG (DELME)
private void checkAndShowPortDialog() {
String KEY_SHOWN_PORT_DIALOG = "portDialogHasBeenShown";
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
if (!firstLaunch) {
if (!preferences.contains(KEY_SHOWN_PORT_DIALOG)) {
showDialog(0);
}
}
preferences.edit().putBoolean(KEY_SHOWN_PORT_DIALOG, true).commit();
}
@Override
protected Dialog onCreateDialog(int id) {
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setMessage("Communication protocol used by the app has changed. Now it uses port 5055 on Traccar server. Do you want to change port to 5055?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
PreferenceManager.getDefaultSharedPreferences(MainActivity.this).edit().putString(KEY_PORT, "5055").commit();
}
})
.setNegativeButton("No", null);
return builder.create();
}
}
+68
Просмотреть файл
@@ -0,0 +1,68 @@
/*
* Copyright 2015 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.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
public class NetworkManager extends BroadcastReceiver {
private static final String TAG = NetworkManager.class.getSimpleName();
private Context context;
private NetworkHandler handler;
private ConnectivityManager connectivityManager;
public NetworkManager(Context context, NetworkHandler handler) {
this.context = context;
this.handler = handler;
connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
public interface NetworkHandler {
void onNetworkUpdate(boolean isOnline);
}
public boolean isOnline() {
NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}
public void start() {
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(this, filter);
}
public void stop() {
context.unregisterReceiver(this);
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION) && handler != null) {
boolean isOnline = isOnline();
Log.i(TAG, "network " + (isOnline ? "on" : "off"));
handler.onNetworkUpdate(isOnline);
}
}
}
+74
Просмотреть файл
@@ -0,0 +1,74 @@
/*
* Copyright 2015 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.location.Location;
import java.util.Date;
public class Position {
public Position() {
}
public Position(String deviceId, Location location, double battery) {
this.deviceId = deviceId;
time = new Date(location.getTime());
latitude = location.getLatitude();
longitude = location.getLongitude();
altitude = location.getAltitude();
speed = location.getSpeed() * 1.943844; // speed in knots
course = location.getBearing();
this.battery = battery;
}
private long id;
public long getId() { return id; }
public void setId(long id) { this.id = id; }
private String deviceId;
public String getDeviceId() { return deviceId; }
public void setDeviceId(String deviceId) { this.deviceId = deviceId; }
private Date time;
public Date getTime() { return time; }
public void setTime(Date time) { this.time = time; }
private double latitude;
public double getLatitude() { return latitude; }
public void setLatitude(double latitude) { this.latitude = latitude; }
private double longitude;
public double getLongitude() { return longitude; }
public void setLongitude(double longitude) { this.longitude = longitude; }
private double altitude;
public double getAltitude() { return altitude; }
public void setAltitude(double altitude) { this.altitude = altitude; }
private double speed;
public double getSpeed() { return speed; }
public void setSpeed(double speed) { this.speed = speed; }
private double course;
public double getCourse() { return course; }
public void setCourse(double course) { this.course = course; }
private double battery;
public double getBattery() { return battery; }
public void setBattery(double battery) { this.battery = battery; }
}
+114
Просмотреть файл
@@ -0,0 +1,114 @@
/*
* Copyright 2013 - 2015 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.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
public class PositionProvider implements LocationListener {
private static final String TAG = PositionProvider.class.getSimpleName();
public interface PositionListener {
void onPositionUpdate(Position position);
}
private final PositionListener listener;
private final Context context;
private final SharedPreferences preferences;
private final LocationManager locationManager;
private String deviceId;
private String type;
private final long period;
public PositionProvider(Context context, PositionListener listener) {
this.context = context;
this.listener = listener;
preferences = PreferenceManager.getDefaultSharedPreferences(context);
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
deviceId = preferences.getString(MainActivity.KEY_DEVICE, null);
period = Integer.parseInt(preferences.getString(MainActivity.KEY_INTERVAL, null)) * 1000;
type = preferences.getString(MainActivity.KEY_PROVIDER, null);
if (!type.equals(LocationManager.NETWORK_PROVIDER)) {
type = LocationManager.GPS_PROVIDER;
}
}
public void startUpdates() {
locationManager.requestLocationUpdates(type, period, 0, this);
}
public void stopUpdates() {
locationManager.removeUpdates(this);
}
private long lastTime;
@Override
public void onLocationChanged(Location location) {
if (location != null && location.getTime() != lastTime) {
Log.i(TAG, "location new");
lastTime = location.getTime();
listener.onPositionUpdate(new Position(deviceId, location, getBatteryLevel()));
} else {
Log.i(TAG, location != null ? "location old" : "location nil");
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.i(TAG, "provider status");
}
@Override
public void onProviderEnabled(String provider) {
Log.i(TAG, "provider enabled");
}
@Override
public void onProviderDisabled(String provider) {
Log.i(TAG, "provider disabled");
}
@TargetApi(Build.VERSION_CODES.ECLAIR)
public double getBatteryLevel() {
if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.ECLAIR) {
Intent batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);
return (level * 100.0) / scale;
} else {
return 0;
}
}
}
+39
Просмотреть файл
@@ -0,0 +1,39 @@
/*
* Copyright 2012 - 2015 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.location.Location;
import android.net.Uri;
public class ProtocolFormatter {
public static String formatRequest(String address, int port, Position position) {
Uri.Builder builder = new Uri.Builder();
builder.scheme("http").encodedAuthority(address + ':' + port)
.appendQueryParameter("id", position.getDeviceId())
.appendQueryParameter("timestamp", String.valueOf(position.getTime().getTime() / 1000))
.appendQueryParameter("lat", String.valueOf(position.getLatitude()))
.appendQueryParameter("lon", String.valueOf(position.getLongitude()))
.appendQueryParameter("speed", String.valueOf(position.getSpeed() * 1.943844))
.appendQueryParameter("bearing", String.valueOf(position.getCourse()))
.appendQueryParameter("altitude", String.valueOf(position.getAltitude()))
.appendQueryParameter("batt", String.valueOf(position.getBattery()));
return builder.build().toString();
}
}
+86
Просмотреть файл
@@ -0,0 +1,86 @@
/*
* Copyright 2015 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.os.AsyncTask;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class RequestManager {
private static final int TIMEOUT = 15 * 1000;
public interface RequestHandler {
void onSuccess();
void onFailure();
}
private static class RequestAsyncTask extends AsyncTask<String, Void, Boolean> {
private RequestHandler handler;
public RequestAsyncTask(RequestHandler handler) {
this.handler = handler;
}
@Override
protected Boolean doInBackground(String... request) {
return sendRequest(request[0]);
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
handler.onSuccess();
} else {
handler.onFailure();
}
}
}
public static boolean sendRequest(String request) {
InputStream inputStream = null;
try {
URL url = new URL(request);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(TIMEOUT);
connection.setConnectTimeout(TIMEOUT);
connection.connect();
inputStream = connection.getInputStream();
while (inputStream.read() != -1);
return true;
} catch (IOException error) {
return false;
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException secondError) {
return false;
}
}
}
public static void sendRequestAsync(String request, RequestHandler handler) {
RequestAsyncTask task = new RequestAsyncTask(handler);
task.execute(request);
}
}
@@ -23,7 +23,6 @@ import java.util.Set;
import android.app.ListActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -43,7 +42,6 @@ public class StatusActivity extends ListActivity {
}
public static void addMessage(String message) {
Log.i(TraccarActivity.LOG_TAG, message);
DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT);
message = format.format(new Date()) + " - " + message;
messages.add(message);
+212
Просмотреть файл
@@ -0,0 +1,212 @@
/*
* Copyright 2015 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.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.util.Log;
public class TrackingController implements PositionProvider.PositionListener, NetworkManager.NetworkHandler {
private static final String TAG = TrackingController.class.getSimpleName();
private static final int RETRY_DELAY = 30 * 1000;
private static final int WAKE_LOCK_TIMEOUT = 60 * 1000;
private boolean isOnline;
private boolean isWaiting;
private Context context;
private Handler handler;
private SharedPreferences preferences;
private PositionProvider positionProvider;
private DatabaseHelper databaseHelper;
private NetworkManager networkManager;
private PowerManager.WakeLock wakeLock;
private void lock() {
wakeLock.acquire(WAKE_LOCK_TIMEOUT);
}
private void unlock() {
if (wakeLock.isHeld()) {
wakeLock.release();
}
}
public TrackingController(Context context) {
this.context = context;
handler = new Handler();
preferences = PreferenceManager.getDefaultSharedPreferences(context);
positionProvider = new PositionProvider(context, this);
databaseHelper = new DatabaseHelper(context);
networkManager = new NetworkManager(context, this);
isOnline = networkManager.isOnline();
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
}
public void start() {
if (isOnline) {
read();
}
positionProvider.startUpdates();
networkManager.start();
}
public void stop() {
networkManager.stop();
positionProvider.stopUpdates();
handler.removeCallbacksAndMessages(null);
}
@Override
public void onPositionUpdate(Position position) {
if (position != null) {
StatusActivity.addMessage(context.getString(R.string.status_location_update));
write(position);
}
}
@Override
public void onNetworkUpdate(boolean isOnline) {
if (!this.isOnline && isOnline) {
read();
}
this.isOnline = isOnline;
}
//
// State transition examples:
//
// write -> read -> send -> delete -> read
//
// read -> send -> retry -> read -> send
//
private void log(String action, Position position) {
if (position != null) {
action += " (" +
"id:" + position.getId() +
" time:" + position.getTime().getTime() / 1000 +
" lat:" + position.getLatitude() +
" lon:" + position.getLongitude() + ")";
}
Log.d(TAG, action);
}
private void write(Position position) {
log("write", position);
lock();
databaseHelper.insertPositionAsync(position, new DatabaseHelper.DatabaseHandler<Void>() {
@Override
public void onSuccess(Void result) {
if (isOnline && isWaiting) {
read();
isWaiting = false;
}
unlock();
}
@Override
public void onFailure(RuntimeException error) {
unlock();
}
});
}
private void read() {
log("read", null);
lock();
databaseHelper.selectPositionAsync(new DatabaseHelper.DatabaseHandler<Position>() {
@Override
public void onSuccess(Position result) {
if (result != null) {
send(result);
} else {
isWaiting = true;
}
unlock();
}
@Override
public void onFailure(RuntimeException error) {
retry();
unlock();
}
});
}
private void delete(Position position) {
log("delete", position);
lock();
databaseHelper.deletePositionAsync(position.getId(), new DatabaseHelper.DatabaseHandler<Void>() {
@Override
public void onSuccess(Void result) {
read();
unlock();
}
@Override
public void onFailure(RuntimeException error) {
retry();
unlock();
}
});
}
private void send(final Position position) {
log("send", position);
lock();
String request = ProtocolFormatter.formatRequest(
preferences.getString(MainActivity.KEY_ADDRESS, null),
Integer.parseInt(preferences.getString(MainActivity.KEY_PORT, null)),
position);
RequestManager.sendRequestAsync(request, new RequestManager.RequestHandler() {
@Override
public void onSuccess() {
delete(position);
unlock();
}
@Override
public void onFailure() {
StatusActivity.addMessage(context.getString(R.string.status_send_fail));
retry();
unlock();
}
});
}
private void retry() {
log("retry", null);
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (isOnline) {
read();
}
}
}, RETRY_DELAY);
}
}
+93
Просмотреть файл
@@ -0,0 +1,93 @@
/*
* Copyright 2012 - 2015 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.annotation.TargetApi;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
public class TrackingService extends Service {
private static final String TAG = TrackingService.class.getSimpleName();
private static final int NOTIFICATION_ID = 1;
private TrackingController trackingController;
private boolean foreground;
@Override
public void onCreate() {
Log.i(TAG, "service create");
StatusActivity.addMessage(getString(R.string.status_service_create));
trackingController = new TrackingController(this);
trackingController.start();
foreground = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(MainActivity.KEY_FOREGROUND, false);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@SuppressWarnings("deprecation")
@Override
public void onStart(Intent intent, int startId) {
if (intent != null) {
AutostartReceiver.completeWakefulIntent(intent);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR && foreground) {
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new Notification(android.R.drawable.stat_notify_sync_noanim, null, 0);
notification.setLatestEventInfo(
this, getString(R.string.app_name), getString(R.string.settings_status_on_summary), pendingIntent);
startForeground(NOTIFICATION_ID, notification);
}
}
@TargetApi(Build.VERSION_CODES.ECLAIR)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return START_STICKY;
}
@Override
public void onDestroy() {
Log.i(TAG, "service destroy");
StatusActivity.addMessage(getString(R.string.status_service_destroy));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR && foreground) {
stopForeground(true);
}
if (trackingController != null) {
trackingController.stop();
}
}
}
Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.7 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 10 KiB

+3
Просмотреть файл
@@ -8,8 +8,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="@dimen/about_margin"
android:layout_marginStart="@dimen/about_margin"
android:layout_marginTop="@dimen/about_margin"
android:src="@drawable/ic_launcher"
android:contentDescription="@string/app_logo" />
@@ -19,6 +21,7 @@
android:layout_height="fill_parent"
android:layout_margin="@dimen/about_margin"
android:layout_toRightOf="@+id/logo"
android:layout_toEndOf="@+id/logo"
android:orientation="vertical" >
<TextView
Просмотреть файл
Просмотреть файл
Просмотреть файл
+2 -7
Просмотреть файл
@@ -16,15 +16,14 @@
<string name="settings_status_on">Stop</string>
<string name="settings_status_off_summary">Zastaveno</string>
<string name="settings_status_on_summary">Spuštěno</string>
<string name="settings_extended_title">Rozšířené formát</string>
<string name="settings_extended_summary">Použijte nový formát zprávy</string>
<string name="settings_provider_title">Poskytovatel zaměření</string>
<string name="settings_provider_summary">Zdroj zaměřovacích dat</string>
<string-array name="settings_provider_names">
<item>GPS</item>
<item>Mobilní síť</item>
<item>Obojí</item>
</string-array>
<string name="settings_foreground_title">Popředí služba</string>
<string name="settings_foreground_summary">Zvýšit prioritu služba</string>
<string name="menu_status">Stav</string>
<string name="menu_about">O aplikaci</string>
@@ -35,13 +34,9 @@
<string name="about_web">Pro více informací navštivte\nwww.traccar.org/client</string>
<string name="status_service_create">Služba vytvořena</string>
<string name="status_service_start">Služba spuštěna</string>
<string name="status_service_destroy">Služba zastavena</string>
<string name="status_connection_success">Spojení se zdařilo</string>
<string name="status_connection_fail">Spojení selhalo</string>
<string name="status_send_fail">Odesílání selhalo</string>
<string name="status_location_update">Aktualizace pozice</string>
<string name="status_preference_update">Aktualizace nastavení</string>
<string name="status_connectivity_change">Změna připojení</string>
</resources>
+2 -7
Просмотреть файл
@@ -16,15 +16,14 @@
<string name="settings_status_on">Stop</string>
<string name="settings_status_off_summary">Service stoppet</string>
<string name="settings_status_on_summary">Service er aktiv</string>
<string name="settings_extended_title">Udvidet format</string>
<string name="settings_extended_summary">Brug ny besked format</string>
<string name="settings_provider_title">Udbyder</string>
<string name="settings_provider_summary">Udbyder lokaliseringsdata</string>
<string-array name="settings_provider_names">
<item>GPS udbyder</item>
<item>Netværks udbyder</item>
<item>Mixet udbyder</item>
</string-array>
<string name="settings_foreground_title">Forgrunden tjeneste</string>
<string name="settings_foreground_summary">Øg tjeneste prioritet</string>
<string name="menu_status">Status</string>
<string name="menu_about">Om</string>
@@ -35,13 +34,9 @@
<string name="about_web">For mere information besøg\nwww.traccar.org/client</string>
<string name="status_service_create">Service oprettet</string>
<string name="status_service_start">Service startet</string>
<string name="status_service_destroy">Service ødelagt</string>
<string name="status_connection_success">Forbindelse lykkedes</string>
<string name="status_connection_fail">Forbindelse fejlet</string>
<string name="status_send_fail">Send fejl</string>
<string name="status_location_update">Placering opdateret</string>
<string name="status_preference_update">Oplysninger opdateret</string>
<string name="status_connectivity_change">Connectivity forandring</string>
</resources>
+2 -7
Просмотреть файл
@@ -16,15 +16,14 @@
<string name="settings_status_on">Stop</string>
<string name="settings_status_off_summary">Dienst inaktiv</string>
<string name="settings_status_on_summary">Dienst aktiv</string>
<string name="settings_extended_title">Erweiterte Format</string>
<string name="settings_extended_summary">Verwenden Sie neue Nachrichtenformat</string>
<string name="settings_provider_title">Datenherkunft</string>
<string name="settings_provider_summary">Quelle der Positionen</string>
<string-array name="settings_provider_names">
<item>GPS</item>
<item>Netzwerk</item>
<item>Gemischt</item>
</string-array>
<string name="settings_foreground_title">Vordergrund service</string>
<string name="settings_foreground_summary">Erhöhen service priorität</string>
<string name="menu_status">Status</string>
<string name="menu_about">Über</string>
@@ -35,13 +34,9 @@
<string name="about_web">Für weitere Informationen besuche uns auf \nwww.traccar.org/client</string>
<string name="status_service_create">Dienst installiert</string>
<string name="status_service_start">Dienst gestartet</string>
<string name="status_service_destroy">Dienst zerstört</string>
<string name="status_connection_success">Verbindung erfolgreich</string>
<string name="status_connection_fail">Verbindung fehlerhaft</string>
<string name="status_send_fail">Übertragung fehlerhaft</string>
<string name="status_location_update">Positionsupdate</string>
<string name="status_preference_update">Prioritätsupdate</string>
<string name="status_connectivity_change">Anschlusswechsel</string>
</resources>
+2 -7
Просмотреть файл
@@ -16,15 +16,14 @@
<string name="settings_status_on">Desactivado</string>
<string name="settings_status_off_summary">Servicio parado</string>
<string name="settings_status_on_summary">Servicio activado</string>
<string name="settings_extended_title">Formato extendido</string>
<string name="settings_extended_summary">Utilice el nuevo formato de mensaje</string>
<string name="settings_provider_title">Proveedor de localización</string>
<string name="settings_provider_summary">Fuente de los datos de localización</string>
<string-array name="settings_provider_names">
<item>Proveedor GPS</item>
<item>Proveedor de red</item>
<item>Proveedor mixto</item>
</string-array>
<string name="settings_foreground_title">Servicio de primer plano</string>
<string name="settings_foreground_summary">Aumentar prioridad de servicio</string>
<string name="menu_status">Estado</string>
<string name="menu_about">Acerca de&#8230;</string>
@@ -35,13 +34,9 @@
<string name="about_web">Para más información visite\nwww.traccar.org/client</string>
<string name="status_service_create">Servicio creado</string>
<string name="status_service_start">Service arrancado</string>
<string name="status_service_destroy">Servicio destruído</string>
<string name="status_connection_success">Conexión realizada</string>
<string name="status_connection_fail">Fallo en la conexión</string>
<string name="status_send_fail">Erro en el envío</string>
<string name="status_location_update">Posición actualizada</string>
<string name="status_preference_update">Preferencias actualizadas</string>
<string name="status_connectivity_change">Cambio conectividad</string>
</resources>
+2 -7
Просмотреть файл
@@ -16,15 +16,14 @@
<string name="settings_status_on">Arrêter</string>
<string name="settings_status_off_summary">Arrêté</string>
<string name="settings_status_on_summary">En marche</string>
<string name="settings_extended_title">Format étendu</string>
<string name="settings_extended_summary">Utilisez un nouveau format de message</string>
<string name="settings_provider_title">Source de localisation</string>
<string name="settings_provider_summary">Source utilisée par le système afin d\'obtenir la localisation de l\'appareil</string>
<string-array name="settings_provider_names">
<item>Mode GPS uniquement</item>
<item>Mode cellulaire uniquement</item>
<item>Mode hybride</item>
</string-array>
<string name="settings_foreground_title">Un service de premier plan</string>
<string name="settings_foreground_summary">Augmenter la priorité de service</string>
<string name="menu_status">Etat</string>
<string name="menu_about">A propos</string>
@@ -35,13 +34,9 @@
<string name="about_web">Pour plus dinformation, visitez le site: \nwww.traccar.org/client</string>
<string name="status_service_create">Service créé</string>
<string name="status_service_start">Service démarré</string>
<string name="status_service_destroy">Service supprimé</string>
<string name="status_connection_success">Connexion établie avec le serveur</string>
<string name="status_connection_fail">Echec de la connexion au serveur</string>
<string name="status_send_fail">Lenvoi de localisation a échoué</string>
<string name="status_location_update">Localisation mise à jour</string>
<string name="status_preference_update">Mise à jour des préférences</string>
<string name="status_connectivity_change">Changement de connectivité</string>
</resources>
+2 -7
Просмотреть файл
@@ -16,15 +16,14 @@
<string name="settings_status_on">Stopp</string>
<string name="settings_status_off_summary">Tjenesten stoppet</string>
<string name="settings_status_on_summary">Tjenesten kjører</string>
<string name="settings_extended_title">Utvidet format</string>
<string name="settings_extended_summary">Bruk det nye utvidede formatet</string>
<string name="settings_provider_title">Lokaliseringsleverandør</string>
<string name="settings_provider_summary">Kilde for lokaliseringsdata</string>
<string-array name="settings_provider_names">
<item>GPS-lokalisering</item>
<item>Nettverkslokalisering</item>
<item>Blandet lokalisering</item>
</string-array>
<string name="settings_foreground_title">Forgrunnen tjeneste</string>
<string name="settings_foreground_summary">Øk tjeneste prioritet</string>
<string name="menu_status">Status</string>
<string name="menu_about">Om</string>
@@ -35,13 +34,9 @@
<string name="about_web">For mer informasjon besøk\nwww.traccar.org/client</string>
<string name="status_service_create">Tjeneste opprettet</string>
<string name="status_service_start">Tjeneste startet</string>
<string name="status_service_destroy">Tjeneste ødelagt</string>
<string name="status_connection_success">Tilkobling var vellykket</string>
<string name="status_connection_fail">Tilkobling mislyktes</string>
<string name="status_send_fail">Sending mislyktes</string>
<string name="status_location_update">Plassering oppdatert</string>
<string name="status_preference_update">Innstillinger oppdatert</string>
<string name="status_connectivity_change">Tilkobling forandret</string>
</resources>
+2 -7
Просмотреть файл
@@ -16,15 +16,14 @@
<string name="settings_status_on">Parar</string>
<string name="settings_status_off_summary">Serviço Parado</string>
<string name="settings_status_on_summary">Serviço em execução</string>
<string name="settings_extended_title">Formato prolongado</string>
<string name="settings_extended_summary">Use o formato de mensagem nova</string>
<string name="settings_provider_title">Provedor de localização</string>
<string name="settings_provider_summary">Fonte dos dados de localização</string>
<string-array name="settings_provider_names">
<item>Provedor GPS</item>
<item>Provedor Rede</item>
<item>Provedor Misto</item>
</string-array>
<string name="settings_foreground_title">Serviço primeiro plano</string>
<string name="settings_foreground_summary">Aumentar a prioridade de serviço</string>
<string name="menu_status">Status</string>
<string name="menu_about">Sobre</string>
@@ -35,13 +34,9 @@
<string name="about_web">Para mais informações visite\nwww.traccar.org/client</string>
<string name="status_service_create">Serviço criado</string>
<string name="status_service_start">Serviço iniciado</string>
<string name="status_service_destroy">Serviço destruído</string>
<string name="status_connection_success">Sucesso na conexão</string>
<string name="status_connection_fail">Falha na conexão</string>
<string name="status_send_fail">Falha no envio</string>
<string name="status_location_update">Localização atualizada</string>
<string name="status_preference_update">Preferências atualizadas</string>
<string name="status_connectivity_change">Mudança de conectividade</string>
</resources>
+2 -7
Просмотреть файл
@@ -16,15 +16,14 @@
<string name="settings_status_on">Стоп</string>
<string name="settings_status_off_summary">Сервис остановлен</string>
<string name="settings_status_on_summary">Сервис запущен</string>
<string name="settings_extended_title">Расширенный формат</string>
<string name="settings_extended_summary">Использовать новый формат сообщений</string>
<string name="settings_provider_title">Провайдер местоположения</string>
<string name="settings_provider_summary">Источник данных о местоположении</string>
<string-array name="settings_provider_names">
<item>GPS провайдер</item>
<item>Сетевой провайдер</item>
<item>Смешанный провайдер</item>
</string-array>
<string name="settings_foreground_title">Приотитетный сервис</string>
<string name="settings_foreground_summary">Увеличить приоритет сервиса</string>
<string name="menu_status">Состояние</string>
<string name="menu_about">О программе</string>
@@ -35,13 +34,9 @@
<string name="about_web">Для получения дополнительной информации посетите\nwww.traccar.org/client</string>
<string name="status_service_create">Сервис создан</string>
<string name="status_service_start">Сервис запущен</string>
<string name="status_service_destroy">Сервис удален</string>
<string name="status_connection_success">Соедниение установлено</string>
<string name="status_connection_fail">Ошибка установки соединения</string>
<string name="status_send_fail">Ошибка отправки</string>
<string name="status_location_update">Обновление местоположения</string>
<string name="status_preference_update">Обновление настроек</string>
<string name="status_connectivity_change">Изменение подключения</string>
</resources>
+2 -7
Просмотреть файл
@@ -16,15 +16,14 @@
<string name="settings_status_on">Stop</string>
<string name="settings_status_off_summary">Servis zaustavljen</string>
<string name="settings_status_on_summary">Servis pokrenut</string>
<string name="settings_extended_title">Produžen format</string>
<string name="settings_extended_summary">Koristi novi format za poruke</string>
<string name="settings_provider_title">Provajder lokacije</string>
<string name="settings_provider_summary">Izvor lokacijskih podataka</string>
<string-array name="settings_provider_names">
<item>GPS provajder</item>
<item>Provajder Mreže</item>
<item>Oba zajedno provajdera</item>
</string-array>
<string name="settings_foreground_title">Prvi plan servis</string>
<string name="settings_foreground_summary">Povecanje usluga prioritet</string>
<string name="menu_status">Status</string>
<string name="menu_about">O klijentu</string>
@@ -35,13 +34,9 @@
<string name="about_web">"Za više informacija www.traccar.org/client "</string>
<string name="status_service_create">Servis kreiran</string>
<string name="status_service_start">Servis pokrenut</string>
<string name="status_service_destroy">Servis uništen</string>
<string name="status_connection_success">Konekcija uspešna</string>
<string name="status_connection_fail">Konekcija neuspešna</string>
<string name="status_send_fail">Slanje neuspešno</string>
<string name="status_location_update">Ažuriranje lokacije</string>
<string name="status_preference_update">Ažuriranje preferenci</string>
<string name="status_connectivity_change">Promenjena konekcija</string>
</resources>
+7
Просмотреть файл
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TraccarTheme" parent="android:Theme.Holo.Light">
</style>
</resources>
+7
Просмотреть файл
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TraccarTheme" parent="android:Theme.Material.Light">
</style>
</resources>
Просмотреть файл
+2 -7
Просмотреть файл
@@ -16,15 +16,14 @@
<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_extended_title">Extended format</string>
<string name="settings_extended_summary">Use new message format</string>
<string name="settings_provider_title">Location provider</string>
<string name="settings_provider_summary">Source of location data</string>
<string-array name="settings_provider_names">
<item>GPS provider</item>
<item>Network provider</item>
<item>Mixed provider</item>
</string-array>
<string name="settings_foreground_title">Foreground service</string>
<string name="settings_foreground_summary">Increase service priority</string>
<string name="menu_status">Status</string>
<string name="menu_about">About</string>
@@ -35,13 +34,9 @@
<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>
<string name="status_connectivity_change">Connectivity change</string>
</resources>
+7
Просмотреть файл
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TraccarTheme" parent="android:Theme.Light">
</style>
</resources>
-1
Просмотреть файл
@@ -4,7 +4,6 @@
<string-array name="settings_provider_values" translatable="false">
<item>gps</item>
<item>network</item>
<item>mixed</item>
</string-array>
</resources>
+15 -15
Просмотреть файл
@@ -1,6 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<SwitchPreference
android:defaultValue="false"
android:key="status"
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:title="@string/settings_status_title" />
<EditTextPreference
android:key="id"
android:title="@string/settings_id_title" />
@@ -12,14 +21,14 @@
android:title="@string/settings_address_title" />
<EditTextPreference
android:defaultValue="5005"
android:defaultValue="5055"
android:key="port"
android:numeric="integer"
android:summary="@string/settings_port_summary"
android:title="@string/settings_port_title" />
<EditTextPreference
android:defaultValue="60"
android:defaultValue="300"
android:key="interval"
android:numeric="integer"
android:summary="@string/settings_interval_summary"
@@ -34,18 +43,9 @@
android:title="@string/settings_provider_title" />
<CheckBoxPreference
android:defaultValue="false"
android:key="extended"
android:summary="@string/settings_extended_summary"
android:title="@string/settings_extended_title" />
<SwitchPreference
android:defaultValue="false"
android:key="status"
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:title="@string/settings_status_title" />
android:defaultValue="true"
android:key="foreground"
android:summary="@string/settings_foreground_summary"
android:title="@string/settings_foreground_title" />
</PreferenceScreen>
+13 -13
Просмотреть файл
@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<CheckBoxPreference
android:defaultValue="false"
android:key="status"
android:summaryOff="@string/settings_status_off_summary"
android:summaryOn="@string/settings_status_on_summary"
android:title="@string/settings_status_title" />
<EditTextPreference
android:key="id"
android:title="@string/settings_id_title" />
@@ -12,14 +19,14 @@
android:title="@string/settings_address_title" />
<EditTextPreference
android:defaultValue="5005"
android:defaultValue="5055"
android:key="port"
android:numeric="integer"
android:summary="@string/settings_port_summary"
android:title="@string/settings_port_title" />
<EditTextPreference
android:defaultValue="60"
android:defaultValue="300"
android:key="interval"
android:numeric="integer"
android:summary="@string/settings_interval_summary"
@@ -34,16 +41,9 @@
android:title="@string/settings_provider_title" />
<CheckBoxPreference
android:defaultValue="false"
android:key="extended"
android:summary="@string/settings_extended_summary"
android:title="@string/settings_extended_title" />
<CheckBoxPreference
android:defaultValue="false"
android:key="status"
android:summaryOff="@string/settings_status_off_summary"
android:summaryOn="@string/settings_status_on_summary"
android:title="@string/settings_status_title" />
android:defaultValue="true"
android:key="foreground"
android:summary="@string/settings_foreground_summary"
android:title="@string/settings_foreground_title" />
</PreferenceScreen>
+46
Просмотреть файл
@@ -0,0 +1,46 @@
package org.traccar.client;
import android.database.sqlite.SQLiteDatabase;
import android.location.Location;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.Date;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class DatabaseHelperTest {
@Test
public void test() throws Exception {
DatabaseHelper databaseHelper = new DatabaseHelper(RuntimeEnvironment.application);
SQLiteDatabase db = databaseHelper.getWritableDatabase();
Position position = new Position("123456789012345", new Location("gps"), 0);
position.setTime(new Date(0));
assertNull(databaseHelper.selectPosition());
databaseHelper.insertPosition(position);
position = databaseHelper.selectPosition();
assertNotNull(position);
databaseHelper.deletePosition(position.getId());
assertNull(databaseHelper.selectPosition());
}
}
+31
Просмотреть файл
@@ -0,0 +1,31 @@
package org.traccar.client;
import android.location.Location;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;
import java.util.Date;
import static org.junit.Assert.assertEquals;
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class ProtocolFormatterTest {
@Test
public void testFormatRequest() throws Exception {
Position position = new Position("123456789012345", new Location("gps"), 0);
position.setTime(new Date(0));
String url = ProtocolFormatter.formatRequest("localhost", 5055, position);
assertEquals("http://localhost:5055?id=123456789012345&timestamp=0&lat=0.0&lon=0.0&speed=0.0&bearing=0.0&altitude=0.0&batt=0.0", url);
}
}
+22
Просмотреть файл
@@ -0,0 +1,22 @@
package org.traccar.client;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;
import static org.junit.Assert.assertTrue;
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class RequestManagerTest {
@Test
public void testSendRequest() throws Exception {
assertTrue(RequestManager.sendRequest("http://www.google.com"));
}
}
+1 -1
Просмотреть файл
@@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.9.+'
classpath 'com.android.tools.build:gradle:1.3.0'
}
}
-18
Просмотреть файл
@@ -1,18 +0,0 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Settings specified in this file will override any Gradle settings
# configured through the IDE.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
Двоичные данные
Двоичный файл не отображается.
+2 -2
Просмотреть файл
@@ -1,6 +1,6 @@
#Thu May 15 23:13:59 NZST 2014
#Wed Aug 12 13:33:05 NZST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.11-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-all.zip
Vendored
-90
Просмотреть файл
@@ -1,90 +0,0 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
-135
Просмотреть файл
@@ -1,135 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="512"
height="512"
id="svg4101"
version="1.1"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="icon.svg"
inkscape:export-filename="/home/user/Documents/traccar-client/res/drawable-xhdpi/ic_launcher.png"
inkscape:export-xdpi="16.875"
inkscape:export-ydpi="16.875">
<defs
id="defs4103" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="402.73478"
inkscape:cy="279.68584"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1680"
inkscape:window-height="1026"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
width="512px" />
<metadata
id="metadata4106">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-317.72197,34.03834)">
<g
id="g3057">
<rect
ry="99.363052"
rx="99.36306"
y="-11.541533"
x="340.21878"
height="467.00638"
width="467.00635"
id="rect3055"
style="fill:#ffffff;stroke:#ffffff;stroke-width:0.99363058999999998" />
<g
transform="matrix(3.9153612,2.053283,-2.053283,3.9153612,92.187853,-3064.4694)"
id="g4068">
<g
id="g4046"
transform="matrix(0.83109018,-0.84335752,0.84335752,0.83109018,-425.72131,478.52845)">
<path
inkscape:connector-curvature="0"
id="path3194"
d="m 443.65385,563.57293 c -1.05193,-0.0129 -2.10701,0.0598 -3.12744,0.18048 l 0.06,2.75094 c 0.99036,-0.12733 2.00989,-0.19417 3.0337,-0.18162 12.83055,0.15709 23.11001,11.57671 22.93914,25.53274 -0.002,0.17643 -0.001,0.35569 -0.007,0.53121 l 2.50057,-0.0319 c 0.004,-0.15699 0.004,-0.31113 0.006,-0.46872 0.18944,-15.473 -11.18011,-28.13898 -25.40528,-28.31315 z"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none" />
<path
sodipodi:nodetypes="cccscccccc"
inkscape:connector-curvature="0"
id="path3194-4"
d="m 442.89836,570.53348 c -0.79783,-0.01 -1.59802,0.0454 -2.37195,0.13688 l 0.0455,2.52833 c 0.75111,-0.0966 1.52436,-0.14725 2.30084,-0.13774 9.73108,0.11913 16.95911,8.33817 16.82952,18.92284 -0.002,0.1338 -10e-4,0.26976 -0.005,0.40289 l 2.46472,-0.0242 c 0.003,-0.11907 0.003,-0.23598 0.004,-0.35547 0.14368,-11.73519 -8.47933,-21.34145 -19.26811,-21.47354 z"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none" />
<path
sodipodi:nodetypes="cccccccccc"
inkscape:connector-curvature="0"
id="path3194-0"
d="m 442.20847,576.88946 c -0.56577,-0.007 -1.13323,0.0322 -1.68206,0.0971 l 0.0323,2.42658 c 0.53265,-0.0685 1.081,-0.10442 1.63165,-0.0977 6.90079,0.46331 10.91426,5.09 11.13804,12.78552 -10e-4,0.0949 -7.7e-4,0.19129 -0.003,0.28572 l 2.54446,-0.0171 c 0.002,-0.0845 0.002,-0.16735 0.003,-0.25208 0.10189,-8.32201 -6.01312,-15.13429 -13.66399,-15.22797 z"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none" />
</g>
<g
id="g4061"
transform="translate(4.3272904,0)">
<path
id="path4401"
d="m 428.82958,632.50381 c 1.51739,8.39514 3.18843,16.70366 3.25039,25.86381 13.43389,-7.07008 16.24573,-8.60045 29.67957,-15.67062 -4.84405,-3.37683 -9.59166,-7.39353 -13.56307,-11.22903 -6.14118,1.98174 -12.37667,2.63171 -19.36689,1.03584 z m 3.03559,3.5588 2.90054,0.34654 c 1.65734,7.68989 1.24429,15.11973 -0.19508,18.63703 -0.5999,-6.11993 -0.9108,-10.44519 -2.70546,-18.98357 z"
style="fill:#000000;fill-opacity:1;stroke:none"
inkscape:connector-curvature="0" />
<path
id="path3423-9-5"
d="m 398.11826,602.8218 c 5.46403,15.3042 20.05405,26.26585 37.2409,26.32057 17.18753,0.0547 31.81943,-10.80285 37.38029,-26.07291 l -74.62119,-0.24766 z m 6.11343,4.37701 6.55964,0.18844 c 4.52018,8.23085 9.05564,11.77782 15.40988,16.82483 -9.13544,-2.75636 -16.94711,-7.80772 -21.96952,-17.01327 z"
style="fill:#000000;fill-opacity:1;stroke:none"
inkscape:connector-curvature="0" />
<g
transform="translate(2.1996971,2)"
id="g4055">
<rect
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect4051"
width="3.2829957"
height="8.0812206"
x="431.58765"
y="594.76306" />
<path
sodipodi:type="arc"
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path4053"
sodipodi:cx="433.22916"
sodipodi:cy="594.00549"
sodipodi:rx="3.4092648"
sodipodi:ry="3.7880721"
d="m 436.63842,594.00549 c 0,2.0921 -1.52638,3.78808 -3.40926,3.78808 -1.88289,0 -3.40927,-1.69598 -3.40927,-3.78808 0,-2.09209 1.52638,-3.78807 3.40927,-3.78807 1.88288,0 3.40926,1.69598 3.40926,3.78807 z" />
</g>
</g>
</g>
</g>
</g>
</svg>

До

Ширина:  |  Высота:  |  Размер: 6.4 KiB

Двоичные данные
Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 25 KiB

+1 -1
Просмотреть файл
@@ -1 +1 @@
include ':traccar-client'
include ':app'
-13
Просмотреть файл
@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
-1
Просмотреть файл
@@ -1 +0,0 @@
/build
-33
Просмотреть файл
@@ -1,33 +0,0 @@
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion "19.0.3"
defaultConfig {
minSdkVersion 3
targetSdkVersion 19
versionCode 19
versionName "2.12"
}
signingConfigs {
release {
storeFile file('/home/user/Documents/android.keystore')
keyAlias "tananaev"
storePassword ""
keyPassword ""
}
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
signingConfig signingConfigs.release
}
}
}
dependencies {
}
-17
Просмотреть файл
@@ -1,17 +0,0 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/user/android-studio/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-141
Просмотреть файл
@@ -1,141 +0,0 @@
/*
* 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.LinkedList;
import java.util.Queue;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.util.Log;
public class ClientController implements Connection.ConnectionHandler {
public static final long RECONNECT_DELAY = 10 * 1000;
private Context context;
private Handler handler;
private Queue<String> messageQueue;
private Connection connection;
private String address;
private int port;
private String loginMessage;
public ClientController(Context context, String address, int port, String loginMessage) {
this.context = context;
messageQueue = new LinkedList<String>();
this.address = address;
this.port = port;
this.loginMessage = loginMessage;
}
private BroadcastReceiver connectivityListener = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
StatusActivity.addMessage(context.getString(R.string.status_connectivity_change));
/*if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)) {
handler.removeCallbacksAndMessages(null);
} else {
reconnect();
}*/
}
};
public void start() {
handler = new Handler();
connection = new Connection(this);
connection.connect(address, port);
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(connectivityListener, filter);
}
public void stop() {
context.unregisterReceiver(connectivityListener);
connection.close();
handler.removeCallbacksAndMessages(null);
}
private void reconnect() {
handler.removeCallbacksAndMessages(null);
connection.close();
connection = new Connection(this);
connection.connect(address, port);
}
private void delayedReconnect() {
connection.close();
handler.postDelayed(new Runnable() {
@Override
public void run() {
connection = new Connection(ClientController.this);
connection.connect(address, port);
}
}, RECONNECT_DELAY);
}
public void setNewServer(String address, int port) {
this.address = address;
this.port = port;
reconnect();
}
public void setNewLogin(String loginMessage) {
this.loginMessage = loginMessage;
reconnect();
}
public void setNewLocation(String locationMessage) {
messageQueue.offer(locationMessage);
if (!connection.isClosed() && !connection.isBusy()) {
connection.send(messageQueue.poll());
}
}
@Override
public void onConnected(boolean result) {
if (result) {
StatusActivity.addMessage(context.getString(R.string.status_connection_success));
connection.send(loginMessage);
} else {
StatusActivity.addMessage(context.getString(R.string.status_connection_fail));
delayedReconnect();
}
}
@Override
public void onSent(boolean result) {
if (result) {
if (!messageQueue.isEmpty()) {
connection.send(messageQueue.poll());
}
} else {
StatusActivity.addMessage(context.getString(R.string.status_send_fail));
delayedReconnect();
}
}
}
-157
Просмотреть файл
@@ -1,157 +0,0 @@
/*
* Copyright 2012 - 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.io.Closeable;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import android.os.AsyncTask;
import android.util.Log;
/**
* Asynchronous connection
*
* All methods should be called from UI thread only.
*/
public class Connection implements Closeable {
public static final String LOG_TAG = "Traccar.Connection";
public static final int SOCKET_TIMEOUT = 10 * 1000;
/**
* Callback interface
*/
public interface ConnectionHandler {
void onConnected(boolean result);
void onSent(boolean result);
}
private ConnectionHandler handler;
private Socket socket;
private OutputStream socketStream;
private boolean closed;
private boolean busy;
public boolean isClosed() {
return closed;
}
public boolean isBusy() {
return busy;
}
public Connection(ConnectionHandler handler) {
this.handler = handler;
closed = false;
busy = false;
}
public void connect(final String address, final int port) {
busy = true;
new AsyncTask<Void, Void, Boolean>() {
@Override
protected Boolean doInBackground(Void... params) {
try {
socket = new Socket();
socket.connect(new InetSocketAddress(address, port));
socket.setSoTimeout(SOCKET_TIMEOUT);
socketStream = socket.getOutputStream();
return true;
} catch (Exception e) {
Log.w(LOG_TAG, e.getMessage());
return false;
}
}
@Override
protected void onCancelled() {
if (!closed) {
busy = false;
handler.onConnected(false);
}
}
@Override
protected void onPostExecute(Boolean result) {
if (!closed) {
busy = false;
handler.onConnected(result);
}
}
}.execute();
}
public void send(String message) {
busy = true;
new AsyncTask<String, Void, Boolean>() {
@Override
protected Boolean doInBackground(String... params) {
try {
socketStream.write(params[0].getBytes());
socketStream.flush();
return true;
} catch (Exception e) {
Log.w(LOG_TAG, e.getMessage());
return false;
}
}
@Override
protected void onCancelled() {
if (!closed) {
busy = false;
handler.onSent(false);
}
}
@Override
protected void onPostExecute(Boolean result) {
if (!closed) {
busy = false;
handler.onSent(result);
}
}
}.execute(message);
}
@Override
public void close() {
closed = true;
try {
if (socketStream != null) {
socketStream.close();
}
if (socket != null) {
socket.close();
}
} catch (Exception e) {
Log.e(LOG_TAG, e.getMessage());
}
}
}
-136
Просмотреть файл
@@ -1,136 +0,0 @@
/*
* Copyright 2013 - 2014 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);
}
}
}
}
-92
Просмотреть файл
@@ -1,92 +0,0 @@
/*
* Copyright 2012 - 2014 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.Calendar;
import java.util.Formatter;
import java.util.Locale;
import java.util.TimeZone;
import android.location.Location;
/**
* Protocol formatting
*/
public class Protocol {
/**
* Format device id message
*/
public static String createLoginMessage(String id) {
StringBuilder s = new StringBuilder("$PGID,");
Formatter f = new Formatter(s, Locale.ENGLISH);
s.append(id);
byte checksum = 0;
for (byte b : s.substring(1).getBytes()) {
checksum ^= b;
}
f.format("*%02x\r\n", (int) checksum);
f.close();
return s.toString();
}
/**
* Format location message
*/
public static String createLocationMessage(boolean extended, Location l, double battery) {
StringBuilder s = new StringBuilder(extended ? "$TRCCR," : "$GPRMC,");
Formatter f = new Formatter(s, Locale.ENGLISH);
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ENGLISH);
calendar.setTimeInMillis(l.getTime());
if (extended) {
f.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS.%1$tL,A,", calendar);
f.format("%.6f,%.6f,", l.getLatitude(), l.getLongitude());
f.format("%.2f,%.2f,", l.getSpeed() * 1.943844, l.getBearing());
f.format("%.2f,", l.getAltitude());
f.format("%.0f,", battery);
} else {
f.format("%1$tH%1$tM%1$tS.%1$tL,A,", calendar);
double lat = l.getLatitude();
double lon = l.getLongitude();
f.format("%02d%07.4f,%c,", (int) Math.abs(lat), Math.abs(lat) % 1 * 60, lat < 0 ? 'S' : 'N');
f.format("%03d%07.4f,%c,", (int) Math.abs(lon), Math.abs(lon) % 1 * 60, lon < 0 ? 'W' : 'E');
double speed = l.getSpeed() * 1.943844; // speed in knots
f.format("%.2f,%.2f,", speed, l.getBearing());
f.format("%1$td%1$tm%1$ty,,", calendar);
}
byte checksum = 0;
for (byte b : s.substring(1).getBytes()) {
checksum ^= b;
}
f.format("*%02x\r\n", (int) checksum);
f.close();
return s.toString();
}
}
-129
Просмотреть файл
@@ -1,129 +0,0 @@
/*
* Copyright 2012 - 2014 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.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.content.Intent;
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;
import android.view.MenuItem;
/**
* Main user interface
*/
@SuppressWarnings("deprecation")
public class TraccarActivity extends PreferenceActivity {
public static final String LOG_TAG = "traccar";
public static final String KEY_ID = "id";
public static final String KEY_ADDRESS = "address";
public static final String KEY_PORT = "port";
public static final String KEY_INTERVAL = "interval";
public static final String KEY_PROVIDER = "provider";
public static final String KEY_EXTENDED = "extended";
public static final String KEY_STATUS = "status";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
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));
}
} else if (key.equals(KEY_ID)) {
findPreference(KEY_ID).setSummary(sharedPreferences.getString(KEY_ID, null));
}
}
};
@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 false;
}
private void initPreferences() {
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String id = telephonyManager.getDeviceId();
SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
if (!sharedPreferences.contains(KEY_ID)) {
sharedPreferences.edit().putString(KEY_ID, id).commit();
}
findPreference(KEY_ID).setSummary(sharedPreferences.getString(KEY_ID, id));
sharedPreferences.edit().putBoolean(KEY_STATUS, isServiceRunning()).commit();
}
}
-179
Просмотреть файл
@@ -1,179 +0,0 @@
/*
* Copyright 2012 - 2014 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.annotation.TargetApi;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.location.Location;
import android.os.BatteryManager;
import android.os.Build;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.preference.PreferenceManager;
import android.util.Log;
/**
* Background service
*/
public class TraccarService extends Service {
public static final String LOG_TAG = "Traccar.TraccarService";
private String id;
private String address;
private int port;
private int interval;
private String provider;
private boolean extended;
private SharedPreferences sharedPreferences;
private ClientController clientController;
private PositionProvider positionProvider;
private WakeLock wakeLock;
@Override
public void onCreate() {
StatusActivity.addMessage(getString(R.string.status_service_create));
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
wakeLock.acquire();
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
id = sharedPreferences.getString(TraccarActivity.KEY_ID, null);
address = sharedPreferences.getString(TraccarActivity.KEY_ADDRESS, null);
provider = sharedPreferences.getString(TraccarActivity.KEY_PROVIDER, null);
port = Integer.valueOf(sharedPreferences.getString(TraccarActivity.KEY_PORT, null));
interval = Integer.valueOf(sharedPreferences.getString(TraccarActivity.KEY_INTERVAL, null));
extended = sharedPreferences.getBoolean(TraccarActivity.KEY_EXTENDED, false);
} catch (Exception error) {
Log.w(LOG_TAG, error);
}
clientController = new ClientController(this, address, port, Protocol.createLoginMessage(id));
clientController.start();
positionProvider = new PositionProvider(this, provider, interval * 1000, positionListener);
positionProvider.startUpdates();
sharedPreferences.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
StatusActivity.addMessage(getString(R.string.status_service_destroy));
if (sharedPreferences != null) {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
}
if (positionProvider != null) {
positionProvider.stopUpdates();
}
if (clientController != null) {
clientController.stop();
}
wakeLock.release();
}
@TargetApi(Build.VERSION_CODES.ECLAIR)
public double getBatteryLevel() {
if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.ECLAIR) {
Intent batteryIntent = registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);
return (level * 100.0) / scale;
} else {
return 0;
}
}
private PositionProvider.PositionListener positionListener = new PositionProvider.PositionListener() {
@Override
public void onPositionUpdate(Location location) {
if (location != null) {
StatusActivity.addMessage(getString(R.string.status_location_update));
clientController.setNewLocation(Protocol.createLocationMessage(extended, location, getBatteryLevel()));
}
}
};
OnSharedPreferenceChangeListener preferenceChangeListener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
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));
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);
positionProvider.stopUpdates();
positionProvider = new PositionProvider(TraccarService.this, provider, interval * 1000, positionListener);
positionProvider.startUpdates();
} else if (key.equals(TraccarActivity.KEY_EXTENDED)) {
extended = sharedPreferences.getBoolean(TraccarActivity.KEY_EXTENDED, false);
}
} catch (Exception error) {
Log.w(LOG_TAG, error);
}
}
};
}
Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.7 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.7 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 3.6 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 5.3 KiB

-75
Просмотреть файл
@@ -1,75 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="traccar-client-android" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":traccar-client" />
</configuration>
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/classes/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/source/r/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/test/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/test/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/apk" />
<excludeFolder url="file://$MODULE_DIR$/build/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/libs" />
<excludeFolder url="file://$MODULE_DIR$/build/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/res" />
<excludeFolder url="file://$MODULE_DIR$/build/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>