Add charging status
Этот коммит содержится в:
@@ -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) {}
|
||||||
|
|||||||
@@ -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 changing: Boolean = false,
|
||||||
|
)
|
||||||
@@ -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
|
||||||
@@ -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,6 +92,7 @@ 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)
|
||||||
}
|
}
|
||||||
@@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,11 @@ 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),
|
||||||
latitude = location.latitude,
|
latitude = location.latitude,
|
||||||
@@ -47,7 +48,8 @@ data class Position(
|
|||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
},
|
},
|
||||||
battery = battery,
|
battery = battery.level,
|
||||||
|
charging = battery.changing,
|
||||||
mock = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
mock = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
location.isMock
|
location.isMock
|
||||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -54,20 +54,24 @@ abstract class PositionProvider(
|
|||||||
) {
|
) {
|
||||||
Log.i(TAG, "location new")
|
Log.i(TAG, "location new")
|
||||||
lastLocation = location
|
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,
|
||||||
|
changing = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return 0.0
|
return BatteryStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -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())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|
||||||
|
|||||||
@@ -15,21 +15,21 @@ 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×tamp=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×tamp=0&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×tamp=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×tamp=0&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×tamp=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×tamp=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)
|
||||||
}
|
}
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user