From 0873aa7302484bc394e3e6f74640b223468d24bd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 14 Aug 2022 17:28:44 -0700 Subject: [PATCH] Add charging status --- .../traccar/client/AndroidPositionProvider.kt | 4 ++-- .../java/org/traccar/client/BatteryStatus.kt | 21 +++++++++++++++++++ .../java/org/traccar/client/DatabaseHelper.kt | 9 ++++++-- .../main/java/org/traccar/client/Position.kt | 6 ++++-- .../org/traccar/client/PositionProvider.kt | 14 ++++++++----- .../org/traccar/client/ProtocolFormatter.kt | 3 +++ .../org/traccar/client/DatabaseHelperTest.kt | 2 +- .../traccar/client/ProtocolFormatterTest.kt | 6 +++--- 8 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/org/traccar/client/BatteryStatus.kt diff --git a/app/src/main/java/org/traccar/client/AndroidPositionProvider.kt b/app/src/main/java/org/traccar/client/AndroidPositionProvider.kt index 47cdf6d..17e7718 100644 --- a/app/src/main/java/org/traccar/client/AndroidPositionProvider.kt +++ b/app/src/main/java/org/traccar/client/AndroidPositionProvider.kt @@ -47,11 +47,11 @@ class AndroidPositionProvider(context: Context, listener: PositionListener) : Po try { val location = locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER) if (location != null) { - listener.onPositionUpdate(Position(deviceId, location, getBatteryLevel(context))) + listener.onPositionUpdate(Position(deviceId, location, getBatteryStatus(context))) } else { locationManager.requestSingleUpdate(provider, object : LocationListener { 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) {} diff --git a/app/src/main/java/org/traccar/client/BatteryStatus.kt b/app/src/main/java/org/traccar/client/BatteryStatus.kt new file mode 100644 index 0000000..a7f0923 --- /dev/null +++ b/app/src/main/java/org/traccar/client/BatteryStatus.kt @@ -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, +) diff --git a/app/src/main/java/org/traccar/client/DatabaseHelper.kt b/app/src/main/java/org/traccar/client/DatabaseHelper.kt index 454742c..c77c62c 100644 --- a/app/src/main/java/org/traccar/client/DatabaseHelper.kt +++ b/app/src/main/java/org/traccar/client/DatabaseHelper.kt @@ -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"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ @file:Suppress("DEPRECATION", "StaticFieldLeak") package org.traccar.client +import android.annotation.SuppressLint import android.content.ContentValues import android.content.Context import android.database.SQLException @@ -65,6 +66,7 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM "course REAL," + "accuracy REAL," + "battery REAL," + + "charging INTEGER," + "mock INTEGER)" ) } @@ -90,6 +92,7 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM values.put("course", position.course) values.put("accuracy", position.accuracy) values.put("battery", position.battery) + values.put("charging", if (position.charging) 1 else 0) values.put("mock", if (position.mock) 1 else 0) db.insertOrThrow("position", null, values) } @@ -102,6 +105,7 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM }.execute() } + @SuppressLint("Range") fun selectPosition(): Position? { db.rawQuery("SELECT * FROM position ORDER BY id LIMIT 1", null).use { cursor -> if (cursor.count > 0) { @@ -117,6 +121,7 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM course = cursor.getDouble(cursor.getColumnIndex("course")), accuracy = cursor.getDouble(cursor.getColumnIndex("accuracy")), battery = cursor.getDouble(cursor.getColumnIndex("battery")), + charging = cursor.getInt(cursor.getColumnIndex("charging")) > 0, mock = cursor.getInt(cursor.getColumnIndex("mock")) > 0, ) } @@ -147,7 +152,7 @@ class DatabaseHelper(context: Context?) : SQLiteOpenHelper(context, DATABASE_NAM } companion object { - const val DATABASE_VERSION = 3 + const val DATABASE_VERSION = 4 const val DATABASE_NAME = "traccar.db" } diff --git a/app/src/main/java/org/traccar/client/Position.kt b/app/src/main/java/org/traccar/client/Position.kt index 5dd6c8f..4847d9c 100644 --- a/app/src/main/java/org/traccar/client/Position.kt +++ b/app/src/main/java/org/traccar/client/Position.kt @@ -31,10 +31,11 @@ data class Position( val course: Double = 0.0, val accuracy: Double = 0.0, val battery: Double = 0.0, + val charging: Boolean = false, val mock: Boolean = false, ) { - constructor(deviceId: String, location: Location, battery: Double) : this( + constructor(deviceId: String, location: Location, battery: BatteryStatus) : this( deviceId = deviceId, time = Date(location.time), latitude = location.latitude, @@ -47,7 +48,8 @@ data class Position( } else { 0.0 }, - battery = battery, + battery = battery.level, + charging = battery.changing, mock = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { location.isMock } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { diff --git a/app/src/main/java/org/traccar/client/PositionProvider.kt b/app/src/main/java/org/traccar/client/PositionProvider.kt index 6ee5063..c0a7587 100644 --- a/app/src/main/java/org/traccar/client/PositionProvider.kt +++ b/app/src/main/java/org/traccar/client/PositionProvider.kt @@ -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"); * you may not use this file except in compliance with the License. @@ -54,20 +54,24 @@ abstract class PositionProvider( ) { Log.i(TAG, "location new") lastLocation = location - listener.onPositionUpdate(Position(deviceId, location, getBatteryLevel(context))) + listener.onPositionUpdate(Position(deviceId, location, getBatteryStatus(context))) } else { 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)) if (batteryIntent != null) { val level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0) 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 { diff --git a/app/src/main/java/org/traccar/client/ProtocolFormatter.kt b/app/src/main/java/org/traccar/client/ProtocolFormatter.kt index 642d88d..0f30ab6 100644 --- a/app/src/main/java/org/traccar/client/ProtocolFormatter.kt +++ b/app/src/main/java/org/traccar/client/ProtocolFormatter.kt @@ -31,6 +31,9 @@ object ProtocolFormatter { .appendQueryParameter("altitude", position.altitude.toString()) .appendQueryParameter("accuracy", position.accuracy.toString()) .appendQueryParameter("batt", position.battery.toString()) + if (position.charging) { + builder.appendQueryParameter("charge", position.charging.toString()) + } if (position.mock) { builder.appendQueryParameter("mock", position.mock.toString()) } diff --git a/app/src/test/java/org/traccar/client/DatabaseHelperTest.kt b/app/src/test/java/org/traccar/client/DatabaseHelperTest.kt index 730d051..dae56bb 100644 --- a/app/src/test/java/org/traccar/client/DatabaseHelperTest.kt +++ b/app/src/test/java/org/traccar/client/DatabaseHelperTest.kt @@ -17,7 +17,7 @@ class DatabaseHelperTest { 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()) diff --git a/app/src/test/java/org/traccar/client/ProtocolFormatterTest.kt b/app/src/test/java/org/traccar/client/ProtocolFormatterTest.kt index 115653d..5cb0344 100644 --- a/app/src/test/java/org/traccar/client/ProtocolFormatterTest.kt +++ b/app/src/test/java/org/traccar/client/ProtocolFormatterTest.kt @@ -15,21 +15,21 @@ class ProtocolFormatterTest { @Test fun testFormatRequest() { - val position = Position("123456789012345", Location("gps"), 0.0) + val position = Position("123456789012345", Location("gps"), BatteryStatus()) 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) } @Test 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) 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 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") 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) }