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

..
37 Коммитов
Автор SHA1 Сообщение Дата
Anton Tananaev 235e58d3e2 Fix translation issues 2022-10-21 08:50:43 -07:00
Anton Tananaev 9cdb10db14 Update localization 2022-10-21 08:49:00 -07:00
Anton Tananaev 745a8523ef Update project 2022-10-21 08:17:05 -07:00
Anton Tananaev a2b2c215da Handle GPS rollover (fix #414) 2022-10-21 07:38:43 -07:00
Anton Tananaev 6d1c7b47e1 Fix Google flavor 2022-08-15 18:12:27 -07:00
Anton Tananaev 10bc96caf9 Fix typo 2022-08-14 17:38:34 -07:00
Anton Tananaev 0873aa7302 Add charging status 2022-08-14 17:28:44 -07:00
Anton Tananaev 37d3584f77 Handle deprecation 2022-08-14 17:02:22 -07:00
Anton Tananaev 404886f80e Update project files 2022-08-14 16:57:14 -07:00
Anton Tananaev a68b489681 Merge pull request #434 from aguerraVikua/master
Upgrade dependencies
2022-07-28 15:38:56 -07:00
Antonio Guerra 04e5b01cc7 ⬆️Upgrade dependencies 2022-07-19 21:31:48 -04:00
Anton Tananaev 5f059645a1 Update project 2022-05-29 10:50:11 -07:00
Anton Tananaev 8b985526dd Update version number 2022-01-30 10:18:36 -08:00
Anton Tananaev 5e8ea134e0 Attempt at fixing crashes 2022-01-30 10:18:09 -08:00
Anton Tananaev ec85edd56f Update version number 2021-11-04 19:21:19 -07:00
Anton Tananaev c5ab10919e Update dependencies 2021-11-04 19:20:08 -07:00
Anton Tananaev 3e8ba9a603 Fix Android 11 location permissions 2021-11-04 19:18:09 -07:00
Anton Tananaev 826d638ea3 Update version number 2021-10-11 23:26:51 -07:00
Anton Tananaev 1b687bd075 Handle security exception 2021-10-11 23:26:28 -07:00
Anton Tananaev 42d5584d8d Fix hidden app 2021-10-09 17:59:58 -07:00
Anton Tananaev ff88682e40 Update app version 2021-10-09 17:41:18 -07:00
Anton Tananaev 307e692459 Integrate DKMA info 2021-10-09 17:40:27 -07:00
Anton Tananaev b7ec644ecf Improve app autostart 2021-10-09 17:40:27 -07:00
Anton Tananaev 842baa2aec Merge pull request #427 from scfarley/master
Accept user CA's for connections via HTTPS proxy
2021-09-12 18:25:32 -07:00
Sean Farley 26bc92cf8e Accept user CA's for connections via HTTPS proxy
Permit Traccar client to communicate with the Traccar server via an
HTTPS proxy that uses a certificate generated from a user (non-system)
CA.
2021-09-12 21:02:20 -04:00
Anton Tananaev 6dadf5e7c3 Update project files 2021-08-29 22:13:52 -07:00
Anton Tananaev 39e9c171c4 Handle battery optimization exception 2021-08-29 18:17:31 -07:00
Anton Tananaev bcb5985cef Alarm foreground priority 2021-08-29 15:55:52 -07:00
Anton Tananaev eb868056bf Change alarm flag 2021-07-31 07:37:47 -10:00
Anton Tananaev 94e094e648 Update app version 2021-07-24 11:24:26 -07:00
Anton Tananaev 25c0434e4c Fix database management 2021-07-24 11:23:58 -07:00
Anton Tananaev 3afcfa17d0 Update version number 2021-07-20 23:12:26 -07:00
Anton Tananaev 02263d5fd9 Fix crash 2021-07-20 23:12:04 -07:00
Anton Tananaev a884b2f3d7 Reorder dependencies 2021-07-19 20:26:42 -07:00
Anton Tananaev 6910790fa7 Specify location services version 2021-07-19 20:17:53 -07:00
Anton Tananaev 6cab1a0b36 Update Firebase 2021-07-19 20:14:15 -07:00
Anton Tananaev edd4f670fe Remove unused 2021-07-19 20:03:06 -07:00
42 изменённых файлов: 626 добавлений и 150 удалений
+26 -24
Просмотреть файл
@@ -2,29 +2,23 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
android { android {
compileSdkVersion 30 compileSdkVersion 33
defaultConfig { defaultConfig {
applicationId 'org.traccar.client' applicationId 'org.traccar.client'
buildConfigField 'boolean', 'HIDDEN_APP', 'false' buildConfigField 'boolean', 'HIDDEN_APP', 'false'
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 30 targetSdkVersion 33
versionCode 69 versionCode 79
versionName '6.8' versionName '6.18'
multiDexEnabled true multiDexEnabled true
} }
namespace 'org.traccar.client'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions { packagingOptions {
exclude 'META-INF/DEPENDENCIES' resources {
} excludes += ['META-INF/DEPENDENCIES']
}
lintOptions {
checkReleaseBuilds false
} }
flavorDimensions 'default' flavorDimensions 'default'
@@ -44,22 +38,30 @@ android {
includeAndroidResources = true includeAndroidResources = true
} }
} }
lint {
checkReleaseBuilds false
}
} }
dependencies { dependencies {
implementation 'com.google.android.material:material:1.5.0-alpha01' implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.preference:preference-ktx:1.1.1' implementation 'androidx.preference:preference-ktx:1.2.0'
implementation 'androidx.test:core-ktx:1.4.0' implementation 'androidx.test:core-ktx:1.4.0'
testImplementation 'junit:junit:4.13.2' implementation 'androidx.core:core-ktx:1.9.0'
testImplementation 'org.robolectric:robolectric:4.1'
googleImplementation 'com.google.firebase:firebase-core:19.0.0'
googleImplementation 'com.google.firebase:firebase-crashlytics-gradle:2.7.1'
googleImplementation 'com.google.firebase:firebase-analytics:19.0.0'
googleImplementation 'com.google.android.gms:play-services-location:18.0.0'
googleImplementation 'com.google.android.play:core:1.10.0'
implementation "androidx.core:core-ktx:1.6.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.github.judemanutd:autostarter:1.1.0'
implementation('dev.doubledot.doki:library:0.0.1@aar') {
transitive = true
}
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.robolectric:robolectric:4.7.3'
googleImplementation platform('com.google.firebase:firebase-bom:28.2.1')
googleImplementation 'com.google.firebase:firebase-core'
googleImplementation 'com.google.firebase:firebase-analytics'
googleImplementation 'com.google.firebase:firebase-crashlytics'
googleImplementation 'com.google.android.gms:play-services-location:21.0.0'
googleImplementation 'com.google.android.play:core:1.10.3'
} }
if (getGradle().getStartParameter().getTaskRequests().toString().contains('Google')) { if (getGradle().getStartParameter().getTaskRequests().toString().contains('Google')) {
+1 -1
Просмотреть файл
@@ -43,7 +43,7 @@ class GooglePositionProvider(context: Context, listener: PositionListener) : Pos
override fun requestSingleLocation() { override fun requestSingleLocation() {
fusedLocationClient.lastLocation.addOnSuccessListener { location -> fusedLocationClient.lastLocation.addOnSuccessListener { location ->
if (location != null) { if (location != null) {
listener.onPositionUpdate(Position(deviceId, location, getBatteryLevel(context))) listener.onPositionUpdate(Position(deviceId, location, getBatteryStatus(context)))
} }
} }
} }
+5 -2
Просмотреть файл
@@ -9,7 +9,8 @@
tools:replace="android:label"> tools:replace="android:label">
<activity <activity
android:name="org.traccar.client.MainActivity"> android:name="org.traccar.client.MainActivity"
android:exported="true">
<intent-filter android:label="@string/app_name"> <intent-filter android:label="@string/app_name">
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
@@ -18,7 +19,9 @@
</intent-filter> </intent-filter>
</activity> </activity>
<receiver android:name="org.traccar.client.DialLaunchReceiver" > <receiver
android:name="org.traccar.client.DialLaunchReceiver"
android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" /> <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter> </intent-filter>
+18 -6
Просмотреть файл
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest <manifest
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools">
package="org.traccar.client">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_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.RECEIVE_BOOT_COMPLETED" />
@@ -13,6 +13,9 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /> <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="oppo.permission.OPPO_COMPONENT_SAFE" />
<uses-permission android:name="com.huawei.permission.external_app_settings.USE_COMPONENT" />
<uses-feature android:name="android.hardware.location.network" /> <uses-feature android:name="android.hardware.location.network" />
<uses-feature android:name="android.hardware.location.gps" /> <uses-feature android:name="android.hardware.location.gps" />
@@ -23,7 +26,7 @@
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
android:name=".MainApplication" android:name=".MainApplication"
tools:ignore="GoogleAppIndexingWarning"> tools:ignore="GoogleAppIndexingWarning,UnusedAttribute">
<meta-data <meta-data
android:name="google_analytics_adid_collection_enabled" android:name="google_analytics_adid_collection_enabled"
@@ -31,10 +34,12 @@
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTask" /> android:launchMode="singleTask" />
<activity-alias <activity-alias
android:name=".Launcher" android:name=".Launcher"
android:exported="true"
android:targetActivity=".MainActivity"> android:targetActivity=".MainActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -45,10 +50,13 @@
android:resource="@xml/shortcuts" /> android:resource="@xml/shortcuts" />
</activity-alias> </activity-alias>
<activity android:name=".StatusActivity"/> <activity
android:name=".StatusActivity"
android:exported="false" />
<activity <activity
android:name=".ShortcutActivity" android:name=".ShortcutActivity"
android:exported="true"
android:label="@string/menu_shortcuts"> android:label="@string/menu_shortcuts">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -58,12 +66,16 @@
<service <service
android:name=".TrackingService" android:name=".TrackingService"
android:exported="false"
android:foregroundServiceType="location" /> android:foregroundServiceType="location" />
<service <service
android:name=".TrackingService$HideNotificationService" /> android:name=".TrackingService$HideNotificationService"
android:exported="false" />
<receiver android:name=".AutostartReceiver"> <receiver
android:name=".AutostartReceiver"
android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter> </intent-filter>
+2 -2
Просмотреть файл
@@ -47,11 +47,11 @@ class AndroidPositionProvider(context: Context, listener: PositionListener) : Po
try { try {
val location = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER) val location = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER)
if (location != null) { if (location != null) {
listener.onPositionUpdate(Position(deviceId, location, getBatteryLevel(context))) listener.onPositionUpdate(Position(deviceId, location, getBatteryStatus(context)))
} else { } else {
locationManager.requestSingleUpdate(provider, object : LocationListener { locationManager.requestSingleUpdate(provider, object : LocationListener {
override fun onLocationChanged(location: Location) { override fun onLocationChanged(location: Location) {
listener.onPositionUpdate(Position(deviceId, location, getBatteryLevel(context))) listener.onPositionUpdate(Position(deviceId, location, getBatteryStatus(context)))
} }
override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {} override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
+102
Просмотреть файл
@@ -0,0 +1,102 @@
/*
* Copyright 2021 Anton Tananaev (anton@traccar.org)
*
* 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.ActivityNotFoundException
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import androidx.appcompat.app.AlertDialog
import androidx.preference.PreferenceManager
import com.judemanutd.autostarter.AutoStartPermissionHelper
class BatteryOptimizationHelper {
private fun showDialog(context: Context, onSuccess: () -> Unit) {
val builder = AlertDialog.Builder(context)
builder.setMessage(context.getString(R.string.request_exception))
builder.setPositiveButton(android.R.string.ok) { _, _ -> onSuccess() }
builder.setNegativeButton(android.R.string.cancel, null)
builder.show()
}
private fun requestVendorException(context: Context) {
val vendorIntentList = listOf(
Intent().setComponent(ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")),
Intent().setComponent(ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity")),
Intent().setComponent(ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity")),
Intent().setComponent(ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")),
Intent().setComponent(ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity")),
Intent().setComponent(ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity")),
Intent().setComponent(ComponentName("com.coloros.safecenter", "com.coloros.safecenter.startupapp.StartupAppListActivity")),
Intent().setComponent(ComponentName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity")),
Intent().setComponent(ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity")),
Intent().setComponent(ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.BgStartUpManager")),
Intent().setComponent(ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity")),
Intent().setComponent(ComponentName("com.samsung.android.lool", "com.samsung.android.sm.ui.battery.BatteryActivity")),
Intent().setComponent(ComponentName("com.htc.pitroad", "com.htc.pitroad.landingpage.activity.LandingPageActivity")),
Intent().setComponent(ComponentName("com.asus.mobilemanager", "com.asus.mobilemanager.MainActivity")),
)
for (vendorIntent in vendorIntentList) {
if (context.packageManager.resolveActivity(vendorIntent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
try {
context.startActivity(vendorIntent)
return
} catch (e: Exception) {
continue
}
}
}
}
fun requestException(context: Context): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
if (!sharedPreferences.getBoolean(KEY_EXCEPTION_REQUESTED, false)) {
sharedPreferences.edit().putBoolean(KEY_EXCEPTION_REQUESTED, true).apply()
val powerManager = context.getSystemService(PowerManager::class.java)
if (!powerManager.isIgnoringBatteryOptimizations(context.packageName)) {
showDialog(context) {
try {
context.startActivity(Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS))
} catch (e: ActivityNotFoundException) {
requestVendorException(context)
}
}
return true
}
} else if (!sharedPreferences.getBoolean(KEY_AUTOSTART_REQUESTED, false)) {
sharedPreferences.edit().putBoolean(KEY_AUTOSTART_REQUESTED, true).apply()
try {
if (AutoStartPermissionHelper.getInstance().getAutoStartPermission(context)) {
return true
}
} catch (e: SecurityException) {
}
}
}
return false
}
companion object {
private const val KEY_EXCEPTION_REQUESTED = "exceptionRequested"
private const val KEY_AUTOSTART_REQUESTED = "autostartRequested"
}
}
+21
Просмотреть файл
@@ -0,0 +1,21 @@
/*
* Copyright 2022 Anton Tananaev (anton@traccar.org)
*
* 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
data class BatteryStatus(
val level: Double = 0.0,
val charging: Boolean = false,
)
+11 -6
Просмотреть файл
@@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
@file:Suppress("DEPRECATION", "StaticFieldLeak") @file:Suppress("DEPRECATION", "StaticFieldLeak")
package org.traccar.client package org.traccar.client
import android.annotation.SuppressLint
import android.content.ContentValues import android.content.ContentValues
import android.content.Context import android.content.Context
import android.database.SQLException import android.database.SQLException
@@ -30,7 +31,7 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM
fun onComplete(success: Boolean, result: T) fun onComplete(success: Boolean, result: T)
} }
private abstract class DatabaseAsyncTask<T>(val handler: DatabaseHandler<T>) : AsyncTask<Unit, Unit, T?>() { private abstract class DatabaseAsyncTask<T>(val handler: DatabaseHandler<T?>) : AsyncTask<Unit, Unit, T?>() {
private var error: RuntimeException? = null private var error: RuntimeException? = null
@@ -46,7 +47,7 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM
protected abstract fun executeMethod(): T protected abstract fun executeMethod(): T
override fun onPostExecute(result: T?) { override fun onPostExecute(result: T?) {
result?.let { handler.onComplete(error == null, result) } handler.onComplete(error == null, result)
} }
} }
@@ -65,6 +66,7 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM
"course REAL," + "course REAL," +
"accuracy REAL," + "accuracy REAL," +
"battery REAL," + "battery REAL," +
"charging INTEGER," +
"mock INTEGER)" "mock INTEGER)"
) )
} }
@@ -90,11 +92,12 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM
values.put("course", position.course) values.put("course", position.course)
values.put("accuracy", position.accuracy) values.put("accuracy", position.accuracy)
values.put("battery", position.battery) values.put("battery", position.battery)
values.put("charging", if (position.charging) 1 else 0)
values.put("mock", if (position.mock) 1 else 0) values.put("mock", if (position.mock) 1 else 0)
db.insertOrThrow("position", null, values) db.insertOrThrow("position", null, values)
} }
fun insertPositionAsync(position: Position, handler: DatabaseHandler<Unit>) { fun insertPositionAsync(position: Position, handler: DatabaseHandler<Unit?>) {
object : DatabaseAsyncTask<Unit>(handler) { object : DatabaseAsyncTask<Unit>(handler) {
override fun executeMethod() { override fun executeMethod() {
insertPosition(position) insertPosition(position)
@@ -102,6 +105,7 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM
}.execute() }.execute()
} }
@SuppressLint("Range")
fun selectPosition(): Position? { fun selectPosition(): Position? {
db.rawQuery("SELECT * FROM position ORDER BY id LIMIT 1", null).use { cursor -> db.rawQuery("SELECT * FROM position ORDER BY id LIMIT 1", null).use { cursor ->
if (cursor.count > 0) { if (cursor.count > 0) {
@@ -117,6 +121,7 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM
course = cursor.getDouble(cursor.getColumnIndex("course")), course = cursor.getDouble(cursor.getColumnIndex("course")),
accuracy = cursor.getDouble(cursor.getColumnIndex("accuracy")), accuracy = cursor.getDouble(cursor.getColumnIndex("accuracy")),
battery = cursor.getDouble(cursor.getColumnIndex("battery")), battery = cursor.getDouble(cursor.getColumnIndex("battery")),
charging = cursor.getInt(cursor.getColumnIndex("charging")) > 0,
mock = cursor.getInt(cursor.getColumnIndex("mock")) > 0, mock = cursor.getInt(cursor.getColumnIndex("mock")) > 0,
) )
} }
@@ -138,7 +143,7 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM
} }
} }
fun deletePositionAsync(id: Long, handler: DatabaseHandler<Unit>) { fun deletePositionAsync(id: Long, handler: DatabaseHandler<Unit?>) {
object : DatabaseAsyncTask<Unit>(handler) { object : DatabaseAsyncTask<Unit>(handler) {
override fun executeMethod() { override fun executeMethod() {
deletePosition(id) deletePosition(id)
@@ -147,7 +152,7 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM
} }
companion object { companion object {
const val DATABASE_VERSION = 3 const val DATABASE_VERSION = 4
const val DATABASE_NAME = "traccar.db" const val DATABASE_NAME = "traccar.db"
} }
-5
Просмотреть файл
@@ -24,11 +24,6 @@ import android.graphics.Color
import android.os.Build import android.os.Build
import android.app.Activity import android.app.Activity
import androidx.annotation.NonNull
open class MainApplication : MultiDexApplication() { open class MainApplication : MultiDexApplication() {
override fun onCreate() { override fun onCreate() {
+60 -13
Просмотреть файл
@@ -1,5 +1,5 @@
/* /*
* Copyright 2012 - 2021 Anton Tananaev (anton@traccar.org) * Copyright 2012 - 2022 Anton Tananaev (anton@traccar.org)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -45,6 +45,7 @@ import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.preference.TwoStatePreference import androidx.preference.TwoStatePreference
import dev.doubledot.doki.ui.DokiActivity
import java.util.* import java.util.*
import kotlin.collections.HashSet import kotlin.collections.HashSet
@@ -53,6 +54,7 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
private lateinit var alarmManager: AlarmManager private lateinit var alarmManager: AlarmManager
private lateinit var alarmIntent: PendingIntent private lateinit var alarmIntent: PendingIntent
private var requestingPermissions: Boolean = false
@SuppressLint("UnspecifiedImmutableFlag") @SuppressLint("UnspecifiedImmutableFlag")
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
@@ -60,7 +62,7 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene
removeLauncherIcon() removeLauncherIcon()
} }
setHasOptionsMenu(true) setHasOptionsMenu(true)
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) sharedPreferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
setPreferencesFromResource(R.xml.preferences, rootKey) setPreferencesFromResource(R.xml.preferences, rootKey)
initPreferences() initPreferences()
@@ -90,7 +92,16 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene
findPreference<Preference>(KEY_ANGLE)?.onPreferenceChangeListener = numberValidationListener findPreference<Preference>(KEY_ANGLE)?.onPreferenceChangeListener = numberValidationListener
alarmManager = requireActivity().getSystemService(Context.ALARM_SERVICE) as AlarmManager alarmManager = requireActivity().getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = PendingIntent.getBroadcast(activity, 0, Intent(activity, AutostartReceiver::class.java), 0) val originalIntent = Intent(activity, AutostartReceiver::class.java)
originalIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
} else {
PendingIntent.FLAG_UPDATE_CURRENT
}
alarmIntent = PendingIntent.getBroadcast(activity, 0, originalIntent, flags)
if (sharedPreferences.getBoolean(KEY_STATUS, false)) { if (sharedPreferences.getBoolean(KEY_STATUS, false)) {
startTrackingService(checkPermission = true, initialPermission = false) startTrackingService(checkPermission = true, initialPermission = false)
} }
@@ -115,6 +126,7 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene
} }
} }
@Suppress("DEPRECATION")
override fun onDisplayPreferenceDialog(preference: Preference) { override fun onDisplayPreferenceDialog(preference: Preference) {
if (listOf(KEY_INTERVAL, KEY_DISTANCE, KEY_ANGLE).contains(preference.key)) { if (listOf(KEY_INTERVAL, KEY_DISTANCE, KEY_ANGLE).contains(preference.key)) {
val f: EditTextPreferenceDialogFragmentCompat = val f: EditTextPreferenceDialogFragmentCompat =
@@ -144,6 +156,13 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene
} }
} }
override fun onStart() {
super.onStart()
if (requestingPermissions) {
requestingPermissions = BatteryOptimizationHelper().requestException(requireContext())
}
}
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
sharedPreferences.registerOnSharedPreferenceChangeListener(this) sharedPreferences.registerOnSharedPreferenceChangeListener(this)
@@ -187,12 +206,15 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene
if (item.itemId == R.id.status) { if (item.itemId == R.id.status) {
startActivity(Intent(activity, StatusActivity::class.java)) startActivity(Intent(activity, StatusActivity::class.java))
return true return true
} else if (item.itemId == R.id.info) {
DokiActivity.start(requireContext())
return true
} }
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
} }
private fun initPreferences() { private fun initPreferences() {
PreferenceManager.setDefaultValues(activity, R.xml.preferences, false) PreferenceManager.setDefaultValues(requireActivity(), R.xml.preferences, false)
if (!sharedPreferences.contains(KEY_DEVICE)) { if (!sharedPreferences.contains(KEY_DEVICE)) {
val id = (Random().nextInt(900000) + 100000).toString() val id = (Random().nextInt(900000) + 100000).toString()
sharedPreferences.edit().putString(KEY_DEVICE, id).apply() sharedPreferences.edit().putString(KEY_DEVICE, id).apply()
@@ -201,6 +223,19 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene
findPreference<Preference>(KEY_DEVICE)?.summary = sharedPreferences.getString(KEY_DEVICE, null) findPreference<Preference>(KEY_DEVICE)?.summary = sharedPreferences.getString(KEY_DEVICE, null)
} }
private fun showBackgroundLocationDialog(context: Context, onSuccess: () -> Unit) {
val builder = AlertDialog.Builder(context)
val option = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
context.packageManager.backgroundPermissionOptionLabel
} else {
context.getString(R.string.request_background_option)
}
builder.setMessage(context.getString(R.string.request_background, option))
builder.setPositiveButton(android.R.string.ok) { _, _ -> onSuccess() }
builder.setNegativeButton(android.R.string.cancel, null)
builder.show()
}
private fun startTrackingService(checkPermission: Boolean, initialPermission: Boolean) { private fun startTrackingService(checkPermission: Boolean, initialPermission: Boolean) {
var permission = initialPermission var permission = initialPermission
if (checkPermission) { if (checkPermission) {
@@ -211,10 +246,7 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene
permission = requiredPermissions.isEmpty() permission = requiredPermissions.isEmpty()
if (!permission) { if (!permission) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions( requestPermissions(requiredPermissions.toTypedArray(), PERMISSIONS_REQUEST_LOCATION)
requiredPermissions.toTypedArray(),
PERMISSIONS_REQUEST_LOCATION
)
} }
return return
} }
@@ -222,10 +254,22 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene
if (permission) { if (permission) {
setPreferencesEnabled(false) setPreferencesEnabled(false)
ContextCompat.startForegroundService(requireContext(), Intent(activity, TrackingService::class.java)) ContextCompat.startForegroundService(requireContext(), Intent(activity, TrackingService::class.java))
alarmManager.setInexactRepeating( if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmManager.setInexactRepeating(
ALARM_MANAGER_INTERVAL.toLong(), ALARM_MANAGER_INTERVAL.toLong(), alarmIntent AlarmManager.ELAPSED_REALTIME_WAKEUP,
) ALARM_MANAGER_INTERVAL.toLong(), ALARM_MANAGER_INTERVAL.toLong(), alarmIntent
)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
&& ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestingPermissions = true
showBackgroundLocationDialog(requireContext()) {
requestPermissions(arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION), PERMISSIONS_REQUEST_BACKGROUND_LOCATION)
}
} else {
requestingPermissions = BatteryOptimizationHelper().requestException(requireContext())
}
} else { } else {
sharedPreferences.edit().putBoolean(KEY_STATUS, false).apply() sharedPreferences.edit().putBoolean(KEY_STATUS, false).apply()
val preference = findPreference<TwoStatePreference>(KEY_STATUS) val preference = findPreference<TwoStatePreference>(KEY_STATUS)
@@ -234,7 +278,9 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene
} }
private fun stopTrackingService() { private fun stopTrackingService() {
alarmManager.cancel(alarmIntent) if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
alarmManager.cancel(alarmIntent)
}
requireActivity().stopService(Intent(activity, TrackingService::class.java)) requireActivity().stopService(Intent(activity, TrackingService::class.java))
setPreferencesEnabled(true) setPreferencesEnabled(true)
} }
@@ -278,6 +324,7 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene
const val KEY_BUFFER = "buffer" const val KEY_BUFFER = "buffer"
const val KEY_WAKELOCK = "wakelock" const val KEY_WAKELOCK = "wakelock"
private const val PERMISSIONS_REQUEST_LOCATION = 2 private const val PERMISSIONS_REQUEST_LOCATION = 2
private const val PERMISSIONS_REQUEST_BACKGROUND_LOCATION = 3
} }
} }
+26 -6
Просмотреть файл
@@ -1,5 +1,5 @@
/* /*
* Copyright 2015 - 2021 Anton Tananaev (anton@traccar.org) * Copyright 2015 - 2022 Anton Tananaev (anton@traccar.org)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -31,19 +31,39 @@ data class Position(
val course: Double = 0.0, val course: Double = 0.0,
val accuracy: Double = 0.0, val accuracy: Double = 0.0,
val battery: Double = 0.0, val battery: Double = 0.0,
val charging: Boolean = false,
val mock: Boolean = false, val mock: Boolean = false,
) { ) {
constructor(deviceId: String, location: Location, battery: Double) : this( constructor(deviceId: String, location: Location, battery: BatteryStatus) : this(
deviceId = deviceId, deviceId = deviceId,
time = Date(location.time), time = Date(location.time.correctRollover()),
latitude = location.latitude, latitude = location.latitude,
longitude = location.longitude, longitude = location.longitude,
altitude = location.altitude, altitude = location.altitude,
speed = location.speed * 1.943844, // speed in knots speed = location.speed * 1.943844, // speed in knots
course = location.bearing.toDouble(), course = location.bearing.toDouble(),
accuracy = if (location.provider != null && location.provider != LocationManager.GPS_PROVIDER) location.accuracy.toDouble() else 0.0, accuracy = if (location.provider != null && location.provider != LocationManager.GPS_PROVIDER) {
battery = battery, location.accuracy.toDouble()
mock = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) location.isFromMockProvider else false, } else {
0.0
},
battery = battery.level,
charging = battery.charging,
mock = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
location.isMock
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
@Suppress("DEPRECATION")
location.isFromMockProvider
} else {
false
},
) )
} }
private const val rolloverDate = 1554508800000L // April 6, 2019
private const val rolloverOffset = 619315200000L // 1024 weeks
private fun Long.correctRollover(): Long {
return if (this < rolloverDate) this + rolloverOffset else this
}
+11 -6
Просмотреть файл
@@ -1,5 +1,5 @@
/* /*
* Copyright 2013 - 2021 Anton Tananaev (anton@traccar.org) * Copyright 2013 - 2022 Anton Tananaev (anton@traccar.org)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -47,27 +47,32 @@ abstract class PositionProvider(
abstract fun requestSingleLocation() abstract fun requestSingleLocation()
protected fun processLocation(location: Location?) { protected fun processLocation(location: Location?) {
val lastLocation = this.lastLocation
if (location != null && if (location != null &&
(lastLocation == null || location.time - lastLocation!!.time >= interval || distance > 0 (lastLocation == null || location.time - lastLocation!!.time >= interval || distance > 0
&& location.distanceTo(lastLocation) >= distance || angle > 0 && location.distanceTo(lastLocation) >= distance || angle > 0
&& abs(location.bearing - lastLocation!!.bearing) >= angle) && abs(location.bearing - lastLocation!!.bearing) >= angle)
) { ) {
Log.i(TAG, "location new") Log.i(TAG, "location new")
lastLocation = location this.lastLocation = location
listener.onPositionUpdate(Position(deviceId, location, getBatteryLevel(context))) listener.onPositionUpdate(Position(deviceId, location, getBatteryStatus(context)))
} else { } else {
Log.i(TAG, if (location != null) "location ignored" else "location nil") Log.i(TAG, if (location != null) "location ignored" else "location nil")
} }
} }
protected fun getBatteryLevel(context: Context): Double { protected fun getBatteryStatus(context: Context): BatteryStatus {
val batteryIntent = context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) val batteryIntent = context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
if (batteryIntent != null) { if (batteryIntent != null) {
val level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0) val level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
val scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1) val scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1)
return level * 100.0 / scale val status = batteryIntent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)
return BatteryStatus(
level = level * 100.0 / scale,
charging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL,
)
} }
return 0.0 return BatteryStatus()
} }
companion object { companion object {
+3
Просмотреть файл
@@ -31,6 +31,9 @@ object ProtocolFormatter {
.appendQueryParameter("altitude", position.altitude.toString()) .appendQueryParameter("altitude", position.altitude.toString())
.appendQueryParameter("accuracy", position.accuracy.toString()) .appendQueryParameter("accuracy", position.accuracy.toString())
.appendQueryParameter("batt", position.battery.toString()) .appendQueryParameter("batt", position.battery.toString())
if (position.charging) {
builder.appendQueryParameter("charge", position.charging.toString())
}
if (position.mock) { if (position.mock) {
builder.appendQueryParameter("mock", position.mock.toString()) builder.appendQueryParameter("mock", position.mock.toString())
} }
+4 -4
Просмотреть файл
@@ -104,8 +104,8 @@ class TrackingController(private val context: Context) : PositionListener, Netwo
private fun write(position: Position) { private fun write(position: Position) {
log("write", position) log("write", position)
databaseHelper.insertPositionAsync(position, object : DatabaseHandler<Unit> { databaseHelper.insertPositionAsync(position, object : DatabaseHandler<Unit?> {
override fun onComplete(success: Boolean, result: Unit) { override fun onComplete(success: Boolean, result: Unit?) {
if (success) { if (success) {
if (isOnline && isWaiting) { if (isOnline && isWaiting) {
read() read()
@@ -139,8 +139,8 @@ class TrackingController(private val context: Context) : PositionListener, Netwo
private fun delete(position: Position) { private fun delete(position: Position) {
log("delete", position) log("delete", position)
databaseHelper.deletePositionAsync(position.id, object : DatabaseHandler<Unit> { databaseHelper.deletePositionAsync(position.id, object : DatabaseHandler<Unit?> {
override fun onComplete(success: Boolean, result: Unit) { override fun onComplete(success: Boolean, result: Unit?) {
if (success) { if (success) {
read() read()
} else { } else {
+10 -6
Просмотреть файл
@@ -49,7 +49,7 @@ class TrackingService : Service() {
stopForeground(true) stopForeground(true)
} }
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
stopSelfResult(startId) stopSelfResult(startId)
return START_NOT_STICKY return START_NOT_STICKY
} }
@@ -57,11 +57,10 @@ class TrackingService : Service() {
@SuppressLint("WakelockTimeout") @SuppressLint("WakelockTimeout")
override fun onCreate() { override fun onCreate() {
startForeground(NOTIFICATION_ID, createNotification(this))
Log.i(TAG, "service create") Log.i(TAG, "service create")
sendBroadcast(Intent(ACTION_STARTED)) sendBroadcast(Intent(ACTION_STARTED))
StatusActivity.addMessage(getString(R.string.status_service_create)) StatusActivity.addMessage(getString(R.string.status_service_create))
startForeground(NOTIFICATION_ID, createNotification(this))
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(MainFragment.KEY_WAKELOCK, true)) { if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(MainFragment.KEY_WAKELOCK, true)) {
@@ -83,16 +82,16 @@ class TrackingService : Service() {
} }
@TargetApi(Build.VERSION_CODES.ECLAIR) @TargetApi(Build.VERSION_CODES.ECLAIR)
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
WakefulBroadcastReceiver.completeWakefulIntent(intent) WakefulBroadcastReceiver.completeWakefulIntent(intent)
return START_STICKY return START_STICKY
} }
override fun onDestroy() { override fun onDestroy() {
stopForeground(true)
Log.i(TAG, "service destroy") Log.i(TAG, "service destroy")
sendBroadcast(Intent(ACTION_STOPPED)) sendBroadcast(Intent(ACTION_STOPPED))
StatusActivity.addMessage(getString(R.string.status_service_destroy)) StatusActivity.addMessage(getString(R.string.status_service_destroy))
stopForeground(true)
if (wakeLock?.isHeld == true) { if (wakeLock?.isHeld == true) {
wakeLock?.release() wakeLock?.release()
} }
@@ -122,7 +121,12 @@ class TrackingService : Service() {
} else { } else {
intent = Intent(Settings.ACTION_SETTINGS) intent = Intent(Settings.ACTION_SETTINGS)
} }
builder.setContentIntent(PendingIntent.getActivity(context, 0, intent, 0)) val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.FLAG_IMMUTABLE
} else {
PendingIntent.FLAG_UPDATE_CURRENT
}
builder.setContentIntent(PendingIntent.getActivity(context, 0, intent, flags))
return builder.build() return builder.build()
} }
} }
+2 -2
Просмотреть файл
@@ -51,8 +51,8 @@ abstract class WakefulBroadcastReceiver : BroadcastReceiver() {
} }
} }
fun completeWakefulIntent(intent: Intent): Boolean { fun completeWakefulIntent(intent: Intent?): Boolean {
val id = intent.getIntExtra(EXTRA_WAKE_LOCK_ID, 0) val id = intent?.getIntExtra(EXTRA_WAKE_LOCK_ID, 0) ?: 0
if (id == 0) { if (id == 0) {
return false return false
} }
+5
Просмотреть файл
@@ -8,4 +8,9 @@
android:title="@string/menu_status" android:title="@string/menu_status"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item
android:id="@+id/info"
android:title="@string/menu_info"
app:showAsAction="ifRoom" />
</menu> </menu>
+53
Просмотреть файл
@@ -0,0 +1,53 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<string name="app_name">Traccar Client</string>
<string name="app_logo">Traccar</string>
<string name="shortcut_start">Inicia servei</string>
<string name="shortcut_stop">Atura servei</string>
<string name="shortcut_sos">Envia SOS</string>
<string name="channel_default">Canal principal</string>
<string name="settings_id_title">Id dispositiu</string>
<string name="settings_url_title">URL Servidor</string>
<string name="settings_url_summary">URL del servidor de seguiment</string>
<string name="settings_interval_title">Interval</string>
<string name="settings_interval_summary">Interval d\'enviament en segons</string>
<string name="settings_distance_title">Distància</string>
<string name="settings_distance_summary">Distància en metres per informar</string>
<string name="settings_angle_title">Angle</string>
<string name="settings_angle_summary">Graus de diferència per informar</string>
<string name="settings_status_title">Estat del servei</string>
<string name="settings_status_off">Aturat</string>
<string name="settings_status_on">Inciat</string>
<string name="settings_status_off_summary">Servei aturat</string>
<string name="settings_status_on_summary">Servei iniciat</string>
<string name="settings_buffer">Buffer</string>
<string name="settings_buffer_off_summary">Buffer desactivat</string>
<string name="settings_buffer_on_summary">Buffer activat</string>
<string name="settings_wakelock">Bloca despertar</string>
<string name="settings_wakelock_off_summary">Bloca despertar desactivat</string>
<string name="settings_wakelock_on_summary">Bloca despertar activat</string>
<string name="settings_accuracy_title">Precisió</string>
<string name="settings_accuracy_summary">Precisió</string>
<string name="settings_accuracy_high">Precisió alta</string>
<string name="settings_accuracy_medium">Precisió mitjana</string>
<string name="settings_accuracy_low">Precisió baixa</string>
<string name="settings_foreground_title">Primer pla</string>
<string name="settings_foreground_summary">En primer pla</string>
<string name="menu_status">Estat</string>
<string name="menu_info">Informació</string>
<string name="menu_shortcuts">Dreceres</string>
<string name="menu_clear">Netejar</string>
<string name="status_service_create">Servei iniciat</string>
<string name="status_service_destroy">Servei aturat</string>
<string name="status_send_success">Enviat correctament</string>
<string name="status_send_fail">Error a l\'enviar</string>
<string name="status_location_update">Actualització de localització</string>
<string name="status_network_online">Xarxa en línia</string>
<string name="status_network_offline">Xarxa fora de línia</string>
<string name="hidden_app_name">Configuració del dispositiu</string>
<string name="hidden_alert">Aplicació ocultada. Per obrir-la de nou escriviu 8722227 (TRACCAR).</string>
<string name="error_msg_invalid_url">Adreça URL incorrecte</string>
<string name="request_exception">Per obtenir contínuament les dades de localització, desactivi la optimització de la bateria per aquesta aplicació</string>
<string name="request_background">Per obtenir contínuament les dades de localització, activi el permís \"%s\".</string>
<string name="request_background_option">Permetre tot el temps</string>
</resources>
+4
Просмотреть файл
@@ -34,6 +34,7 @@
<string name="settings_foreground_title">Popředí služba</string> <string name="settings_foreground_title">Popředí služba</string>
<string name="settings_foreground_summary">Zvýšit prioritu služba</string> <string name="settings_foreground_summary">Zvýšit prioritu služba</string>
<string name="menu_status">Stav</string> <string name="menu_status">Stav</string>
<string name="menu_info">Informace</string>
<string name="menu_shortcuts">Přidat zástupce</string> <string name="menu_shortcuts">Přidat zástupce</string>
<string name="menu_clear">Vyčistit</string> <string name="menu_clear">Vyčistit</string>
<string name="status_service_create">Služba spuštěna</string> <string name="status_service_create">Služba spuštěna</string>
@@ -46,4 +47,7 @@
<string name="hidden_app_name">Nastavení zařízení</string> <string name="hidden_app_name">Nastavení zařízení</string>
<string name="hidden_alert">Aplikace byla skryta. Pro znovuotevření vytočte 8722227 (TRACCAR)</string> <string name="hidden_alert">Aplikace byla skryta. Pro znovuotevření vytočte 8722227 (TRACCAR)</string>
<string name="error_msg_invalid_url">Prosím vložte platnou http:// nebo https:// URL</string> <string name="error_msg_invalid_url">Prosím vložte platnou http:// nebo https:// URL</string>
<string name="request_exception">Chcete-li průběžně shromažďovat údaje o poloze, vypněte optimalizaci baterie pro aplikaci.</string>
<string name="request_background">Chcete-li průběžně shromažďovat údaje o poloze, zapněte \"%s\" oprávnění.</string>
<string name="request_background_option">Povolit po celou dobu</string>
</resources> </resources>
+4
Просмотреть файл
@@ -34,6 +34,7 @@
<string name="settings_foreground_title">Υπηρεσία προσκηνίου</string> <string name="settings_foreground_title">Υπηρεσία προσκηνίου</string>
<string name="settings_foreground_summary">Αύξηση προτεραιότητας της υπηρεσίας</string> <string name="settings_foreground_summary">Αύξηση προτεραιότητας της υπηρεσίας</string>
<string name="menu_status">Κατάσταση</string> <string name="menu_status">Κατάσταση</string>
<string name="menu_info">Πληροφορίες</string>
<string name="menu_shortcuts">Προσθήκη συντόμευσης</string> <string name="menu_shortcuts">Προσθήκη συντόμευσης</string>
<string name="menu_clear">Καθαρισμός</string> <string name="menu_clear">Καθαρισμός</string>
<string name="status_service_create">Η υπηρεσία εκκινήθηκε</string> <string name="status_service_create">Η υπηρεσία εκκινήθηκε</string>
@@ -46,4 +47,7 @@
<string name="hidden_app_name">Ρυθμίσεις συσκευής</string> <string name="hidden_app_name">Ρυθμίσεις συσκευής</string>
<string name="hidden_alert">Η εφαρμογή αποκρύφτηκε. Για να προβληθεί καλέστε 8722227 (TRACCAR)</string> <string name="hidden_alert">Η εφαρμογή αποκρύφτηκε. Για να προβληθεί καλέστε 8722227 (TRACCAR)</string>
<string name="error_msg_invalid_url">Παρακαλώ εισάγετε μία έγκυρη http:// ή https:// διεύθυνση</string> <string name="error_msg_invalid_url">Παρακαλώ εισάγετε μία έγκυρη http:// ή https:// διεύθυνση</string>
<string name="request_exception">Για να συλλέγετε συνεχώς δεδομένα τοποθεσίας απενεργοποιήστε την βελτιστοποίηση μπαταρίας για την εφαρμογή.</string>
<string name="request_background">Για να συλλέγετε συνεχώς δεδομένα τοποθεσίας ενεργοποιήστε την επιλογή \"%s\".</string>
<string name="request_background_option">Να επιτρέπεται όλη την ώρα</string>
</resources> </resources>
+7 -3
Просмотреть файл
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<resources> <resources>
<string name="app_name">Cliente Traccar</string> <string name="app_name">Traccar Client</string>
<string name="app_logo">Traccar</string> <string name="app_logo">Traccar</string>
<string name="shortcut_start">Iniciar servicio</string> <string name="shortcut_start">Iniciar servicio</string>
<string name="shortcut_stop">Detener servicio</string> <string name="shortcut_stop">Detener servicio</string>
@@ -34,16 +34,20 @@
<string name="settings_foreground_title">Servicio en primer plano</string> <string name="settings_foreground_title">Servicio en primer plano</string>
<string name="settings_foreground_summary">Aumentar prioridad del servicio</string> <string name="settings_foreground_summary">Aumentar prioridad del servicio</string>
<string name="menu_status">Estado</string> <string name="menu_status">Estado</string>
<string name="menu_info">Info</string>
<string name="menu_shortcuts">Añadir acceso directo</string> <string name="menu_shortcuts">Añadir acceso directo</string>
<string name="menu_clear">Limpiar</string> <string name="menu_clear">Limpiar</string>
<string name="status_service_create">Servicio iniciado</string> <string name="status_service_create">Servicio iniciado</string>
<string name="status_service_destroy">Servicio detenido</string> <string name="status_service_destroy">Servicio detenido</string>
<string name="status_send_success">Enviado correctamente</string> <string name="status_send_success">Enviado correctamente</string>
<string name="status_send_fail">Falló el envío</string> <string name="status_send_fail">Fallo en el envío</string>
<string name="status_location_update">Actualización de localización</string> <string name="status_location_update">Actualización de localización</string>
<string name="status_network_online">Red en línea</string> <string name="status_network_online">Red en línea</string>
<string name="status_network_offline">Red fuera de línea</string> <string name="status_network_offline">Red fuera de línea</string>
<string name="hidden_app_name">Ajustes del dispositivo</string> <string name="hidden_app_name">Ajustes del dispositivo</string>
<string name="hidden_alert">La aplicación se ha ocultado. Para abrirla de nuevo por favor marque 8722227 (TRACCAR).</string> <string name="hidden_alert">La aplicación se ha ocultado. Para abrirla de nuevo por favor marque 8722227 (TRACCAR).</string>
<string name="error_msg_invalid_url">Por favor. Introduzca una URL válida http:// ó https:// </string> <string name="error_msg_invalid_url">Por favor, introduzca una URL válida http:// ó https:// </string>
<string name="request_exception">Para recoger continuamente los datos de localización, desactiva la optimización de la batería de la aplicación.</string>
<string name="request_background">Para recoger continuamente los datos de localización, por favor, activa el permiso \"%s\".</string>
<string name="request_background_option">Permitir todo el tiempo</string>
</resources> </resources>
+7
Просмотреть файл
@@ -23,6 +23,9 @@
<string name="settings_buffer">Offline-puskurointi</string> <string name="settings_buffer">Offline-puskurointi</string>
<string name="settings_buffer_off_summary">Puskurointi pois päältä</string> <string name="settings_buffer_off_summary">Puskurointi pois päältä</string>
<string name="settings_buffer_on_summary">Puskurointi päälle</string> <string name="settings_buffer_on_summary">Puskurointi päälle</string>
<string name="settings_wakelock">Lepotilalukko</string>
<string name="settings_wakelock_off_summary">Lepotilalukko pois päältä</string>
<string name="settings_wakelock_on_summary">Lepotilalukko päällä</string>
<string name="settings_accuracy_title">Sijainnin tarkkuus</string> <string name="settings_accuracy_title">Sijainnin tarkkuus</string>
<string name="settings_accuracy_summary">Haluttu sijainnin tarkkuus</string> <string name="settings_accuracy_summary">Haluttu sijainnin tarkkuus</string>
<string name="settings_accuracy_high">Korkea</string> <string name="settings_accuracy_high">Korkea</string>
@@ -31,6 +34,7 @@
<string name="settings_foreground_title">Edustapalvelu</string> <string name="settings_foreground_title">Edustapalvelu</string>
<string name="settings_foreground_summary">Lisää palvelun prioriteettia</string> <string name="settings_foreground_summary">Lisää palvelun prioriteettia</string>
<string name="menu_status">Tila</string> <string name="menu_status">Tila</string>
<string name="menu_info">Tiedot</string>
<string name="menu_shortcuts">Lisää pikakuvakkeet</string> <string name="menu_shortcuts">Lisää pikakuvakkeet</string>
<string name="menu_clear">Tyhjennä</string> <string name="menu_clear">Tyhjennä</string>
<string name="status_service_create">Palvelu käynnistynyt</string> <string name="status_service_create">Palvelu käynnistynyt</string>
@@ -43,4 +47,7 @@
<string name="hidden_app_name">Laitteen asetukset</string> <string name="hidden_app_name">Laitteen asetukset</string>
<string name="hidden_alert">Sovellus on piilotettu. Näppäile 8722227 (TRACCAR) avataksesi sovelluksen uudelleen.</string> <string name="hidden_alert">Sovellus on piilotettu. Näppäile 8722227 (TRACCAR) avataksesi sovelluksen uudelleen.</string>
<string name="error_msg_invalid_url">Syötä kelvollinen http:// tai https:// URL-osoite</string> <string name="error_msg_invalid_url">Syötä kelvollinen http:// tai https:// URL-osoite</string>
<string name="request_exception">Kerätäksesi jatkuvasti sijaintitietoa, poista akun optimointi käytöstä tältä sovellukselta.</string>
<string name="request_background">Kerätäksesi jatkuvasti sijaintitietoa, salli \"%s\" käyttöoikeus.</string>
<string name="request_background_option">Salli kokoajan</string>
</resources> </resources>
+6
Просмотреть файл
@@ -20,6 +20,12 @@
<string name="settings_status_on">Arrêter</string> <string name="settings_status_on">Arrêter</string>
<string name="settings_status_off_summary">Arrêté</string> <string name="settings_status_off_summary">Arrêté</string>
<string name="settings_status_on_summary">En marche</string> <string name="settings_status_on_summary">En marche</string>
<string name="settings_buffer">Mise en tampon hors ligne</string>
<string name="settings_buffer_off_summary">Mise en tampon désactivée</string>
<string name="settings_buffer_on_summary">Mise en tampon activée</string>
<string name="settings_wakelock">Wake lock</string>
<string name="settings_wakelock_off_summary">Wake lock off</string>
<string name="settings_wakelock_on_summary">Wake lock on</string>
<string name="settings_accuracy_title">Precision de la localisation</string> <string name="settings_accuracy_title">Precision de la localisation</string>
<string name="settings_accuracy_summary">Précision de localisation désirée</string> <string name="settings_accuracy_summary">Précision de localisation désirée</string>
<string name="settings_accuracy_high">Haut</string> <string name="settings_accuracy_high">Haut</string>
+13
Просмотреть файл
@@ -20,6 +20,12 @@
<string name="settings_status_on">Megállítás</string> <string name="settings_status_on">Megállítás</string>
<string name="settings_status_off_summary">Szolgáltatás megállítva</string> <string name="settings_status_off_summary">Szolgáltatás megállítva</string>
<string name="settings_status_on_summary">Szolgáltatás elindítva</string> <string name="settings_status_on_summary">Szolgáltatás elindítva</string>
<string name="settings_buffer">Offline pufferelés</string>
<string name="settings_buffer_off_summary">Pufferelés ki</string>
<string name="settings_buffer_on_summary">Pufferelés be</string>
<string name="settings_wakelock">Ébresztési zár</string>
<string name="settings_wakelock_off_summary">Ébresztési zár ki</string>
<string name="settings_wakelock_on_summary">Ébresztési zár be</string>
<string name="settings_accuracy_title">Pozíció pontossága</string> <string name="settings_accuracy_title">Pozíció pontossága</string>
<string name="settings_accuracy_summary">Kívánt pozíció pontosság</string> <string name="settings_accuracy_summary">Kívánt pozíció pontosság</string>
<string name="settings_accuracy_high">Magas</string> <string name="settings_accuracy_high">Magas</string>
@@ -28,6 +34,7 @@
<string name="settings_foreground_title">Előtér szolgáltatás</string> <string name="settings_foreground_title">Előtér szolgáltatás</string>
<string name="settings_foreground_summary">Szolgáltatás prioritásának emelése</string> <string name="settings_foreground_summary">Szolgáltatás prioritásának emelése</string>
<string name="menu_status">Státusz</string> <string name="menu_status">Státusz</string>
<string name="menu_info">Infó</string>
<string name="menu_shortcuts">Parancsikon hozzáadása</string> <string name="menu_shortcuts">Parancsikon hozzáadása</string>
<string name="menu_clear">Töröl</string> <string name="menu_clear">Töröl</string>
<string name="status_service_create">Szolgáltatás elindítva</string> <string name="status_service_create">Szolgáltatás elindítva</string>
@@ -40,4 +47,10 @@
<string name="hidden_app_name">Eszköz beállítások</string> <string name="hidden_app_name">Eszköz beállítások</string>
<string name="hidden_alert">Ez az applikáció el lett rejtve. Megnyitásához kérjük hívja a 8722227 (TRACCAR) telefonszámot.</string> <string name="hidden_alert">Ez az applikáció el lett rejtve. Megnyitásához kérjük hívja a 8722227 (TRACCAR) telefonszámot.</string>
<string name="error_msg_invalid_url">Adjon meg egy érvényes URL-t (http:// vagy https://)</string> <string name="error_msg_invalid_url">Adjon meg egy érvényes URL-t (http:// vagy https://)</string>
<string name="request_exception">A folyamatos helyadatok
gyűjtéséhez kapcsolja ki
az alkalmazás akkumulátor
optimazilását.</string>
<string name="request_background">A folyamatos helyadat gyűjtéshez engedélyezze a \"%s\" jogosultságot.</string>
<string name="request_background_option">Mindig engedélyezve</string>
</resources> </resources>
+10
Просмотреть файл
@@ -20,6 +20,12 @@
<string name="settings_status_on">Stop</string> <string name="settings_status_on">Stop</string>
<string name="settings_status_off_summary">Servizio arrestato</string> <string name="settings_status_off_summary">Servizio arrestato</string>
<string name="settings_status_on_summary">Servizio avviato</string> <string name="settings_status_on_summary">Servizio avviato</string>
<string name="settings_buffer">Buffering offline</string>
<string name="settings_buffer_off_summary">Buffering spento</string>
<string name="settings_buffer_on_summary">Buffering acceso</string>
<string name="settings_wakelock">Wake lock</string>
<string name="settings_wakelock_off_summary">Wake lock spento</string>
<string name="settings_wakelock_on_summary">Wake lock acceso</string>
<string name="settings_accuracy_title">Accuratezza posizione</string> <string name="settings_accuracy_title">Accuratezza posizione</string>
<string name="settings_accuracy_summary">Precisione desiderata per la posizione</string> <string name="settings_accuracy_summary">Precisione desiderata per la posizione</string>
<string name="settings_accuracy_high">Alta</string> <string name="settings_accuracy_high">Alta</string>
@@ -28,6 +34,7 @@
<string name="settings_foreground_title">Servizio in primo piano</string> <string name="settings_foreground_title">Servizio in primo piano</string>
<string name="settings_foreground_summary">Aumenta la priorità del servizio</string> <string name="settings_foreground_summary">Aumenta la priorità del servizio</string>
<string name="menu_status">Stato</string> <string name="menu_status">Stato</string>
<string name="menu_info">Informazioni</string>
<string name="menu_shortcuts">Aggiungi combinazione rapida</string> <string name="menu_shortcuts">Aggiungi combinazione rapida</string>
<string name="menu_clear">Pulisci</string> <string name="menu_clear">Pulisci</string>
<string name="status_service_create">Servizio avviato</string> <string name="status_service_create">Servizio avviato</string>
@@ -40,4 +47,7 @@
<string name="hidden_app_name">Impostazioni dispositivo</string> <string name="hidden_app_name">Impostazioni dispositivo</string>
<string name="hidden_alert">La app è stata nascosta. Per aprirla nuovamente digita 8722227 (TRACCAR).</string> <string name="hidden_alert">La app è stata nascosta. Per aprirla nuovamente digita 8722227 (TRACCAR).</string>
<string name="error_msg_invalid_url">Per favore inserisci un URL valido http:// o https://</string> <string name="error_msg_invalid_url">Per favore inserisci un URL valido http:// o https://</string>
<string name="request_exception">Per abilitare la raccolta continua delle posizioni, disabilita le ottimizzazioni batteria per questa applicazione</string>
<string name="request_background">Per abilitare la raccolta delle posizione, abilita il permesso \"%s\"</string>
<string name="request_background_option">Contenti per tutto il tempo</string>
</resources> </resources>
+49
Просмотреть файл
@@ -0,0 +1,49 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<string name="app_name">Traccar კლიენტი</string>
<string name="app_logo">Traccar</string>
<string name="shortcut_start">სერვისის სტარტი</string>
<string name="shortcut_stop">სერვისის დასტოპება</string>
<string name="shortcut_sos">SOS სიგნალის გაგზავნა</string>
<string name="channel_default">ძირითადი არხი</string>
<string name="settings_id_title">მოწყობილობის იდენტიფიკატორი</string>
<string name="settings_url_title">სერვერის მისამართი URL</string>
<string name="settings_url_summary">ტრეკინგ სერვერის მისამართი URL</string>
<string name="settings_interval_title">სიხშირე</string>
<string name="settings_interval_summary">რეპორტებს შორის ინტერვალი წამებში</string>
<string name="settings_distance_title">დისტანცია</string>
<string name="settings_distance_summary">რეპორტებს შორის ინტერვალი მეტრებში</string>
<string name="settings_angle_title">მიმართულება</string>
<string name="settings_angle_summary">მიმართულების რეპორტი გრადუსებში</string>
<string name="settings_status_title">სერვისი სტატუსი</string>
<string name="settings_status_off">სტარტი</string>
<string name="settings_status_on">შეჩერება</string>
<string name="settings_status_off_summary">სერვისი შეჩერებულია</string>
<string name="settings_status_on_summary">სერვისი გაშვებულია</string>
<string name="settings_buffer">ოფლაინ ბუფერიზაცია</string>
<string name="settings_buffer_off_summary">ბუფერიზაცია გამორთულია</string>
<string name="settings_buffer_on_summary">ბუფერიზაცია ჩართულია</string>
<string name="settings_wakelock">გაღვიძების ბლოკირება</string>
<string name="settings_wakelock_off_summary">გაღვიძების ბლოკირება გამორთულია</string>
<string name="settings_wakelock_on_summary">გაღვიძების ბლოკირება ჩართულია</string>
<string name="settings_accuracy_title">მდებარეობის სიზუსტე</string>
<string name="settings_accuracy_summary">მდებარეობის სასურველი სიზუსტე</string>
<string name="settings_accuracy_high">მაღალი</string>
<string name="settings_accuracy_medium">საშუალო</string>
<string name="settings_accuracy_low">დაბალი</string>
<string name="settings_foreground_title">ფონური სერვისი</string>
<string name="settings_foreground_summary">სერვისის პრიორიტეტის გაზრდა</string>
<string name="menu_status">სტატუსი</string>
<string name="menu_shortcuts">შორტკატის დამატება</string>
<string name="menu_clear">გასუფთავება</string>
<string name="status_service_create">სერვისი გაშვებულია</string>
<string name="status_service_destroy">სერვისი შეჩერებულია</string>
<string name="status_send_success">წარმატებით გაიგზავნა</string>
<string name="status_send_fail">გაგზავნა ვერ მოხერხდა</string>
<string name="status_location_update">მდებარეობა განახლდა</string>
<string name="status_network_online">ქსელი კავშირშია</string>
<string name="status_network_offline">ქსელი გამორთულია</string>
<string name="hidden_app_name">მოწყობილობის პარამეტრები</string>
<string name="hidden_alert">პროგრამა დამალულია. მის გასახსნელად გთხოვთ აკრიფოთ 8722227 (TRACCAR).</string>
<string name="error_msg_invalid_url">გთხოვთ, შეიყვანოთ სწორი http: // ან https: // URL</string>
</resources>
+2
Просмотреть файл
@@ -34,6 +34,7 @@
<string name="settings_foreground_title">Zināšanu servis</string> <string name="settings_foreground_title">Zināšanu servis</string>
<string name="settings_foreground_summary">Paaugstināt servisa prioritāti</string> <string name="settings_foreground_summary">Paaugstināt servisa prioritāti</string>
<string name="menu_status">Statuss</string> <string name="menu_status">Statuss</string>
<string name="menu_info">Informācija</string>
<string name="menu_shortcuts">Pievienot saīsnes</string> <string name="menu_shortcuts">Pievienot saīsnes</string>
<string name="menu_clear">Notīrīt</string> <string name="menu_clear">Notīrīt</string>
<string name="status_service_create">Serviss uzsākts</string> <string name="status_service_create">Serviss uzsākts</string>
@@ -46,4 +47,5 @@
<string name="hidden_app_name">Ierīces iestatījumi</string> <string name="hidden_app_name">Ierīces iestatījumi</string>
<string name="hidden_alert">Lietotne ir paslēpta. Zvaniet 8722227 (TRACCAR), lai to atkal parādītu.</string> <string name="hidden_alert">Lietotne ir paslēpta. Zvaniet 8722227 (TRACCAR), lai to atkal parādītu.</string>
<string name="error_msg_invalid_url">Lūdzu ievadiet derīgu http:// vai https:// URL</string> <string name="error_msg_invalid_url">Lūdzu ievadiet derīgu http:// vai https:// URL</string>
<string name="request_background_option">Visu laiku atļauts</string>
</resources> </resources>
+4
Просмотреть файл
@@ -34,6 +34,7 @@
<string name="settings_foreground_title">Voorgrond service</string> <string name="settings_foreground_title">Voorgrond service</string>
<string name="settings_foreground_summary">Verhoog voorrang voor service</string> <string name="settings_foreground_summary">Verhoog voorrang voor service</string>
<string name="menu_status">Status</string> <string name="menu_status">Status</string>
<string name="menu_info">Info</string>
<string name="menu_shortcuts">Voeg snelkoppelingen toe</string> <string name="menu_shortcuts">Voeg snelkoppelingen toe</string>
<string name="menu_clear">Wis</string> <string name="menu_clear">Wis</string>
<string name="status_service_create">Service gestart</string> <string name="status_service_create">Service gestart</string>
@@ -46,4 +47,7 @@
<string name="hidden_app_name">Toestel instellingen</string> <string name="hidden_app_name">Toestel instellingen</string>
<string name="hidden_alert">De app is verborgen. Om hem opnieuw te openen bel je naar 8722227 (TRACCAR).</string> <string name="hidden_alert">De app is verborgen. Om hem opnieuw te openen bel je naar 8722227 (TRACCAR).</string>
<string name="error_msg_invalid_url">Voer alstublieft een geldige http:// of https:// URL in</string> <string name="error_msg_invalid_url">Voer alstublieft een geldige http:// of https:// URL in</string>
<string name="request_exception">Om continu locatiegegevens te kunnen verzamelen is het noodzakelijk dat accuoptimalisatie voor deze app is uitgeschakeld.</string>
<string name="request_background">Geef de \"1%s\" permissie om continu locatieinformatie bij te houden.</string>
<string name="request_background_option">Altijd toestaan</string>
</resources> </resources>
+4
Просмотреть файл
@@ -34,6 +34,7 @@
<string name="settings_foreground_title">Usługa pierwszoplanowa</string> <string name="settings_foreground_title">Usługa pierwszoplanowa</string>
<string name="settings_foreground_summary">Zwiększ priorytet usługi</string> <string name="settings_foreground_summary">Zwiększ priorytet usługi</string>
<string name="menu_status">Status</string> <string name="menu_status">Status</string>
<string name="menu_info">Info</string>
<string name="menu_shortcuts">Dodaj skróty</string> <string name="menu_shortcuts">Dodaj skróty</string>
<string name="menu_clear">Wyczyść</string> <string name="menu_clear">Wyczyść</string>
<string name="status_service_create">Usługa uruchomiona</string> <string name="status_service_create">Usługa uruchomiona</string>
@@ -46,4 +47,7 @@
<string name="hidden_app_name">Ustawienia urządzenia</string> <string name="hidden_app_name">Ustawienia urządzenia</string>
<string name="hidden_alert">Aplikacja została ukryta. By ją otworzyć, zadzwoń pod 8722227 (TRACCAR).</string> <string name="hidden_alert">Aplikacja została ukryta. By ją otworzyć, zadzwoń pod 8722227 (TRACCAR).</string>
<string name="error_msg_invalid_url">Wprowadź poprawny adres http:// lub https:// URL</string> <string name="error_msg_invalid_url">Wprowadź poprawny adres http:// lub https:// URL</string>
<string name="request_exception">Do stałego zbierania danych o lokalizacji, należy wyłączyć optymalizację baterii w aplikacji.</string>
<string name="request_background">Włącz zezwolenie \"%s\", aby ciągle zbierać dane o lokalizacji.</string>
<string name="request_background_option">Pozwól cały czas</string>
</resources> </resources>
+4
Просмотреть файл
@@ -34,6 +34,7 @@
<string name="settings_foreground_title">Serviço em primeiro plano</string> <string name="settings_foreground_title">Serviço em primeiro plano</string>
<string name="settings_foreground_summary">Aumentar a prioridade do serviço</string> <string name="settings_foreground_summary">Aumentar a prioridade do serviço</string>
<string name="menu_status">Estado</string> <string name="menu_status">Estado</string>
<string name="menu_info">Informação</string>
<string name="menu_shortcuts">Adicionar atalhos</string> <string name="menu_shortcuts">Adicionar atalhos</string>
<string name="menu_clear">Limpar</string> <string name="menu_clear">Limpar</string>
<string name="status_service_create">Serviço iniciado</string> <string name="status_service_create">Serviço iniciado</string>
@@ -46,4 +47,7 @@
<string name="hidden_app_name">Configurações do Dispositivo</string> <string name="hidden_app_name">Configurações do Dispositivo</string>
<string name="hidden_alert">O aplicativo foi escondido. Para abrir novamente por favor digite 8722227 (TRACCAR).</string> <string name="hidden_alert">O aplicativo foi escondido. Para abrir novamente por favor digite 8722227 (TRACCAR).</string>
<string name="error_msg_invalid_url">Digite uma URL http: // ou https: // válida</string> <string name="error_msg_invalid_url">Digite uma URL http: // ou https: // válida</string>
<string name="request_exception">Para coletar dados de localização continuamente por favor desabilite a economia de bateria para o aplicativo.</string>
<string name="request_background">Para coletar dados de localização continuamente por favor habilite a permissão \"%s\".</string>
<string name="request_background_option">Permitir sempre</string>
</resources> </resources>
+6
Просмотреть файл
@@ -20,6 +20,12 @@
<string name="settings_status_on">Стоп</string> <string name="settings_status_on">Стоп</string>
<string name="settings_status_off_summary">Сервис остановлен</string> <string name="settings_status_off_summary">Сервис остановлен</string>
<string name="settings_status_on_summary">Сервис запущен</string> <string name="settings_status_on_summary">Сервис запущен</string>
<string name="settings_buffer">Оффлайн буферизация</string>
<string name="settings_buffer_off_summary">Буферизация выключена</string>
<string name="settings_buffer_on_summary">Буферизация включена</string>
<string name="settings_wakelock">Блокировка пробуждения</string>
<string name="settings_wakelock_off_summary">Блокировка выключена</string>
<string name="settings_wakelock_on_summary">Блокировка включена</string>
<string name="settings_accuracy_title">Точность местоположения</string> <string name="settings_accuracy_title">Точность местоположения</string>
<string name="settings_accuracy_summary">Точность местоположения</string> <string name="settings_accuracy_summary">Точность местоположения</string>
<string name="settings_accuracy_high">Высокая</string> <string name="settings_accuracy_high">Высокая</string>
+21 -13
Просмотреть файл
@@ -1,20 +1,28 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<resources> <resources>
<string name="app_name">Traccar Client</string> <string name="app_name">ට්‍රැකකාර් අනුග්‍රාහකය</string>
<string name="app_logo">Traccar</string> <string name="app_logo">ට්‍රැකකාර්</string>
<string name="settings_id_title">උපකරණ හඳුන්වනය</string> <string name="shortcut_start">සේවාව නවතන්න</string>
<string name="shortcut_stop">සේවාව නවතන්න</string>
<string name="settings_id_title">උපාංගයේ හඳුන්වනය</string>
<string name="settings_url_title">සේවාදායකයේ ඒ.ස.නි.</string>
<string name="settings_url_summary">ලුහුබැඳීමේ සේවාදායකයේ ඒ.ස.නි.</string>
<string name="settings_interval_title">සංඛ්‍යාතය</string> <string name="settings_interval_title">සංඛ්‍යාතය</string>
<string name="settings_status_title">සේවා තත්වය</string> <string name="settings_status_title">සේවාවේ තත්වය</string>
<string name="settings_status_off">ඇරැඹීම</string> <string name="settings_status_off">අරඹන්න</string>
<string name="settings_status_on">වතීම</string> <string name="settings_status_on">නවත්වන්න</string>
<string name="settings_status_off_summary">සේවාව අක්‍රීයයි</string> <string name="settings_status_off_summary">සේවාව නවතා ඇත</string>
<string name="settings_status_on_summary">සේවාව ක්‍රියාත්මකයි</string> <string name="settings_status_on_summary">සේවාව ධාවනය වෙමින්</string>
<string name="settings_foreground_title">Foreground service</string> <string name="settings_foreground_title">පෙරබිම් සේවාව</string>
<string name="settings_foreground_summary">Increase service priority</string> <string name="settings_foreground_summary">සේවාවේ ප්‍රමුඛත්වය වැඩිකරන්න</string>
<string name="menu_status">තත්වය</string> <string name="menu_status">තත්වය</string>
<string name="menu_shortcuts">කෙටි මං එකතු කරන්න</string> <string name="menu_info">තොරතුරු</string>
<string name="menu_shortcuts">කෙටිමං එකතු කරන්න</string>
<string name="menu_clear">හිස් කරන්න</string> <string name="menu_clear">හිස් කරන්න</string>
<string name="status_send_fail">යැවිය නොහැකිය</string> <string name="status_service_create">සේවාව ඇරඹිණි</string>
<string name="status_location_update">Location update</string> <string name="status_service_destroy">සේවාව නැවතිණි</string>
<string name="status_send_success">සාර්ථකව යැවිණි</string>
<string name="status_send_fail">යැවීමට අසමත් විය</string>
<string name="status_location_update">ස්ථානය යාවත්කාලය</string>
<string name="hidden_app_name">උපකරණ සැකසුම්</string> <string name="hidden_app_name">උපකරණ සැකසුම්</string>
</resources> </resources>
+4
Просмотреть файл
@@ -34,6 +34,7 @@
<string name="settings_foreground_title">Prvi plan servis</string> <string name="settings_foreground_title">Prvi plan servis</string>
<string name="settings_foreground_summary">Povecanje usluga prioritet</string> <string name="settings_foreground_summary">Povecanje usluga prioritet</string>
<string name="menu_status">Status</string> <string name="menu_status">Status</string>
<string name="menu_info">Info</string>
<string name="menu_shortcuts">Dodaj prečice</string> <string name="menu_shortcuts">Dodaj prečice</string>
<string name="menu_clear">Očisti</string> <string name="menu_clear">Očisti</string>
<string name="status_service_create">Servis pokrenut</string> <string name="status_service_create">Servis pokrenut</string>
@@ -46,4 +47,7 @@
<string name="hidden_app_name">Podešavanja uređaja</string> <string name="hidden_app_name">Podešavanja uređaja</string>
<string name="hidden_alert">Aplikacija je skrivena. Da je otvorite kucajte 8722227 (TRACCAR).</string> <string name="hidden_alert">Aplikacija je skrivena. Da je otvorite kucajte 8722227 (TRACCAR).</string>
<string name="error_msg_invalid_url">Molimo unesite pravilnu http:// ili https:// adresu</string> <string name="error_msg_invalid_url">Molimo unesite pravilnu http:// ili https:// adresu</string>
<string name="request_exception">Da biste kontinuirano prikupljali podatke o lokaciji, isključite optimizaciju baterije za aplikaciju.</string>
<string name="request_background">Da biste kontinuirano prikupljali podatke o lokaciji, omogućite %s dozvolu.</string>
<string name="request_background_option">Dozvoljeno svo vreme</string>
</resources> </resources>
+53
Просмотреть файл
@@ -0,0 +1,53 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<string name="app_name">Traccarklient</string>
<string name="app_logo">Traccar</string>
<string name="shortcut_start">Starta tjänsten</string>
<string name="shortcut_stop">Stoppa tjänsten</string>
<string name="shortcut_sos">Skicka SOS</string>
<string name="channel_default">Primärkanal</string>
<string name="settings_id_title">Enhets-ID</string>
<string name="settings_url_title">URL till servern</string>
<string name="settings_url_summary">URL till trackservern</string>
<string name="settings_interval_title">Frekvens</string>
<string name="settings_interval_summary">Uppdateringsintervall i sekunder</string>
<string name="settings_distance_title">Avstånd</string>
<string name="settings_distance_summary">Uppdateringsavstånd i meter</string>
<string name="settings_angle_title">Vinkel</string>
<string name="settings_angle_summary">Uppdateringsvinkel i grader</string>
<string name="settings_status_title">Tjänstens status</string>
<string name="settings_status_off">Starta</string>
<string name="settings_status_on">Stoppa</string>
<string name="settings_status_off_summary">Tjänsten har stoppats</string>
<string name="settings_status_on_summary">Tjänsten är igång</string>
<string name="settings_buffer">Buffring offline</string>
<string name="settings_buffer_off_summary">Buffring av</string>
<string name="settings_buffer_on_summary">Buffring på</string>
<string name="settings_wakelock">Förhindra viloläge</string>
<string name="settings_wakelock_off_summary">Förhindra viloläge av</string>
<string name="settings_wakelock_on_summary">Förhindra viloläge på</string>
<string name="settings_accuracy_title">Positionsnoggranhet</string>
<string name="settings_accuracy_summary">Önskad positionsnoggrannhet</string>
<string name="settings_accuracy_high">Hög</string>
<string name="settings_accuracy_medium">Medel</string>
<string name="settings_accuracy_low">Låg</string>
<string name="settings_foreground_title">Tjänsten i förgrunden</string>
<string name="settings_foreground_summary">Öka tjänstens prioritet</string>
<string name="menu_status">Status</string>
<string name="menu_info">Info</string>
<string name="menu_shortcuts">Lägg till länkar</string>
<string name="menu_clear">Rensa</string>
<string name="status_service_create">Tjänsten har startats</string>
<string name="status_service_destroy">Tjänsten har stoppats</string>
<string name="status_send_success">Skickat OK</string>
<string name="status_send_fail">Sändning misslyckades</string>
<string name="status_location_update">Positionsuppdatering</string>
<string name="status_network_online">Nätverk online</string>
<string name="status_network_offline">Nätverk offline</string>
<string name="hidden_app_name">Inställningar</string>
<string name="hidden_alert">App:en är gömd. För att öppna den igen, vänligen ring 8722227 (TRACCAR).</string>
<string name="error_msg_invalid_url">Vänligen fyll i en giltig http://- eller https://-URL</string>
<string name="request_exception">För att kontinuerligt samla in platsdata, stäng av batterioptimeringen för appen.</string>
<string name="request_background">För att kontinuerligt samla in platsdata vänligen aktivera \"%s\" behörighet.</string>
<string name="request_background_option">Tillåt hela tiden</string>
</resources>
+26 -16
Просмотреть файл
@@ -7,37 +7,47 @@
<string name="shortcut_sos">ส่ง SOS</string> <string name="shortcut_sos">ส่ง SOS</string>
<string name="channel_default">ช่องหลัก</string> <string name="channel_default">ช่องหลัก</string>
<string name="settings_id_title">หมายเลขอุปกรณ์</string> <string name="settings_id_title">หมายเลขอุปกรณ์</string>
<string name="settings_url_title">ท๊่อยู่ URL เซิร์ฟเวอร์</string> <string name="settings_url_title">URL เซิร์ฟเวอร์</string>
<string name="settings_url_summary">ท๊่อยู่ URL เซิร์ฟเวอร์ติดตาม</string> <string name="settings_url_summary">URL เซิร์ฟเวอร์ติดตาม</string>
<string name="settings_interval_title">ช่วงเวลาส่งข้อมูล</string> <string name="settings_interval_title">ความถี่</string>
<string name="settings_interval_summary">รายงานทุกช่วงเวลาวินาที</string> <string name="settings_interval_summary">รายงานทุกช่วงเวลาวินาที</string>
<string name="settings_distance_title">ระยะทาง</string> <string name="settings_distance_title">ระยะทาง</string>
<string name="settings_distance_summary">การรายงานระยะทางเมตร</string> <string name="settings_distance_summary">การรายงานระยะทางแบบเมตร</string>
<string name="settings_angle_title">มุม</string> <string name="settings_angle_title">มุม</string>
<string name="settings_angle_summary">รายงานในมุมองศา</string> <string name="settings_angle_summary">รายงานในมุมองศา</string>
<string name="settings_status_title">สถานะเซร์ฟเวอร์</string> <string name="settings_status_title">สถานะเซร์วิส</string>
<string name="settings_status_off">เริ่มต้น</string> <string name="settings_status_off">เริ่มต้น</string>
<string name="settings_status_on">สิ้นสุด</string> <string name="settings_status_on">สิ้นสุด</string>
<string name="settings_status_off_summary">ริ่มทำงาน</string> <string name="settings_status_off_summary">ซอร์วิสหยุดทำงานแล้ว</string>
<string name="settings_status_on_summary">หยุดทำงาน</string> <string name="settings_status_on_summary">เซอร์วิสทำงานอยู่</string>
<string name="settings_accuracy_title">ตำแหน่ง-ความแม่นยำ</string> <string name="settings_buffer">บัฟเฟอร์แบบออฟไลน์</string>
<string name="settings_accuracy_summary">ตำแหน่ง-ต้องการความแม่นยำ</string> <string name="settings_buffer_off_summary">ปิดบัฟเฟอร์</string>
<string name="settings_accuracy_high">สูงมาก</string> <string name="settings_buffer_on_summary">เปิดบัฟเฟอร์</string>
<string name="settings_wakelock">ล็อกการปลุก</string>
<string name="settings_wakelock_off_summary">ปิดล็อกการปลุก</string>
<string name="settings_wakelock_on_summary">เปิดล็อกการปลุก</string>
<string name="settings_accuracy_title">ความแม่นยำของตำแหน่ง</string>
<string name="settings_accuracy_summary">ต้องการความแม่นยำของตำแหน่ง-</string>
<string name="settings_accuracy_high">สูง</string>
<string name="settings_accuracy_medium">ปานกลาง</string> <string name="settings_accuracy_medium">ปานกลาง</string>
<string name="settings_accuracy_low">ต่ำ</string> <string name="settings_accuracy_low">ต่ำ</string>
<string name="settings_foreground_title">ทำงานเบื้องหน้า</string> <string name="settings_foreground_title">ทำงานเบื้องหน้า</string>
<string name="settings_foreground_summary">เพิ่มความลำดับสำคัญการทำงาน</string> <string name="settings_foreground_summary">เพิ่มความลำดับสำคัญการทำงาน</string>
<string name="menu_status">สถานะ</string> <string name="menu_status">สถานะ</string>
<string name="menu_info">ข้อมูล</string>
<string name="menu_shortcuts">เพิ่มชอร์ตคัท</string> <string name="menu_shortcuts">เพิ่มชอร์ตคัท</string>
<string name="menu_clear">ล้างข้อมูล</string> <string name="menu_clear">ล้างข้อมูล</string>
<string name="status_service_create">บริการเริ่มต้นแล้ว</string> <string name="status_service_create">เซอร์วิสเริ่มทำงานแล้ว</string>
<string name="status_service_destroy">หยุดให้บริการแล้ว</string> <string name="status_service_destroy">เซอร์วิสหยุดทำงานแล้ว</string>
<string name="status_send_success">ส่งข้อมูลเรียบร้อย</string> <string name="status_send_success">ส่งข้อมูลเรียบร้อย</string>
<string name="status_send_fail">ส่งข้อมูลล้มเหลว</string> <string name="status_send_fail">ส่งข้อมูลล้มเหลว</string>
<string name="status_location_update">ปรับปรุงตำแหน่ง</string> <string name="status_location_update">ปรับปรุงตำแหน่ง</string>
<string name="status_network_online">น็ต-ออนไลน์</string> <string name="status_network_online">ครือข่ายออนไลน์</string>
<string name="status_network_offline">น็ต-ออฟไลน์</string> <string name="status_network_offline">ครือข่ายออฟไลน์</string>
<string name="hidden_app_name">ตั้งค่าอุปกรณ์</string> <string name="hidden_app_name">ตั้งค่าอุปกรณ์</string>
<string name="hidden_alert">The app has been hidden. To open it again please dial 8722227 (TRACCAR).</string> <string name="hidden_alert">แอพถูกซ่อน หากต้องการเปิดอีกครั้ง โปรดโทร 8722227 (TRACCAR)</string>
<string name="error_msg_invalid_url">โปรดใส่ค่า http:// or https:// URL ที่ถูกต้อง</string> <string name="error_msg_invalid_url">โปรดใส่ค่า http:// หรือ https:// URL ที่ถูกต้อง</string>
<string name="request_exception">หากต้องการรวบรวมข้อมูลตำแหน่งอย่างต่อเนื่อง โปรดปิดการเพิ่มประสิทธิภาพแบตเตอรี่สำหรับแอป</string>
<string name="request_background">หากต้องการรวบรวมข้อมูลตำแหน่งอย่างต่อเนื่อง โปรดเปิดใช้การอนุญาต \"%s\"</string>
<string name="request_background_option">อนุญาตตลอดเวลา</string>
</resources> </resources>
+4
Просмотреть файл
@@ -34,6 +34,7 @@
<string name="settings_foreground_title">Foreground service</string> <string name="settings_foreground_title">Foreground service</string>
<string name="settings_foreground_summary">Increase service priority</string> <string name="settings_foreground_summary">Increase service priority</string>
<string name="menu_status">Status</string> <string name="menu_status">Status</string>
<string name="menu_info">Info</string>
<string name="menu_shortcuts">Add shortcuts</string> <string name="menu_shortcuts">Add shortcuts</string>
<string name="menu_clear">Clear</string> <string name="menu_clear">Clear</string>
<string name="status_service_create">Service started</string> <string name="status_service_create">Service started</string>
@@ -46,4 +47,7 @@
<string name="hidden_app_name">Device Settings</string> <string name="hidden_app_name">Device Settings</string>
<string name="hidden_alert">The app has been hidden. To open it again please dial 8722227 (TRACCAR).</string> <string name="hidden_alert">The app has been hidden. To open it again please dial 8722227 (TRACCAR).</string>
<string name="error_msg_invalid_url">Please enter a valid http:// or https:// URL</string> <string name="error_msg_invalid_url">Please enter a valid http:// or https:// URL</string>
<string name="request_exception">To continuously collect location data please turn off battery optimization for the app.</string>
<string name="request_background">To continuously collect location data please enable \"%s\" permission.</string>
<string name="request_background_option">Allow all the time</string>
</resources> </resources>
+6 -1
Просмотреть файл
@@ -1,4 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<network-security-config> <network-security-config>
<base-config cleartextTrafficPermitted="true" /> <base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config> </network-security-config>
+1 -1
Просмотреть файл
@@ -17,7 +17,7 @@ class DatabaseHelperTest {
val databaseHelper = DatabaseHelper(ApplicationProvider.getApplicationContext()) val databaseHelper = DatabaseHelper(ApplicationProvider.getApplicationContext())
var position: Position? = Position("123456789012345", Location("gps"), 0.0) var position: Position? = Position("123456789012345", Location("gps"), BatteryStatus())
Assert.assertNull(databaseHelper.selectPosition()) Assert.assertNull(databaseHelper.selectPosition())
+6 -6
Просмотреть файл
@@ -15,23 +15,23 @@ class ProtocolFormatterTest {
@Test @Test
fun testFormatRequest() { fun testFormatRequest() {
val position = Position("123456789012345", Location("gps"), 0.0) val position = Position("123456789012345", Location("gps"), BatteryStatus())
val url = formatRequest("http://localhost:5055", position) val url = formatRequest("http://localhost:5055", position)
Assert.assertEquals("http://localhost:5055?id=123456789012345&timestamp=0&lat=0.0&lon=0.0&speed=0.0&bearing=0.0&altitude=0.0&accuracy=0.0&batt=0.0", url) Assert.assertEquals("http://localhost:5055?id=123456789012345&timestamp=619315200&lat=0.0&lon=0.0&speed=0.0&bearing=0.0&altitude=0.0&accuracy=0.0&batt=0.0", url)
} }
@Test @Test
fun testFormatPathPortRequest() { fun testFormatPathPortRequest() {
val position = Position("123456789012345", Location("gps"), 0.0) val position = Position("123456789012345", Location("gps"), BatteryStatus())
val url = formatRequest("http://localhost:8888/path", position) val url = formatRequest("http://localhost:8888/path", position)
Assert.assertEquals("http://localhost:8888/path?id=123456789012345&timestamp=0&lat=0.0&lon=0.0&speed=0.0&bearing=0.0&altitude=0.0&accuracy=0.0&batt=0.0", url) Assert.assertEquals("http://localhost:8888/path?id=123456789012345&timestamp=619315200&lat=0.0&lon=0.0&speed=0.0&bearing=0.0&altitude=0.0&accuracy=0.0&batt=0.0", url)
} }
@Test @Test
fun testFormatAlarmRequest() { fun testFormatAlarmRequest() {
val position = Position("123456789012345", Location("gps"), 0.0) val position = Position("123456789012345", Location("gps"), BatteryStatus())
val url = formatRequest("http://localhost:5055/path", position, "alert message") val url = formatRequest("http://localhost:5055/path", position, "alert message")
Assert.assertEquals("http://localhost:5055/path?id=123456789012345&timestamp=0&lat=0.0&lon=0.0&speed=0.0&bearing=0.0&altitude=0.0&accuracy=0.0&batt=0.0&alarm=alert%20message", url) Assert.assertEquals("http://localhost:5055/path?id=123456789012345&timestamp=619315200&lat=0.0&lon=0.0&speed=0.0&bearing=0.0&altitude=0.0&accuracy=0.0&batt=0.0&alarm=alert%20message", url)
} }
} }
+5 -4
Просмотреть файл
@@ -1,13 +1,13 @@
buildscript { buildscript {
ext.kotlin_version = '1.5.21' ext.kotlin_version = '1.7.20'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.0.0-beta05' classpath 'com.android.tools.build:gradle:7.3.1'
classpath 'com.google.gms:google-services:4.3.8' classpath 'com.google.gms:google-services:4.3.14'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.7.1' classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
@@ -16,5 +16,6 @@ allprojects {
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
maven { url 'https://jitpack.io' }
} }
} }
+1 -1
Просмотреть файл
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
+19 -22
Просмотреть файл
@@ -1,45 +1,42 @@
#!/usr/bin/python #!/usr/bin/env python3
import os import os
import optparse import optparse
import urllib2 import requests
import json
import base64
import shutil import shutil
from transifex.api import transifex_api
parser = optparse.OptionParser() parser = optparse.OptionParser()
parser.add_option("-u", "--user", dest="username", help="transifex user login") parser.add_option("-t", "--token", dest="token", help="transifex token")
parser.add_option("-p", "--password", dest="password", help="transifex user password")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
if not options.username or not options.password: if not options.token:
parser.error('User name and password are required') parser.error('Token is required')
os.chdir(os.path.dirname(os.path.abspath(__file__))) os.chdir(os.path.dirname(os.path.abspath(__file__)))
path = "./app/src/main/res/" path = "./app/src/main/res/"
def request(url): transifex_api.setup(auth=options.token)
req = urllib2.Request(url)
auth = base64.encodestring("%s:%s" % (options.username, options.password)).replace("\n", "")
req.add_header("Authorization", "Basic %s" % auth)
return urllib2.urlopen(req)
resource = json.load(request("https://www.transifex.com/api/2/project/traccar/resource/client/?details")) organization = transifex_api.Organization.get(slug='traccar')
project = organization.fetch('projects').get(slug='traccar')
resource = project.fetch('resources').get(slug='client')
languages = project.fetch('languages')
for language in resource["available_languages"]: for language in languages:
code = language["code"] print(language.code)
data = request("https://www.transifex.com/api/2/project/traccar/resource/client/translation/" + code + "?file") url = transifex_api.ResourceTranslationsAsyncDownload.download(resource=resource, language=language)
if code == "en": result = requests.get(url)
if language.code == "en":
filename = path + "values/strings.xml" filename = path + "values/strings.xml"
else: else:
filename = path + "values-" + code.replace("_", "-r") + "/strings.xml" filename = path + "values-" + language.code.replace("_", "-r") + "/strings.xml"
if not os.path.exists(os.path.dirname(filename)): if not os.path.exists(os.path.dirname(filename)):
os.makedirs(os.path.dirname(filename)) os.makedirs(os.path.dirname(filename))
file = open(filename, "wb") with open(filename, "w") as file:
file.write(data.read()) file.write(result.text)
file.close()
filename = path + "values-iw/strings.xml" filename = path + "values-iw/strings.xml"
if not os.path.exists(os.path.dirname(filename)): if not os.path.exists(os.path.dirname(filename)):