mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Debug: Allow setting device type
This commit is contained in:
+68
-1
@@ -1,13 +1,23 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.debug
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceCategory
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication
|
||||
import nodomain.freeyourgadget.gadgetbridge.R
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceTypeDialog
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
|
||||
class DeviceDebugFragment : AbstractDebugFragment() {
|
||||
private lateinit var gbDevice: GBDevice
|
||||
|
||||
@@ -24,12 +34,29 @@ class DeviceDebugFragment : AbstractDebugFragment() {
|
||||
preferenceScreen?.title = gbDevice.aliasOrName
|
||||
|
||||
findPreference<Preference>(PREF_DEBUG_DEVICE_NAME)?.summary = gbDevice.name ?: "<null>"
|
||||
findPreference<Preference>(PREF_DEBUG_DEVICE_ALIAS)?.summary = gbDevice.alias ?: getString(R.string.not_set)
|
||||
if (gbDevice.alias.isNullOrEmpty()) {
|
||||
findPreference<Preference>(PREF_DEBUG_DEVICE_ALIAS)?.summary = getString(R.string.not_set)
|
||||
} else {
|
||||
findPreference<Preference>(PREF_DEBUG_DEVICE_ALIAS)?.summary = gbDevice.alias ?: getString(R.string.not_set)
|
||||
}
|
||||
findPreference<Preference>(PREF_DEBUG_DEVICE_MAC_ADDRESS)?.summary = gbDevice.address
|
||||
|
||||
// Device Type
|
||||
findPreference<Preference>(PREF_DEBUG_DEVICE_TYPE)?.summary = gbDevice.type.name
|
||||
findPreference<Preference>(PREF_DEBUG_DEVICE_TYPE)?.setOnPreferenceClickListener {
|
||||
DeviceTypeDialog(requireActivity(), R.string.set_device_type, gbDevice.address)
|
||||
.show(gbDevice.type) { _: String, deviceType: DeviceType ->
|
||||
setDeviceType(gbDevice, deviceType)
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
val headerDetails = findPreference<PreferenceCategory>(PREF_HEADER_DETAILS)
|
||||
for (detail in gbDevice.deviceInfos) {
|
||||
if (detail.name.startsWith("ADDR:")) {
|
||||
// We already show the address above
|
||||
continue
|
||||
}
|
||||
addDynamicPref(headerDetails, detail.name.replace(": *$".toRegex(), ""), detail.details)
|
||||
}
|
||||
|
||||
@@ -59,6 +86,46 @@ class DeviceDebugFragment : AbstractDebugFragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun setDeviceType(gbDevice: GBDevice, newType: DeviceType) {
|
||||
LOG.debug("Setting device {} type from {} to {}", gbDevice.address, gbDevice.type, newType)
|
||||
|
||||
if (gbDevice.type == newType) {
|
||||
GB.toast("Type is the same!", Toast.LENGTH_SHORT, GB.INFO)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
GBApplication.acquireDB().use { dbHandler ->
|
||||
val session = dbHandler.getDaoSession()
|
||||
DBHelper.updateDeviceType(session, gbDevice.address, newType)
|
||||
}
|
||||
} catch (e: java.lang.Exception) {
|
||||
LOG.error("Failed to update device type", e)
|
||||
GB.toast("Failed to update device type", Toast.LENGTH_LONG, GB.ERROR)
|
||||
return
|
||||
}
|
||||
|
||||
LOG.info("Restarting GB after device type update")
|
||||
|
||||
restart()
|
||||
}
|
||||
|
||||
private fun restart() {
|
||||
MaterialAlertDialogBuilder(requireActivity())
|
||||
.setCancelable(false)
|
||||
.setIcon(R.drawable.ic_sync)
|
||||
.setTitle(R.string.backup_restore_restart_title)
|
||||
.setMessage(getString(R.string.backup_restore_restart_summary, getString(R.string.app_name)))
|
||||
.setOnCancelListener((DialogInterface.OnCancelListener { _: DialogInterface? ->
|
||||
requireActivity().finishAffinity()
|
||||
GBApplication.restart()
|
||||
}))
|
||||
.setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int ->
|
||||
requireActivity().finishAffinity()
|
||||
GBApplication.restart()
|
||||
}.show()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOG: Logger = LoggerFactory.getLogger(DeviceDebugFragment::class.java)
|
||||
|
||||
|
||||
+3
-3
@@ -16,7 +16,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.welcome.WelcomeActivity
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCameraRemote
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.TestDeviceDialog
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceTypeDialog
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
@@ -31,8 +31,8 @@ class MainDebugFragment : AbstractDebugFragment() {
|
||||
setPreferencesFromResource(R.xml.debug_preferences_main, rootKey)
|
||||
|
||||
onClick(PREF_DEBUG_ADD_TEST_DEVICE) {
|
||||
TestDeviceDialog(requireActivity(), null).show { address, deviceType ->
|
||||
TestDeviceDialog.createTestDevice(requireContext(), deviceType, address, null)
|
||||
DeviceTypeDialog(requireActivity(), R.string.add_test_device, null).show { address, deviceType ->
|
||||
DeviceTypeDialog.createTestDevice(requireContext(), deviceType, address, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -95,7 +95,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.BondingUtil;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.TestDeviceDialog;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceTypeDialog;
|
||||
|
||||
|
||||
public class DiscoveryActivityV2 extends AbstractGBActivity implements AdapterView.OnItemClickListener,
|
||||
@@ -775,8 +775,8 @@ public class DiscoveryActivityV2 extends AbstractGBActivity implements AdapterVi
|
||||
private void showUnsupportedDeviceDialog(final GBDeviceCandidate deviceCandidate) {
|
||||
LOG.info("Unsupported device candidate selected: {}", deviceCandidate);
|
||||
|
||||
new TestDeviceDialog(this, deviceCandidate.getMacAddress())
|
||||
.show((macAddress, deviceType) -> {
|
||||
new DeviceTypeDialog(this, R.string.add_test_device, deviceCandidate.getMacAddress())
|
||||
.show(null, (macAddress, deviceType) -> {
|
||||
LOG.debug("Force-pairing {} as {}", deviceCandidate, deviceType);
|
||||
DeviceHelper.getInstance().setForcedDeviceType(deviceCandidate.getMacAddress().toLowerCase(), deviceType);
|
||||
preparePair(deviceCandidate);
|
||||
|
||||
+2
-2
@@ -380,9 +380,9 @@ public class IntentApiReceiver extends BroadcastReceiver {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.info("Quitting GB after device type update");
|
||||
LOG.info("Restarting GB after device type update");
|
||||
|
||||
GBApplication.quit();
|
||||
GBApplication.restart();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.text.Editable
|
||||
import android.text.InputFilter
|
||||
import android.text.InputType
|
||||
import android.text.Spanned
|
||||
import android.text.TextWatcher
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.EditText
|
||||
import android.widget.Toast
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import nodomain.freeyourgadget.gadgetbridge.BuildConfig
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication
|
||||
import nodomain.freeyourgadget.gadgetbridge.R
|
||||
import nodomain.freeyourgadget.gadgetbridge.adapter.SpinnerWithIconAdapter
|
||||
import nodomain.freeyourgadget.gadgetbridge.adapter.SpinnerWithIconItem
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper
|
||||
import nodomain.freeyourgadget.gadgetbridge.databinding.DialogTestDeviceBinding
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.util.Random
|
||||
import java.util.TreeMap
|
||||
import kotlin.collections.map
|
||||
|
||||
class DeviceTypeDialog(
|
||||
private val activity: Activity,
|
||||
private val dialogTitle: Int,
|
||||
private val macAddress: String?
|
||||
) {
|
||||
var selectedTestDeviceMAC = macAddress ?: randomMac()
|
||||
var selectedTestDeviceKey = -1L
|
||||
private lateinit var updateOkButtonState: (() -> Unit)
|
||||
|
||||
fun show(preselectedType: DeviceType? = null, onSelection: (String, DeviceType) -> Unit) {
|
||||
val binding = DialogTestDeviceBinding.inflate(activity.layoutInflater)
|
||||
|
||||
val allDevicesByName: MutableMap<String, DeviceTypeWithIcon> = getAllSupportedDevices(activity)
|
||||
|
||||
// Get unique manufacturers
|
||||
val manufacturerMap = mutableMapOf<String, MutableList<Map.Entry<String, DeviceTypeWithIcon>>>()
|
||||
val manufacturers = mutableSetOf<String>()
|
||||
for (entry in allDevicesByName.entries) {
|
||||
val manufacturer = entry.value.deviceType.getDeviceCoordinator().getManufacturer()
|
||||
manufacturers.add(manufacturer)
|
||||
manufacturerMap.getOrPut(manufacturer) { mutableListOf() }.add(entry)
|
||||
}
|
||||
|
||||
val manufacturerPriority = listOf(
|
||||
"Gadgetbridge",
|
||||
activity.getString(R.string.pref_header_generic),
|
||||
activity.getString(R.string.unknown)
|
||||
)
|
||||
val sortedManufacturers = manufacturers.toList().sortedWith(
|
||||
compareBy<String> { item ->
|
||||
val index = manufacturerPriority.indexOfFirst { it.equals(item, ignoreCase = true) }
|
||||
if (index >= 0) index else Int.MAX_VALUE
|
||||
}.thenBy(String.CASE_INSENSITIVE_ORDER) { it }
|
||||
)
|
||||
val manufacturerListArray = ArrayList<String>()
|
||||
manufacturerListArray.add(activity.getString(R.string.all_manufacturers))
|
||||
manufacturerListArray.addAll(sortedManufacturers)
|
||||
|
||||
// Create full device list
|
||||
val allDeviceListArray = allDevicesByName.entries
|
||||
.map { SpinnerWithIconItem(it.key, it.value.deviceType.ordinal.toLong(), it.value.icon) }
|
||||
.toCollection(ArrayList())
|
||||
|
||||
val currentDeviceList = ArrayList(allDeviceListArray)
|
||||
|
||||
val deviceListAdapter = SpinnerWithIconAdapter(
|
||||
activity,
|
||||
R.layout.spinner_with_image_layout,
|
||||
R.id.spinner_item_text,
|
||||
currentDeviceList
|
||||
)
|
||||
binding.deviceTypeDropdown.setAdapter(deviceListAdapter)
|
||||
binding.deviceTypeDropdown.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ ->
|
||||
val selectedItem = parent.getItemAtPosition(position) as SpinnerWithIconItem
|
||||
selectedTestDeviceKey = selectedItem.getId()
|
||||
updateOkButtonState.invoke()
|
||||
}
|
||||
|
||||
// Set up manufacturer dropdown
|
||||
binding.deviceManufacturerDropdown.setAdapter(
|
||||
ArrayAdapter(
|
||||
activity,
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
manufacturerListArray
|
||||
)
|
||||
)
|
||||
binding.deviceManufacturerDropdown.setText(activity.getString(R.string.all_manufacturers), false)
|
||||
binding.deviceManufacturerDropdown.onItemClickListener =
|
||||
AdapterView.OnItemClickListener { parent, _, position, _ ->
|
||||
val selectedManufacturer = parent.getItemAtPosition(position) as String
|
||||
|
||||
// Filter device list based on selected manufacturer
|
||||
currentDeviceList.clear()
|
||||
if (position == 0) {
|
||||
// Show all devices
|
||||
currentDeviceList.addAll(allDeviceListArray)
|
||||
} else {
|
||||
// Show only devices from selected manufacturer
|
||||
val filteredDevices = getFilteredDevices(selectedManufacturer, manufacturerMap)
|
||||
currentDeviceList.addAll(filteredDevices)
|
||||
}
|
||||
deviceListAdapter.notifyDataSetChanged()
|
||||
|
||||
// Reset device selection
|
||||
binding.deviceTypeDropdown.setText("", false)
|
||||
selectedTestDeviceKey = -1L
|
||||
updateOkButtonState.invoke()
|
||||
}
|
||||
|
||||
val dialog = MaterialAlertDialogBuilder(activity)
|
||||
.setCancelable(true)
|
||||
.setTitle(dialogTitle)
|
||||
.setView(binding.root)
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
onSelection.invoke(
|
||||
binding.macEditText.text.toString(),
|
||||
DeviceType.entries[selectedTestDeviceKey.toInt()]
|
||||
)
|
||||
}
|
||||
.setNegativeButton(R.string.Cancel) { _, _ -> }
|
||||
.create()
|
||||
|
||||
// Validate and update OK button state
|
||||
updateOkButtonState = {
|
||||
val positiveButton = dialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE)
|
||||
val isMacValid = isValidMacAddress(binding.macEditText.text.toString())
|
||||
val isDeviceSelected = selectedTestDeviceKey != -1L
|
||||
val typeIsDifferentFromDefault =
|
||||
preselectedType == null || preselectedType.ordinal.toLong() != selectedTestDeviceKey
|
||||
positiveButton?.isEnabled = isMacValid && isDeviceSelected && typeIsDifferentFromDefault
|
||||
}
|
||||
|
||||
dialog.setOnShowListener {
|
||||
updateOkButtonState.invoke()
|
||||
}
|
||||
|
||||
setupMacAddressInput(binding.macEditText)
|
||||
|
||||
// Preselect manufacturer and device type if provided
|
||||
preselectedType?.let { deviceType ->
|
||||
val coordinator = deviceType.getDeviceCoordinator()
|
||||
val manufacturer = when (coordinator.getManufacturer()) {
|
||||
"Unknown" -> activity.getString(R.string.unknown)
|
||||
"Generic" -> activity.getString(R.string.pref_header_generic)
|
||||
else -> coordinator.getManufacturer()
|
||||
}
|
||||
|
||||
// Set manufacturer dropdown
|
||||
if (manufacturer in sortedManufacturers) {
|
||||
binding.deviceManufacturerDropdown.setText(manufacturer, false)
|
||||
|
||||
// Filter device list based on selected manufacturer
|
||||
currentDeviceList.clear()
|
||||
val filteredDevices = getFilteredDevices(manufacturer, manufacturerMap)
|
||||
currentDeviceList.addAll(filteredDevices)
|
||||
deviceListAdapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
// Find and set the device type in the list
|
||||
val matchingItem = currentDeviceList.find { it.getId() == deviceType.ordinal.toLong() }
|
||||
matchingItem?.let {
|
||||
binding.deviceTypeDropdown.setText(it.getText(), false)
|
||||
selectedTestDeviceKey = it.getId()
|
||||
updateOkButtonState.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
private fun getFilteredDevices(
|
||||
manufacturer: String,
|
||||
manufacturerMap: Map<String, List<Map.Entry<String, DeviceTypeWithIcon>>>
|
||||
): List<SpinnerWithIconItem> {
|
||||
return manufacturerMap[manufacturer]?.map {
|
||||
SpinnerWithIconItem(
|
||||
it.key.replace("^${manufacturer} ".toRegex(), "")
|
||||
.replace(" \\(${manufacturer}\\)$".toRegex(), ""),
|
||||
it.value.deviceType.ordinal.toLong(),
|
||||
it.value.icon
|
||||
)
|
||||
} ?: emptyList()
|
||||
}
|
||||
|
||||
private fun getAllSupportedDevices(context: Context): MutableMap<String, DeviceTypeWithIcon> {
|
||||
var newMap = LinkedHashMap<String, DeviceTypeWithIcon>(1)
|
||||
for (deviceType in DeviceType.entries) {
|
||||
val coordinator = deviceType.getDeviceCoordinator()
|
||||
val icon = coordinator.getDefaultIconResource()
|
||||
var name = context.getString(coordinator.getDeviceNameResource())
|
||||
val manufacturer = when (coordinator.getManufacturer()) {
|
||||
"Unknown" -> context.getString(R.string.unknown)
|
||||
"Generic" -> context.getString(R.string.pref_header_generic)
|
||||
else -> coordinator.getManufacturer()
|
||||
}
|
||||
if (!name.startsWith(manufacturer)) {
|
||||
name += " (${manufacturer})"
|
||||
}
|
||||
newMap[name] = DeviceTypeWithIcon(deviceType, icon)
|
||||
}
|
||||
|
||||
val sortedMap = TreeMap<String, DeviceTypeWithIcon>(String.CASE_INSENSITIVE_ORDER)
|
||||
sortedMap.putAll(newMap)
|
||||
newMap = LinkedHashMap(sortedMap.size + 3)
|
||||
|
||||
// Ensure some devices are first
|
||||
//newMap[context.getString(R.string.devicetype_scannable)] =
|
||||
// DeviceTypeWithIcon(DeviceType.SCANNABLE, R.drawable.ic_device_scannable)
|
||||
//newMap[context.getString(R.string.devicetype_ble_gatt_client)] =
|
||||
// DeviceTypeWithIcon(DeviceType.BLE_GATT_CLIENT, R.drawable.ic_device_scannable)
|
||||
|
||||
newMap.putAll(sortedMap)
|
||||
|
||||
return newMap
|
||||
}
|
||||
|
||||
private fun setupMacAddressInput(editText: EditText) {
|
||||
editText.inputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
|
||||
|
||||
if (macAddress != null) {
|
||||
editText.isEnabled = false
|
||||
}
|
||||
|
||||
// help the user to input a properly formated MAC - see BluetoothAdapter.checkBluetoothAddress
|
||||
// for Bangle.js builds: also support pebble emulator addresses
|
||||
editText.filters = arrayOf(object : InputFilter {
|
||||
@Suppress("KotlinConstantConditions")
|
||||
override fun filter(
|
||||
source: CharSequence,
|
||||
start: Int, end: Int,
|
||||
dest: Spanned,
|
||||
dstart: Int, dend: Int
|
||||
): CharSequence {
|
||||
val builder = StringBuilder()
|
||||
for (i in start..<end) {
|
||||
val c = source[i]
|
||||
if ((c in '0'..'9') || (c in 'A'..'F') || c == ':') {
|
||||
builder.append(c)
|
||||
} else if (c in 'a'..'f') {
|
||||
builder.append((c.code - 'a'.code + 'A'.code).toChar())
|
||||
} else if (BuildConfig.INTERNET_ACCESS) {
|
||||
builder.append(c)
|
||||
} else if (c == '-') {
|
||||
builder.append(':')
|
||||
}
|
||||
}
|
||||
return builder
|
||||
}
|
||||
})
|
||||
|
||||
editText.setText(selectedTestDeviceMAC)
|
||||
editText.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(charSequence: CharSequence?, i: Int, i1: Int, i2: Int) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(charSequence: CharSequence?, i: Int, i1: Int, i2: Int) {
|
||||
}
|
||||
|
||||
override fun afterTextChanged(editable: Editable) {
|
||||
selectedTestDeviceMAC = editable.toString()
|
||||
updateOkButtonState.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private data class DeviceTypeWithIcon(val deviceType: DeviceType, val icon: Int)
|
||||
|
||||
companion object {
|
||||
private val LOG: Logger = LoggerFactory.getLogger(DeviceTypeDialog::class.java)
|
||||
|
||||
private fun isValidMacAddress(mac: String): Boolean {
|
||||
if (BuildConfig.INTERNET_ACCESS) {
|
||||
// For builds with internet access (Bangle.js), allow more flexible formats
|
||||
return mac.isNotEmpty()
|
||||
}
|
||||
// Standard MAC address validation: XX:XX:XX:XX:XX:XX
|
||||
val macRegex = "^([0-9A-F]{2}:){5}[0-9A-F]{2}$".toRegex()
|
||||
return macRegex.matches(mac)
|
||||
}
|
||||
|
||||
private fun randomMac(): String {
|
||||
val random = Random()
|
||||
return String.format(
|
||||
"%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
random.nextInt(0xff),
|
||||
random.nextInt(0xff),
|
||||
random.nextInt(0xff),
|
||||
random.nextInt(0xff),
|
||||
random.nextInt(0xff),
|
||||
random.nextInt(0xff)
|
||||
)
|
||||
}
|
||||
|
||||
fun createTestDevice(
|
||||
context: Context,
|
||||
deviceType: DeviceType,
|
||||
deviceMac: String,
|
||||
inputDeviceName: String?
|
||||
) {
|
||||
val deviceNameResource = deviceType.getDeviceCoordinator().getDeviceNameResource()
|
||||
val deviceName: String =
|
||||
inputDeviceName ?: if (deviceNameResource == 0) deviceType.name else context.getString(
|
||||
deviceNameResource
|
||||
)
|
||||
|
||||
try {
|
||||
GBApplication.acquireDB().use { db ->
|
||||
val daoSession = db.getDaoSession()
|
||||
val gbDevice = GBDevice(deviceMac, deviceName, "", null, deviceType)
|
||||
gbDevice.firmwareVersion = "N/A"
|
||||
gbDevice.firmwareVersion2 = "N/A"
|
||||
|
||||
//this causes the attributes (fw version) to be stored as well. Not much useful, but still...
|
||||
gbDevice.setState(GBDevice.State.INITIALIZED)
|
||||
|
||||
DBHelper.getDevice(gbDevice, daoSession) //the addition happens here
|
||||
|
||||
val refreshIntent = Intent(DeviceManager.ACTION_REFRESH_DEVICELIST)
|
||||
LocalBroadcastManager.getInstance(context).sendBroadcast(refreshIntent)
|
||||
GB.toast(context, "Added test device: $deviceName", Toast.LENGTH_SHORT, GB.INFO)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
LOG.error("Error accessing database", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1837,6 +1837,7 @@
|
||||
<string name="devicetype_unknown">Unknown Device</string>
|
||||
<string name="devicetype_test" translatable="false">Test Device</string>
|
||||
<string name="add_test_device">Add test device</string>
|
||||
<string name="set_device_type">Set device type</string>
|
||||
<string name="devicetype_pebble" translatable="false">Pebble</string>
|
||||
<string name="devicetype_miband" translatable="false">Mi Band</string>
|
||||
<string name="devicetype_miband2" translatable="false">Mi Band 2</string>
|
||||
|
||||
Reference in New Issue
Block a user