conflict fixed
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,5 +14,4 @@
|
|||||||
.cxx
|
.cxx
|
||||||
local.properties
|
local.properties
|
||||||
deploymentTargetDropDown.xml
|
deploymentTargetDropDown.xml
|
||||||
env.properties
|
|
||||||
app/debug
|
app/debug
|
||||||
|
|||||||
2
.idea/vcs.xml
generated
2
.idea/vcs.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
<mapping directory="" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -5,11 +5,11 @@ plugins {
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
namespace 'com.logitech.vc.kirbytest'
|
namespace 'com.logitech.vc.kirbytest'
|
||||||
compileSdk 32
|
compileSdk 34
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.logitech.vc.kirbytest"
|
applicationId "com.logitech.vc.kirbytest"
|
||||||
minSdk 29
|
minSdk 27
|
||||||
targetSdk 32
|
targetSdk 32
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
@@ -31,6 +31,29 @@ android {
|
|||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applicationVariants.all{
|
||||||
|
variant ->
|
||||||
|
variant.outputs.each{
|
||||||
|
output->
|
||||||
|
// on below line we are specifying our app name.
|
||||||
|
project.ext { appName = 'kirbyTestApp' }
|
||||||
|
// on below line we are adding the formatted date to our apk file name.
|
||||||
|
def formattedDate = new Date().format('yyyyMMdd')
|
||||||
|
// on below line we are creating a new name for our apk.
|
||||||
|
def newName = output.outputFile.name
|
||||||
|
// on below line we are replacing our previous name with our app name.
|
||||||
|
newName = newName.replace("app-", "$project.ext.appName-")
|
||||||
|
// 當build type為 debug時觸發
|
||||||
|
// on below line we are replacing -debug with our formatted date.
|
||||||
|
newName = newName.replace("-debug", "-debug-" + formattedDate)
|
||||||
|
// 當build type為 release時觸發
|
||||||
|
// on below line we are replacing -release with our formatted date.
|
||||||
|
newName = newName.replace("-release", "-release-" + formattedDate)
|
||||||
|
// at last we are setting our apk name to it.
|
||||||
|
output.outputFileName = newName
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
@@ -53,6 +76,7 @@ dependencies {
|
|||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.2'
|
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.2'
|
||||||
implementation 'androidx.navigation:navigation-ui-ktx:2.5.2'
|
implementation 'androidx.navigation:navigation-ui-ktx:2.5.2'
|
||||||
|
implementation 'androidx.activity:activity:1.8.0'
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
|
||||||
<!-- Request legacy Bluetooth permissions on versions older than API 31 (Android 12). -->
|
<!-- Request legacy Bluetooth permissions on versions older than API 31 (Android 12). -->
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.BLUETOOTH"
|
android:name="android.permission.BLUETOOTH"
|
||||||
@@ -16,16 +14,12 @@
|
|||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.ACCESS_FINE_LOCATION"
|
android:name="android.permission.ACCESS_FINE_LOCATION"
|
||||||
android:maxSdkVersion="30" />
|
android:maxSdkVersion="30" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<uses-permission
|
|
||||||
android:name="android.permission.FOREGROUND_SERVICE" />
|
|
||||||
|
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.BLUETOOTH_SCAN"
|
android:name="android.permission.BLUETOOTH_SCAN"
|
||||||
android:usesPermissionFlags="neverForLocation"
|
android:usesPermissionFlags="neverForLocation"
|
||||||
tools:targetApi="s" />
|
tools:targetApi="s" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||||
|
|
||||||
<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" />
|
||||||
|
|
||||||
@@ -35,10 +29,15 @@
|
|||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.SensorTestingApp"
|
android:theme="@style/Theme.SensorTestingApp"
|
||||||
|
android:usesCleartextTraffic="true"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
|
<activity
|
||||||
|
android:name=".ServerSettingActivity"
|
||||||
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
@@ -49,8 +48,10 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<service android:name=".BLEService" android:foregroundServiceType="connectedDevice" />
|
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".BLEService"
|
||||||
|
android:foregroundServiceType="connectedDevice" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -114,7 +114,7 @@ class DeviceListAdapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val inflater = popup.menuInflater
|
val inflater = popup.menuInflater
|
||||||
popup.setForceShowIcon(true)
|
// popup.setForceShowIcon(true)
|
||||||
inflater.inflate(R.menu.device_menu, popup.menu)
|
inflater.inflate(R.menu.device_menu, popup.menu)
|
||||||
popup.show()
|
popup.show()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,6 +173,7 @@ class KirbyDevice(
|
|||||||
Log.i("BleListener", "Char received: $payload")
|
Log.i("BleListener", "Char received: $payload")
|
||||||
val base64Payload = Base64.getEncoder().encodeToString(characteristic.value)
|
val base64Payload = Base64.getEncoder().encodeToString(characteristic.value)
|
||||||
publishMeasurement(base64Payload)
|
publishMeasurement(base64Payload)
|
||||||
|
// publishMeasurementAutoServer(measurement)
|
||||||
|
|
||||||
loggerDb.writeLog(measurement)
|
loggerDb.writeLog(measurement)
|
||||||
}
|
}
|
||||||
@@ -216,6 +217,50 @@ class KirbyDevice(
|
|||||||
queue.add(request)
|
queue.add(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun publishMeasurementAutoServer(measurement: DecoderIaq.Measurement) {
|
||||||
|
// Read url from SharedPreferences
|
||||||
|
val sharedPref = context.getSharedPreferences(context.getString(R.string.app_name), Context.MODE_PRIVATE)
|
||||||
|
val url = sharedPref.getString(
|
||||||
|
"kirby_data_post_url",
|
||||||
|
context.getString(R.string.kirby_data_post_url_default)) ?: context.getString(R.string.kirby_data_post_url_default)
|
||||||
|
val accessKey = BuildConfig.API_KEY
|
||||||
|
|
||||||
|
if(url.isEmpty()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val eui = "0000${bleDevice.address.replace(":", "")}"
|
||||||
|
|
||||||
|
val postData = JSONObject()
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Log.i("POST", "Transmitting for $eui: $payload")
|
||||||
|
postData.put("accessKey", "${accessKey}_fromAndroid")
|
||||||
|
postData.put("eui", eui)
|
||||||
|
postData.put("deviceId", measurement.deviceId)
|
||||||
|
postData.put("msgType", measurement.msgType)
|
||||||
|
postData.put("co2", measurement.co2)
|
||||||
|
postData.put("voc", measurement.voc)
|
||||||
|
postData.put("humidity", measurement.humidity)
|
||||||
|
postData.put("temperature", measurement.temperature)
|
||||||
|
postData.put("pressure", measurement.pressure)
|
||||||
|
postData.put("occupancy", measurement.occupancy)
|
||||||
|
postData.put("pm25", measurement.pm25)
|
||||||
|
postData.put("pm10", measurement.pm10)
|
||||||
|
} catch (e: JSONException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
val request = JsonObjectRequest(
|
||||||
|
Request.Method.POST, url, postData,
|
||||||
|
{ response ->
|
||||||
|
Log.i("sendDataResponse", "Response is: $response")
|
||||||
|
}
|
||||||
|
) { error -> error.printStackTrace() }
|
||||||
|
|
||||||
|
queue.add(request)
|
||||||
|
}
|
||||||
|
|
||||||
private val measurements = ArrayList<Payload>()
|
private val measurements = ArrayList<Payload>()
|
||||||
private val maxMeasurements = 20
|
private val maxMeasurements = 20
|
||||||
|
|
||||||
|
|||||||
@@ -330,6 +330,13 @@ class MainActivity : AppCompatActivity() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.action_server_setting -> {
|
||||||
|
// Goto server setting intent
|
||||||
|
val intent = Intent(this, ServerSettingActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
else -> super.onOptionsItemSelected(item)
|
else -> super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.logitech.vc.kirbytest
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.widget.Button
|
||||||
|
import android.widget.EditText
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
|
||||||
|
class ServerSettingActivity : AppCompatActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
setContentView(R.layout.activity_server_setting)
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||||
|
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current server setting from SharedPreferences
|
||||||
|
val sharedPref = getSharedPreferences(getString(R.string.app_name), MODE_PRIVATE)
|
||||||
|
var currentUrl = sharedPref.getString(
|
||||||
|
"kirby_data_post_url",
|
||||||
|
getString(R.string.kirby_data_post_url_default)) ?: getString(R.string.kirby_data_post_url_default)
|
||||||
|
val editTextServerSetting = findViewById<EditText>(R.id.editTextServerSetting)
|
||||||
|
editTextServerSetting.setText(currentUrl)
|
||||||
|
|
||||||
|
val doneButton = findViewById<Button>(R.id.buttonDone)
|
||||||
|
doneButton.setOnClickListener {
|
||||||
|
// Save editTextServerSetting to SharedPreferences
|
||||||
|
val serverSetting = editTextServerSetting.text.toString()
|
||||||
|
sharedPref.edit().putString("kirby_data_post_url", serverSetting).apply()
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
val cancelButton = findViewById<Button>(R.id.buttonCancel)
|
||||||
|
cancelButton.setOnClickListener {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
val defaultButton = findViewById<Button>(R.id.buttonDefault)
|
||||||
|
defaultButton.setOnClickListener {
|
||||||
|
editTextServerSetting.setText(getString(R.string.kirby_data_post_url_default))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
56
app/src/main/res/layout/activity_server_setting.xml
Normal file
56
app/src/main/res/layout/activity_server_setting.xml
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_margin="10dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:id="@+id/main">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textViewServerSetting"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/server_url"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginBottom="20dp" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/editTextServerSetting"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:autofillHints="@string/kirby_data_post_url_default"
|
||||||
|
android:hint="@string/kirby_data_post_url_default" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_gravity="center">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/buttonDone"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/done"
|
||||||
|
android:layout_marginEnd="10dp"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/buttonCancel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/cancel"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:layout_marginEnd="5dp"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/buttonDefault"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/defaultString"
|
||||||
|
android:layout_marginStart="10dp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -17,4 +17,9 @@
|
|||||||
android:orderInCategory="300"
|
android:orderInCategory="300"
|
||||||
android:title="@string/settings"
|
android:title="@string/settings"
|
||||||
app:showAsAction="never" />
|
app:showAsAction="never" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_server_setting"
|
||||||
|
android:orderInCategory="200"
|
||||||
|
android:title="@string/action_server_setting"
|
||||||
|
app:showAsAction="never" />
|
||||||
</menu>
|
</menu>
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
<string name="app_name">Kirby Test App</string>
|
<string name="app_name">Kirby Test App</string>
|
||||||
<string name="action_export">Export to csv</string>
|
<string name="action_export">Export to csv</string>
|
||||||
<string name="action_reset_log">Reset log</string>
|
<string name="action_reset_log">Reset log</string>
|
||||||
|
<string name="action_server_setting">Server Setting</string>
|
||||||
<!-- Strings used for fragments for navigation -->
|
<!-- Strings used for fragments for navigation -->
|
||||||
<string name="first_fragment_label">First Fragment</string>
|
<string name="first_fragment_label">First Fragment</string>
|
||||||
<string name="second_fragment_label">Second Fragment</string>
|
<string name="second_fragment_label">Second Fragment</string>
|
||||||
@@ -13,5 +14,9 @@
|
|||||||
<string name="save">Save</string>
|
<string name="save">Save</string>
|
||||||
<string name="cancel">Cancel</string>
|
<string name="cancel">Cancel</string>
|
||||||
<string name="start_scan">Start Scan</string>
|
<string name="start_scan">Start Scan</string>
|
||||||
|
<string name="server_url">Server URL</string>
|
||||||
|
<string name="kirby_data_post_url_default">http://vc-automation.logitech.com/api/kirby/addData</string>
|
||||||
|
<string name="done">Done</string>
|
||||||
|
<string name="defaultString">Default</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
7
app/src/main/res/xml/network_security_config.xml
Normal file
7
app/src/main/res/xml/network_security_config.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<network-security-config>
|
||||||
|
<base-config cleartextTrafficPermitted="true" />
|
||||||
|
<domain-config cleartextTrafficPermitted="true">
|
||||||
|
<domain includeSubdomains="true">192.168.1.154:5000</domain>
|
||||||
|
</domain-config>
|
||||||
|
</network-security-config>
|
||||||
@@ -29,13 +29,13 @@ class DecoderTest {
|
|||||||
fun message_type_5() {
|
fun message_type_5() {
|
||||||
val res = DecoderIaq.parseMeasurement("501001C0430000")
|
val res = DecoderIaq.parseMeasurement("501001C0430000")
|
||||||
|
|
||||||
val expected = DecoderIaq.DeviceStatus(msgType = 5, firmware = "1.0.28-4", operationMode = 3, batteryVoltage = 0, errorPm = null, errorVoc = null, errorTemp = null, errorCo2 = null, errorRadar = null)
|
val expected = DecoderIaq.DeviceStatus(msgType = 5, firmware = "1.0.28-4", operationMode = 3, batteryVoltage = 0, errorPm = false, errorVoc = false, errorTemp = false, errorCo2 = false, errorRadar = false)
|
||||||
assertEquals(expected, res)
|
assertEquals(expected, res)
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
fun message_type_5_battery() {
|
fun message_type_5_battery() {
|
||||||
val res = DecoderIaq.parseMeasurement("501001C0430FF9")
|
val res = DecoderIaq.parseMeasurement("501001C0430FF9")
|
||||||
val expected = DecoderIaq.DeviceStatus(msgType = 5, firmware = "1.0.28-4", operationMode = 3, batteryVoltage = 4089f/1000, errorPm = null, errorVoc = null, errorTemp = null, errorCo2 = null, errorRadar = null)
|
val expected = DecoderIaq.DeviceStatus(msgType = 5, firmware = "1.0.28-4", operationMode = 3, batteryVoltage = 4089f/1000, errorPm = false, errorVoc = false, errorTemp = false, errorCo2 = false, errorRadar = false)
|
||||||
|
|
||||||
assertEquals(expected, res)
|
assertEquals(expected, res)
|
||||||
}
|
}
|
||||||
|
|||||||
2
env.properties
Normal file
2
env.properties
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
apiBaseUrl=http://vc-automation.logitech.com/teststation/kirby/addData
|
||||||
|
apiKey=CRa04Bk97VWFnnHOCDhyBuAz1a9L69Eu
|
||||||
Reference in New Issue
Block a user