switching away from kotlin-android-extensions

This commit is contained in:
Kevin Hester 2020-12-07 20:33:29 +08:00
parent cc2b99fdfc
commit 2e30dbcdd0
10 changed files with 191 additions and 170 deletions

View file

@ -34,6 +34,7 @@ import com.geeksville.mesh.MainActivity
import com.geeksville.mesh.R
import com.geeksville.mesh.android.bluetoothManager
import com.geeksville.mesh.android.usbManager
import com.geeksville.mesh.databinding.SettingsFragmentBinding
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.service.BluetoothInterface
import com.geeksville.mesh.service.MeshService
@ -46,7 +47,6 @@ import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.LocationSettingsRequest
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.hoho.android.usbserial.driver.UsbSerialDriver
import kotlinx.android.synthetic.main.settings_fragment.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@ -452,6 +452,10 @@ class BTScanModel(app: Application) : AndroidViewModel(app), Logging {
@SuppressLint("NewApi")
class SettingsFragment : ScreenFragment("Settings"), Logging {
private var _binding: SettingsFragmentBinding? = null
// This property is only valid between onCreateView and onDestroyView.
private val binding get() = _binding!!
private val scanModel: BTScanModel by activityViewModels()
private val model: UIViewModel by activityViewModels()
@ -478,23 +482,23 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
mainScope.handledLaunch {
debug("User started firmware update")
updateFirmwareButton.isEnabled = false // Disable until things complete
updateProgressBar.visibility = View.VISIBLE
updateProgressBar.progress = 0 // start from scratch
binding.updateFirmwareButton.isEnabled = false // Disable until things complete
binding.updateProgressBar.visibility = View.VISIBLE
binding.updateProgressBar.progress = 0 // start from scratch
scanStatusText.text = "Updating firmware, wait up to eight minutes..."
binding.scanStatusText.text = "Updating firmware, wait up to eight minutes..."
try {
service.startFirmwareUpdate()
while (service.updateStatus >= 0) {
updateProgressBar.progress = service.updateStatus
binding.updateProgressBar.progress = service.updateStatus
delay(2000) // Only check occasionally
}
} finally {
val isSuccess = (service.updateStatus == -1)
scanStatusText.text =
binding.scanStatusText.text =
if (isSuccess) "Update successful" else "Update failed"
updateProgressBar.isEnabled = false
updateFirmwareButton.isEnabled = !isSuccess
binding.updateProgressBar.isEnabled = false
binding.updateFirmwareButton.isEnabled = !isSuccess
}
}
}
@ -504,7 +508,8 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.settings_fragment, container, false)
_binding = SettingsFragmentBinding.inflate(inflater, container, false)
return binding.root
}
private fun initNodeInfo() {
@ -513,36 +518,36 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
// If actively connected possibly let the user update firmware
val info = model.myNodeInfo.value
if (connected == MeshService.ConnectionState.CONNECTED && info != null && info.shouldUpdate && info.couldUpdate) {
updateFirmwareButton.visibility = View.VISIBLE
updateFirmwareButton.isEnabled = true
updateFirmwareButton.text =
binding.updateFirmwareButton.visibility = View.VISIBLE
binding.updateFirmwareButton.isEnabled = true
binding.updateFirmwareButton.text =
getString(R.string.update_to).format(getString(R.string.cur_firmware_version))
} else {
updateFirmwareButton.visibility = View.GONE
updateProgressBar.visibility = View.GONE
binding.updateFirmwareButton.visibility = View.GONE
binding.updateProgressBar.visibility = View.GONE
}
when (connected) {
MeshService.ConnectionState.CONNECTED -> {
val fwStr = info?.firmwareString ?: ""
scanStatusText.text = getString(R.string.connected_to).format(fwStr)
binding.scanStatusText.text = getString(R.string.connected_to).format(fwStr)
}
MeshService.ConnectionState.DISCONNECTED ->
scanStatusText.text = getString(R.string.not_connected)
binding.scanStatusText.text = getString(R.string.not_connected)
MeshService.ConnectionState.DEVICE_SLEEP ->
scanStatusText.text = getString(R.string.connected_sleeping)
binding.scanStatusText.text = getString(R.string.connected_sleeping)
}
}
/// Setup the ui widgets unrelated to BLE scanning
private fun initCommonUI() {
model.ownerName.observe(viewLifecycleOwner, Observer { name ->
usernameEditText.setText(name)
binding.usernameEditText.setText(name)
})
// Only let user edit their name or set software update while connected to a radio
model.isConnected.observe(viewLifecycleOwner, Observer { connected ->
usernameView.isEnabled = connected == MeshService.ConnectionState.CONNECTED
binding.usernameView.isEnabled = connected == MeshService.ConnectionState.CONNECTED
if (connected == MeshService.ConnectionState.DISCONNECTED)
model.ownerName.value = ""
initNodeInfo()
@ -553,13 +558,13 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
initNodeInfo()
})
updateFirmwareButton.setOnClickListener {
binding.updateFirmwareButton.setOnClickListener {
doFirmwareUpdate()
}
usernameEditText.on(EditorInfo.IME_ACTION_DONE) {
binding.usernameEditText.on(EditorInfo.IME_ACTION_DONE) {
debug("did IME action")
val n = usernameEditText.text.toString().trim()
val n = binding.usernameEditText.text.toString().trim()
if (n.isNotEmpty())
model.setOwner(n)
@ -569,17 +574,17 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
val app = (requireContext().applicationContext as GeeksvilleApplication)
// Set analytics checkbox
analyticsOkayCheckbox.isChecked = app.isAnalyticsAllowed
binding.analyticsOkayCheckbox.isChecked = app.isAnalyticsAllowed
analyticsOkayCheckbox.setOnCheckedChangeListener { _, isChecked ->
binding.analyticsOkayCheckbox.setOnCheckedChangeListener { _, isChecked ->
debug("User changed analytics to $isChecked")
app.isAnalyticsAllowed = isChecked
reportBugButton.isEnabled = app.isAnalyticsAllowed
binding.reportBugButton.isEnabled = app.isAnalyticsAllowed
}
// report bug button only enabled if analytics is allowed
reportBugButton.isEnabled = app.isAnalyticsAllowed
reportBugButton.setOnClickListener {
binding.reportBugButton.isEnabled = app.isAnalyticsAllowed
binding.reportBugButton.setOnClickListener {
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.report_a_bug)
.setMessage(getString(R.string.report_bug_text))
@ -600,34 +605,34 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
b.isEnabled = enabled
b.isChecked =
device.address == scanModel.selectedNotNull && device.bonded // Only show checkbox if device is still paired
deviceRadioGroup.addView(b)
binding.deviceRadioGroup.addView(b)
// Once we have at least one device, don't show the "looking for" animation - it makes uers think
// something is busted
scanProgressBar.visibility = View.INVISIBLE
binding.scanProgressBar.visibility = View.INVISIBLE
b.setOnClickListener {
if (!device.bonded) // If user just clicked on us, try to bond
scanStatusText.setText(R.string.starting_pairing)
binding.scanStatusText.setText(R.string.starting_pairing)
b.isChecked =
scanModel.onSelected(requireActivity() as MainActivity, device)
if (!b.isSelected)
scanStatusText.setText(getString(R.string.please_pair))
binding.scanStatusText.setText(getString(R.string.please_pair))
}
}
/// Show the GUI for classic scanning
private fun showClassicWidgets(visible: Int) {
scanProgressBar.visibility = visible
deviceRadioGroup.visibility = visible
binding.scanProgressBar.visibility = visible
binding.deviceRadioGroup.visibility = visible
}
/// Setup the GUI to do a classic (pre SDK 26 BLE scan)
private fun initClassicScan() {
// Turn off the widgets for the new API (we turn on/off hte classic widgets when we start scanning
changeRadioButton.visibility = View.GONE
binding.changeRadioButton.visibility = View.GONE
showClassicWidgets(View.VISIBLE)
@ -640,13 +645,13 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
scanModel.errorText.observe(viewLifecycleOwner, Observer { errMsg ->
if (errMsg != null) {
scanStatusText.text = errMsg
binding.scanStatusText.text = errMsg
}
})
scanModel.devices.observe(viewLifecycleOwner, Observer { devices ->
// Remove the old radio buttons and repopulate
deviceRadioGroup.removeAllViews()
binding.deviceRadioGroup.removeAllViews()
val adapter = scanModel.bluetoothAdapter
@ -690,14 +695,14 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
RadioInterfaceService.getBondedDeviceAddress(requireContext()) != null
// get rid of the warning text once at least one device is paired
warningNotPaired.visibility = if (hasBonded) View.GONE else View.VISIBLE
binding.warningNotPaired.visibility = if (hasBonded) View.GONE else View.VISIBLE
})
}
/// Start running the modern scan, once it has one result we enable the
private fun startBackgroundScan() {
// Disable the change button until our scan has some results
changeRadioButton.isEnabled = false
binding.changeRadioButton.isEnabled = false
// To skip filtering based on name and supported feature flags (UUIDs),
// don't include calls to setNamePattern() and addServiceUuid(),
@ -726,8 +731,8 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
override fun onDeviceFound(chooserLauncher: IntentSender) {
debug("Found one device - enabling button")
changeRadioButton.isEnabled = true
changeRadioButton.setOnClickListener {
binding.changeRadioButton.isEnabled = true
binding.changeRadioButton.setOnClickListener {
debug("User clicked BLE change button")
// Request code seems to be ignored anyways
@ -748,18 +753,18 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
private fun initModernScan() {
// Turn off the widgets for the classic API
scanProgressBar.visibility = View.GONE
deviceRadioGroup.visibility = View.GONE
changeRadioButton.visibility = View.VISIBLE
binding.scanProgressBar.visibility = View.GONE
binding.deviceRadioGroup.visibility = View.GONE
binding.changeRadioButton.visibility = View.VISIBLE
val curRadio = RadioInterfaceService.getBondedDeviceAddress(requireContext())
if (curRadio != null) {
scanStatusText.text = getString(R.string.current_pair).format(curRadio)
changeRadioButton.text = getString(R.string.change_radio)
binding.scanStatusText.text = getString(R.string.current_pair).format(curRadio)
binding.changeRadioButton.text = getString(R.string.change_radio)
} else {
scanStatusText.text = getString(R.string.not_paired_yet)
changeRadioButton.setText(R.string.select_radio)
binding.scanStatusText.text = getString(R.string.not_paired_yet)
binding.changeRadioButton.setText(R.string.select_radio)
}
startBackgroundScan()