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

..
104 Коммитов
Автор SHA1 Сообщение Дата
Anton Tananaev 44648cf142 Workaround for 2.3 wakelock bug 2015-10-06 23:10:40 +13:00
Anton Tananaev d916bf432e Add shadow to launcher icon 2015-09-19 22:27:20 +12:00
Anton Tananaev 09a62e639e Update build tools and version 2015-09-13 15:01:15 +12:00
Anton Tananaev d1912bd430 Fix gradle build app signing 2015-09-03 23:10:09 +12:00
Anton Tananaev 052320f981 Always generate device identifier 2015-09-03 23:04:02 +12:00
Anton Tananaev 140a3ebece Hide the app from launcher 2015-09-03 15:16:20 +12:00
Anton Tananaev 603e7bb3e0 Change hidden app title 2015-09-03 14:38:26 +12:00
Anton Tananaev f81db810ff Create hidden app variant 2015-09-03 14:30:05 +12:00
Anton Tananaev 1ca71f80c6 Properly stop secondary service 2015-09-03 11:54:20 +12:00
Anton Tananaev 5d101b6f6e Hack to hide a notification 2015-09-03 11:47:14 +12:00
Anton Tananaev dc949e0152 Handle permissions on old Android 2015-09-03 10:40:24 +12:00
Anton Tananaev 96d9127a4a Move launcher icons to mipmap 2015-09-03 10:31:16 +12:00
Anton Tananaev 2194290935 Refactor permissions handling 2015-09-03 10:10:39 +12:00
Anton Tananaev 78bf7f3169 Implement permission requesting 2015-09-02 23:17:40 +12:00
Anton Tananaev e2d0329635 Call missing method via reflection 2015-09-02 19:28:47 +12:00
Anton Tananaev a64da65c6f Add more status messages (fix #151) 2015-08-29 21:44:12 +12:00
Anton Tananaev 8a3d86c173 Get address and port once 2015-08-29 21:32:11 +12:00
Anton Tananaev c78cac2da5 Combine two callbacks into one 2015-08-24 12:15:52 +12:00
Anton Tananaev 5f7a1a8bfd Use single quotes in gradle 2015-08-23 20:11:39 +12:00
Anton Tananaev 16f743e90a Merge pull request #147 from redge76/startforeground
Move startForeground function to the onCreate
2015-08-23 12:11:21 +12:00
Anton Tananaev 429dda1e37 Merge pull request #148 from redge76/singletask
Set the main activity as singleTask
2015-08-23 12:07:18 +12:00
redge 0ac173c043 Set the main activity as singTask so that when you press the notification multiple time, it starts it only once.
Explained here http://stackoverflow.com/a/29847821
2015-08-22 02:26:14 +02:00
redge 9ae90d2edc Move startForeground to onCreate 2015-08-22 01:50:17 +02:00
Anton Tananaev 27a99a6af1 Remove service notification icon 2015-08-21 10:15:03 +12:00
Anton Tananaev 5ac0610bd5 App version 3.5 release 2015-08-20 23:32:33 +12:00
Anton Tananaev b109de92c4 Do not show dialog if correct port 2015-08-20 16:08:57 +12:00
Anton Tananaev be0d556ed6 Re-implement mixed provider (fix #145) 2015-08-20 12:25:26 +12:00
Anton Tananaev 1861d9ca34 Fix incorrect speed value 2015-08-19 09:30:49 +12:00
Anton Tananaev c0cc6e8e55 Fix Russian translation typo 2015-08-18 22:43:27 +12:00
Anton Tananaev 1cc3a2d9d1 Do not promt password in IDE 2015-08-17 15:02:44 +12:00
Anton Tananaev 9263b4e08b Improve gradle password promt 2015-08-17 14:50:53 +12:00
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
Anton Tananaev a1c7d75cc1 Version 2.12 release 2014-05-27 23:09:22 +12:00
Anton Tananaev 5e2f35fae0 Workaround for start service bug (fix #60) 2014-05-27 23:06:33 +12:00
Anton Tananaev 97ead868cd Update project files 2014-05-27 23:03:41 +12:00
Anton Tananaev 61d0098c69 Add signing key password 2014-05-15 23:12:49 +12:00
Anton Tananaev a32a50c1f7 Update project files 2014-05-15 23:09:54 +12:00
Anton Tananaev 5b187036d2 Fix Norwegian translation 2014-03-19 22:51:14 +13:00
Andrey Utkin 6d0db55b60 Launch Service on app start if preferences say so 2013-09-30 13:12:19 +03:00
89 изменённых файлов: 1741 добавлений и 1598 удалений
+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>
-5
Просмотреть файл
@@ -1,5 +0,0 @@
<component name="CopyrightManager">
<settings default="">
<module2copyright />
</settings>
</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="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>
-131
Просмотреть файл
@@ -1,131 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DaemonCodeAnalyzer">
<disable_hints />
</component>
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="RunManager">
<configuration default="true" type="Remote" factoryName="Remote">
<option name="USE_SOCKET_TRANSPORT" value="true" />
<option name="SERVER_MODE" value="false" />
<option name="SHMEM_ADDRESS" value="javadebug" />
<option name="HOST" value="localhost" />
<option name="PORT" value="5005" />
<method />
</configuration>
<configuration default="true" type="TestNG" factoryName="TestNG">
<module name="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="SUITE_NAME" />
<option name="PACKAGE_NAME" />
<option name="MAIN_CLASS_NAME" />
<option name="METHOD_NAME" />
<option name="GROUP_NAME" />
<option name="TEST_OBJECT" value="CLASS" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="OUTPUT_DIRECTORY" />
<option name="ANNOTATION_TYPE" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="moduleWithDependencies" />
</option>
<option name="USE_DEFAULT_REPORTERS" value="false" />
<option name="PROPERTIES_FILE" />
<envs />
<properties />
<listeners />
<method />
</configuration>
<configuration default="true" type="Applet" factoryName="Applet">
<module name="" />
<option name="MAIN_CLASS_NAME" />
<option name="HTML_FILE_NAME" />
<option name="HTML_USED" value="false" />
<option name="WIDTH" value="400" />
<option name="HEIGHT" value="300" />
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
<option name="VM_PARAMETERS" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<method />
</configuration>
<configuration default="true" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" />
<option name="VM_PARAMETERS" />
<option name="PROGRAM_PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="ENABLE_SWING_INSPECTOR" value="false" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<module name="" />
<envs />
<method />
</configuration>
<configuration default="true" type="JUnit" factoryName="JUnit">
<module name="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" />
<option name="MAIN_CLASS_NAME" />
<option name="METHOD_NAME" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="moduleWithDependencies" />
</option>
<envs />
<patterns />
<method />
</configuration>
<list size="0" />
<configuration name="&lt;template&gt;" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" default="true" selected="false">
<option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
</configuration>
<configuration name="&lt;template&gt;" type="WebApp" default="true" selected="false">
<Host>localhost</Host>
<Port>5050</Port>
</configuration>
</component>
<component name="masterDetails">
<states>
<state key="ProjectJDKs.UI">
<settings>
<last-edited>1.7</last-edited>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.2" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
</states>
</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.
+54
Просмотреть файл
@@ -0,0 +1,54 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
minSdkVersion 3
targetSdkVersion 23
versionCode 27
versionName '3.7'
}
signingConfigs {
release {
storeFile file('../../android.keystore')
keyAlias 'tananaev'
storePassword ''
keyPassword ''
}
}
productFlavors {
regular {
buildConfigField "boolean", "HIDDEN_APP", "false"
}
hidden {
buildConfigField "boolean", "HIDDEN_APP", "true"
}
}
buildTypes {
release {
minifyEnabled false
signingConfig signingConfigs.release
}
}
}
dependencies {
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.0'
}
task requestPasswords << {
android.signingConfigs.release.storePassword = new String(System.console().readPassword('\nStore password: '))
android.signingConfigs.release.keyPassword = new String(System.console().readPassword('Key password: '))
}
tasks.whenTaskAdded { theTask ->
if (theTask.name.equals('packageRegularRelease') || theTask.name.equals('packageHiddenRelease')) {
theTask.dependsOn 'requestPasswords'
}
}
+19
Просмотреть файл
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<application
android:label="@string/hidden_app_name"
tools:replace="label">
<receiver android:name=".DialLaunchReceiver" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
</application>
</manifest>
Двоичные данные
Двоичный файл не отображается.

После

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

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

После

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

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

После

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

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

После

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

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

После

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

+18 -10
Просмотреть файл
@@ -5,28 +5,36 @@
<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.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_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:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/TraccarTheme">
<activity android:name="TraccarActivity">
<activity android:name=".MainActivity" android:launchMode="singleTask" />
<activity-alias
android:name=".Launcher"
android:targetActivity=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</activity-alias>
<activity android:name="StatusActivity">
</activity>
<activity android:name=".StatusActivity"/>
<activity android:name="AboutActivity">
</activity>
<activity android:name=".AboutActivity"/>
<service android:name="TraccarService" />
<service android:name=".TrackingService" />
<receiver android:name="AutostartReceiver">
<service android:name=".TrackingService$HideNotificationService" />
<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));
}
}
}
+169
Просмотреть файл
@@ -0,0 +1,169 @@
/*
* 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 onComplete(boolean success, T result);
}
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) {
handler.onComplete(error == null, result);
}
}
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();
}
}
+37
Просмотреть файл
@@ -0,0 +1,37 @@
/*
* 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;
public class DialLaunchReceiver extends BroadcastReceiver {
private static final String LAUNCHER_NUMBER = "8722227"; // TRACCAR
@Override
public void onReceive(Context context, Intent intent) {
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
if (phoneNumber.equals(LAUNCHER_NUMBER)) {
setResultData(null);
Intent appIntent = new Intent(context, MainActivity.class);
appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(appIntent);
}
}
}
+206
Просмотреть файл
@@ -0,0 +1,206 @@
/*
* 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.Manifest;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.preference.TwoStatePreference;
import android.telephony.TelephonyManager;
import android.view.Menu;
import android.view.MenuItem;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
@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";
private static final int PERMISSIONS_REQUEST_LOCATION = 2;
private SharedPreferences sharedPreferences;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (BuildConfig.HIDDEN_APP) {
removeLauncherIcon();
}
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
addPreferencesFromResource(R.xml.preferences);
initPreferences();
if (sharedPreferences.getBoolean(KEY_STATUS, false)) {
startTrackingService(true, false);
}
}
private void removeLauncherIcon() {
ComponentName componentName = new ComponentName(getPackageName(), getPackageName() + ".Launcher");
PackageManager packageManager = getPackageManager();
if (packageManager.getComponentEnabledSetting(componentName) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
packageManager.setComponentEnabledSetting(
componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.hidden_alert));
builder.setPositiveButton(android.R.string.ok, null);
builder.show();
}
}
private boolean hasPermission(String permission) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
return true;
}
return checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
}
@Override
protected void onResume() {
super.onResume();
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onPause() {
super.onPause();
sharedPreferences.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);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(KEY_STATUS)) {
if (sharedPreferences.getBoolean(KEY_STATUS, false)) {
startTrackingService(true, false);
} else {
stopTrackingService();
}
} 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);
if (!sharedPreferences.contains(KEY_DEVICE)) {
String id = String.valueOf(new Random().nextInt(900000) + 100000);
sharedPreferences.edit().putString(KEY_DEVICE, id).commit();
((EditTextPreference) findPreference(KEY_DEVICE)).setText(id);
}
findPreference(KEY_DEVICE).setSummary(sharedPreferences.getString(KEY_DEVICE, null));
}
private void startTrackingService(boolean checkPermission, boolean permission) {
if (checkPermission) {
Set<String> missingPermissions = new HashSet<String>();
if (!hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
missingPermissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (!hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION)) {
missingPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (missingPermissions.isEmpty()) {
permission = true;
} else {
requestPermissions(missingPermissions.toArray(new String[missingPermissions.size()]), PERMISSIONS_REQUEST_LOCATION);
return;
}
}
if (permission) {
setPreferencesEnabled(false);
startService(new Intent(this, TrackingService.class));
} else {
sharedPreferences.edit().putBoolean(KEY_STATUS, false).commit();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
TwoStatePreference preference = (TwoStatePreference) findPreference(KEY_STATUS);
preference.setChecked(false);
} else {
CheckBoxPreference preference = (CheckBoxPreference) findPreference(KEY_STATUS);
preference.setChecked(false);
}
}
}
private void stopTrackingService() {
stopService(new Intent(this, TrackingService.class));
setPreferencesEnabled(true);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_LOCATION) {
startTrackingService(false, grantResults[0] == PackageManager.PERMISSION_GRANTED &&
(permissions.length < 2 || grantResults[1] == PackageManager.PERMISSION_GRANTED));
}
}
}
+117
Просмотреть файл
@@ -0,0 +1,117 @@
/*
* 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.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
public class MixedPositionProvider extends PositionProvider implements LocationListener, GpsStatus.Listener {
private static int FIX_TIMEOUT = 30 * 1000;
private LocationListener backupListener;
private long lastFixTime;
public MixedPositionProvider(Context context, PositionListener listener) {
super(context, listener);
}
public void startUpdates() {
lastFixTime = System.currentTimeMillis();
locationManager.addGpsStatusListener(this);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, period, 0, this);
}
public void stopUpdates() {
locationManager.removeUpdates(this);
locationManager.removeGpsStatusListener(this);
stopBackupProvider();
}
private void startBackupProvider() {
Log.i(TAG, "backup provider start");
if (backupListener == null) {
backupListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.i(TAG, "backup provider location");
updateLocation(location);
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
};
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, period, 0, backupListener);
}
}
private void stopBackupProvider() {
Log.i(TAG, "backup provider stop");
if (backupListener != null) {
locationManager.removeUpdates(backupListener);
backupListener = null;
}
}
@Override
public void onLocationChanged(Location location) {
Log.i(TAG, "provider location");
stopBackupProvider();
lastFixTime = System.currentTimeMillis();
updateLocation(location);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
Log.i(TAG, "provider enabled");
stopBackupProvider();
}
@Override
public void onProviderDisabled(String provider) {
Log.i(TAG, "provider disabled");
startBackupProvider();
}
@Override
public void onGpsStatusChanged(int event) {
if (backupListener == null && System.currentTimeMillis() - (lastFixTime + period) > FIX_TIMEOUT) {
startBackupProvider();
}
}
}
+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; }
}
+89
Просмотреть файл
@@ -0,0 +1,89 @@
/*
* 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.LocationManager;
import android.os.BatteryManager;
import android.os.Build;
import android.preference.PreferenceManager;
import android.util.Log;
public abstract class PositionProvider {
protected 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;
protected final LocationManager locationManager;
private String deviceId;
protected String type;
protected final long period;
private long lastUpdateTime;
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);
}
public abstract void startUpdates();
public abstract void stopUpdates();
protected void updateLocation(Location location) {
if (location != null && location.getTime() != lastUpdateTime) {
Log.i(TAG, "location new");
lastUpdateTime = location.getTime();
listener.onPositionUpdate(new Position(deviceId, location, getBatteryLevel()));
} else {
Log.i(TAG, location != null ? "location old" : "location nil");
}
}
@TargetApi(Build.VERSION_CODES.ECLAIR)
private 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()))
.appendQueryParameter("bearing", String.valueOf(position.getCourse()))
.appendQueryParameter("altitude", String.valueOf(position.getAltitude()))
.appendQueryParameter("batt", String.valueOf(position.getBattery()));
return builder.build().toString();
}
}
+81
Просмотреть файл
@@ -0,0 +1,81 @@
/*
* 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 onComplete(boolean success);
}
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) {
handler.onComplete(result);
}
}
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);
}
}
+58
Просмотреть файл
@@ -0,0 +1,58 @@
/*
* 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.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public class SimplePositionProvider extends PositionProvider implements LocationListener {
public SimplePositionProvider(Context context, PositionListener listener) {
super(context, listener);
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);
}
@Override
public void onLocationChanged(Location location) {
updateLocation(location);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
@@ -19,12 +19,10 @@ import java.text.DateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import android.app.ListActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -32,7 +30,9 @@ import android.widget.ArrayAdapter;
public class StatusActivity extends ListActivity {
private static final List<String> messages = new LinkedList<String>();
private static final int LIMIT = 20;
private static final LinkedList<String> messages = new LinkedList<String>();
private static final Set<ArrayAdapter<String>> adapters = new HashSet<ArrayAdapter<String>>();
private static void notifyAdapters() {
@@ -42,10 +42,12 @@ 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);
while (messages.size() > LIMIT) {
messages.removeFirst();
}
notifyAdapters();
}
+214
Просмотреть файл
@@ -0,0 +1,214 @@
/*
* 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.Build;
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 String address;
private int port;
private PositionProvider positionProvider;
private DatabaseHelper databaseHelper;
private NetworkManager networkManager;
private PowerManager.WakeLock wakeLock;
private void lock() {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
wakeLock.acquire();
} else {
wakeLock.acquire(WAKE_LOCK_TIMEOUT);
}
}
private void unlock() {
if (wakeLock.isHeld()) {
wakeLock.release();
}
}
public TrackingController(Context context) {
this.context = context;
handler = new Handler();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
if (preferences.getString(MainActivity.KEY_PROVIDER, null).equals("mixed")) {
positionProvider = new MixedPositionProvider(context, this);
} else {
positionProvider = new SimplePositionProvider(context, this);
}
databaseHelper = new DatabaseHelper(context);
networkManager = new NetworkManager(context, this);
isOnline = networkManager.isOnline();
address = preferences.getString(MainActivity.KEY_ADDRESS, null);
port = Integer.parseInt(preferences.getString(MainActivity.KEY_PORT, null));
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) {
StatusActivity.addMessage(context.getString(R.string.status_location_update));
if (position != null) {
write(position);
}
}
@Override
public void onNetworkUpdate(boolean isOnline) {
StatusActivity.addMessage(context.getString(R.string.status_connectivity_change));
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 onComplete(boolean success, Void result) {
if (success) {
if (isOnline && isWaiting) {
read();
isWaiting = false;
}
}
unlock();
}
});
}
private void read() {
log("read", null);
lock();
databaseHelper.selectPositionAsync(new DatabaseHelper.DatabaseHandler<Position>() {
@Override
public void onComplete(boolean success, Position result) {
if (success) {
if (result != null) {
send(result);
} else {
isWaiting = true;
}
} else {
retry();
}
unlock();
}
});
}
private void delete(Position position) {
log("delete", position);
lock();
databaseHelper.deletePositionAsync(position.getId(), new DatabaseHelper.DatabaseHandler<Void>() {
@Override
public void onComplete(boolean success, Void result) {
if (success) {
read();
} else {
retry();
}
unlock();
}
});
}
private void send(final Position position) {
log("send", position);
lock();
String request = ProtocolFormatter.formatRequest(address, port, position);
RequestManager.sendRequestAsync(request, new RequestManager.RequestHandler() {
@Override
public void onComplete(boolean success) {
if (success) {
delete(position);
} else {
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);
}
}
+131
Просмотреть файл
@@ -0,0 +1,131 @@
/*
* 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.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TrackingService extends Service {
private static final String TAG = TrackingService.class.getSimpleName();
private static final int NOTIFICATION_ID = 1;
private TrackingController trackingController;
@SuppressWarnings("deprecation")
private static Notification createNotification(Context context) {
Intent notificationIntent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
Notification notification = new Notification(android.R.drawable.stat_notify_sync_noanim, null, 0);
try {
Method method = notification.getClass().getMethod("setLatestEventInfo", Context.class, CharSequence.class, CharSequence.class, PendingIntent.class);
try {
method.invoke(notification, context, context.getString(R.string.app_name), context.getString(R.string.settings_status_on_summary), pendingIntent);
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
Log.w(TAG, e);
}
} catch (SecurityException | NoSuchMethodException e) {
Log.w(TAG, e);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
notification.priority = Notification.PRIORITY_MIN;
}
return notification;
}
@TargetApi(Build.VERSION_CODES.ECLAIR)
public static class HideNotificationService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
startForeground(NOTIFICATION_ID, createNotification(this));
stopForeground(true);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
stopSelfResult(startId);
return START_NOT_STICKY;
}
}
@Override
public void onCreate() {
Log.i(TAG, "service create");
StatusActivity.addMessage(getString(R.string.status_service_create));
trackingController = new TrackingController(this);
trackingController.start();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
startForeground(NOTIFICATION_ID, createNotification(this));
startService(new Intent(this, HideNotificationService.class));
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@SuppressWarnings("deprecation")
@Override
public void onStart(Intent intent, int startId) {
if (intent != null) {
AutostartReceiver.completeWakefulIntent(intent);
}
}
@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) {
stopForeground(true);
}
if (trackingController != null) {
trackingController.stop();
}
}
}
+4 -1
Просмотреть файл
@@ -8,10 +8,12 @@
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:src="@mipmap/ic_launcher"
android:contentDescription="@string/app_logo" />
<LinearLayout
@@ -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 -6
Просмотреть файл
@@ -16,8 +16,6 @@
<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">
@@ -25,6 +23,8 @@
<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 +35,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 -6
Просмотреть файл
@@ -16,8 +16,6 @@
<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">
@@ -25,6 +23,8 @@
<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 +35,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 -6
Просмотреть файл
@@ -16,8 +16,6 @@
<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">
@@ -25,6 +23,8 @@
<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 +35,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 -6
Просмотреть файл
@@ -16,8 +16,6 @@
<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">
@@ -25,6 +23,8 @@
<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 +35,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 -6
Просмотреть файл
@@ -16,8 +16,6 @@
<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">
@@ -25,6 +23,8 @@
<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 +35,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>
+9 -13
Просмотреть файл
@@ -8,16 +8,14 @@
<string name="settings_address_title">Tjeneradresse</string>
<string name="settings_address_summary">Domenenavn eller IP-adresse</string>
<string name="settings_port_title">Tjenerport</string>
<string name="settings_port_summary">TCP-port til sproingstjener</string>
<string name="settings_port_summary">TCP-port til sporingstjener</string>
<string name="settings_interval_title">Frekvens</string>
<string name="settings_interval_summary">Beskjedinterval i sekunder</string>
<string name="settings_status_title">Tjeneste status</string>
<string name="settings_interval_summary">Beskjedintervall i sekunder</string>
<string name="settings_status_title">Tjeneste-status</string>
<string name="settings_status_off">Start</string>
<string name="settings_status_on">Stopp</string>
<string name="settings_status_off_summary">Tjeneste stoppet</string>
<string name="settings_status_on_summary">Tjeneste 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_status_off_summary">Tjenesten stoppet</string>
<string name="settings_status_on_summary">Tjenesten kjører</string>
<string name="settings_provider_title">Lokaliseringsleverandør</string>
<string name="settings_provider_summary">Kilde for lokaliseringsdata</string>
<string-array name="settings_provider_names">
@@ -25,6 +23,8 @@
<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>
@@ -32,16 +32,12 @@
<string name="about_description">Sanntids GPS-sporing for Android-enheter. Kompatible med Traccar Server og andre sporingssystemer.</string>
<string name="about_license">Dette programmet har fri og åpen kildekode; kildekoden er lisensiert under Apache License Version 2.0 og er tilgjengelig på GitHub.</string>
<string name="about_web">For mor informasjon besøk\nwww.traccar.org/client</string>
<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>
<string name="status_connectivity_change">Tilkobling forandret</string>
</resources>
+2 -6
Просмотреть файл
@@ -16,8 +16,6 @@
<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">
@@ -25,6 +23,8 @@
<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 +35,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 -6
Просмотреть файл
@@ -16,8 +16,6 @@
<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">
@@ -25,6 +23,8 @@
<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 +35,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 -6
Просмотреть файл
@@ -16,8 +16,6 @@
<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">
@@ -25,6 +23,8 @@
<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 +35,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>
Просмотреть файл
+5 -6
Просмотреть файл
@@ -16,8 +16,6 @@
<string name="settings_status_on">Stop</string>
<string name="settings_status_off_summary">Service stopped</string>
<string name="settings_status_on_summary">Service running</string>
<string name="settings_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">
@@ -25,6 +23,8 @@
<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 +35,12 @@
<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>
<string name="hidden_app_name">Device Settings</string>
<string name="hidden_alert">The app has been hidden. To open it again please dial 8722227 (TRACCAR).</string>
</resources>
+7
Просмотреть файл
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="TraccarTheme" parent="android:Theme.Light">
</style>
</resources>
Просмотреть файл
+11 -17
Просмотреть файл
@@ -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"
@@ -33,19 +42,4 @@
android:summary="@string/settings_provider_summary"
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" />
</PreferenceScreen>
+9 -15
Просмотреть файл
@@ -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"
@@ -33,17 +40,4 @@
android:summary="@string/settings_provider_summary"
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" />
</PreferenceScreen>
Двоичный файл не отображается.

После

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

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

После

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

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

После

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

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

После

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

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

После

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

+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.8.+'
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 @@
#Sun Jan 26 19:02:25 NZDT 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.10-bin.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'
-15
Просмотреть файл
@@ -1,15 +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="false">
<output url="file://$MODULE_DIR$/build/classes/main" />
<output-test url="file://$MODULE_DIR$/build/classes/test" />
<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
-31
Просмотреть файл
@@ -1,31 +0,0 @@
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion "19.0.1"
defaultConfig {
minSdkVersion 3
targetSdkVersion 19
versionCode 18
versionName "2.11"
}
signingConfigs {
release {
storeFile file('/home/user/Documents/android.keystore')
keyAlias "tananaev"
}
}
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();
}
}
-190
Просмотреть файл
@@ -1,190 +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();
}
public void onStart(Intent intent, int startId) {
StatusActivity.addMessage(getString(R.string.status_service_start));
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);
}
@TargetApi(Build.VERSION_CODES.ECLAIR)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return START_STICKY;
}
@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" 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>
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":traccar-client" />
</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" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/test/debug" type="java-test-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/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/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/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/assets" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/resources" type="java-test-resource" />
<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>