Merge pull request #373 from meshtastic/release

1.2.58
This commit is contained in:
Andre Kirchhoff 2022-02-13 08:42:41 -03:00 committed by GitHub
commit 69dc99cdbc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 65 deletions

View file

@ -43,8 +43,8 @@ android {
applicationId "com.geeksville.mesh" applicationId "com.geeksville.mesh"
minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works) minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works)
targetSdkVersion 30 // 30 can't work until an explicit location permissions dialog is added targetSdkVersion 30 // 30 can't work until an explicit location permissions dialog is added
versionCode 20257 // format is Mmmss (where M is 1+the numeric major number versionCode 20258 // format is Mmmss (where M is 1+the numeric major number
versionName "1.2.57" versionName "1.2.58"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
// per https://developer.android.com/studio/write/vector-asset-studio // per https://developer.android.com/studio/write/vector-asset-studio

View file

@ -737,24 +737,32 @@ class MainActivity : AppCompatActivity(), Logging,
} }
private fun showSnackbar(msgId: Int) { private fun showSnackbar(msgId: Int) {
Snackbar.make( try {
findViewById(android.R.id.content), Snackbar.make(
msgId, findViewById(android.R.id.content),
Snackbar.LENGTH_LONG msgId,
).show() Snackbar.LENGTH_LONG
).show()
} catch (ex: IllegalStateException) {
reportError("Snackbar couldn't find view for msgId $msgId")
}
} }
private fun showSnackbar(msg: String) { private fun showSnackbar(msg: String) {
Snackbar.make( try {
findViewById(android.R.id.content), Snackbar.make(
msg, findViewById(android.R.id.content),
Snackbar.LENGTH_INDEFINITE msg,
) Snackbar.LENGTH_INDEFINITE
.apply { view.findViewById<TextView>(R.id.snackbar_text).isSingleLine = false } )
.setAction(R.string.okay) { .apply { view.findViewById<TextView>(R.id.snackbar_text).isSingleLine = false }
// dismiss .setAction(R.string.okay) {
} // dismiss
.show() }
.show()
} catch (ex: IllegalStateException) {
reportError("Snackbar couldn't find view for msgString $msg")
}
} }
fun perhapsChangeChannel(url: Uri? = requestedChannelUrl) { fun perhapsChangeChannel(url: Uri? = requestedChannelUrl) {

View file

@ -25,6 +25,7 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.BufferedWriter import java.io.BufferedWriter
import java.io.FileNotFoundException
import java.io.FileWriter import java.io.FileWriter
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@ -350,12 +351,16 @@ class UIViewModel @Inject constructor(
private suspend inline fun writeToUri(uri: Uri, crossinline block: suspend (BufferedWriter) -> Unit) { private suspend inline fun writeToUri(uri: Uri, crossinline block: suspend (BufferedWriter) -> Unit) {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
app.contentResolver.openFileDescriptor(uri, "wt")?.use { parcelFileDescriptor -> try {
FileWriter(parcelFileDescriptor.fileDescriptor).use { fileWriter -> app.contentResolver.openFileDescriptor(uri, "wt")?.use { parcelFileDescriptor ->
BufferedWriter(fileWriter).use { writer -> FileWriter(parcelFileDescriptor.fileDescriptor).use { fileWriter ->
block.invoke(writer) BufferedWriter(fileWriter).use { writer ->
block.invoke(writer)
}
} }
} }
} catch (ex: FileNotFoundException) {
errormsg("Can't write file error: ${ex.message}")
} }
} }
} }

View file

@ -112,15 +112,14 @@ class BluetoothInterface(val service: RadioInterfaceService, val address: String
/** Return true if this address is still acceptable. For BLE that means, still bonded */ /** Return true if this address is still acceptable. For BLE that means, still bonded */
@SuppressLint("NewApi", "MissingPermission") @SuppressLint("NewApi", "MissingPermission")
override fun addressValid(context: Context, rest: String): Boolean { override fun addressValid(context: Context, rest: String): Boolean {
val allPaired = if (hasCompanionDeviceApi(context)) { /* val allPaired = if (hasCompanionDeviceApi(context)) {
val deviceManager: CompanionDeviceManager by lazy { val deviceManager: CompanionDeviceManager by lazy {
context.getSystemService(Context.COMPANION_DEVICE_SERVICE) as CompanionDeviceManager context.getSystemService(Context.COMPANION_DEVICE_SERVICE) as CompanionDeviceManager
} }
deviceManager.associations.map { it }.toSet() deviceManager.associations.map { it }.toSet()
} else { } else { */
getBluetoothAdapter(context)?.bondedDevices.orEmpty() val allPaired = getBluetoothAdapter(context)?.bondedDevices.orEmpty()
.map { it.address }.toSet() .map { it.address }.toSet()
}
return if (!allPaired.contains(rest)) { return if (!allPaired.contains(rest)) {
warn("Ignoring stale bond to ${rest.anonymize}") warn("Ignoring stale bond to ${rest.anonymize}")
false false

View file

@ -286,22 +286,6 @@ class RadioInterfaceService : Service(), Logging {
debug("Setting bonded device to ${address.anonymize}") debug("Setting bonded device to ${address.anonymize}")
// We only keep an association to one device at a time... (move to BluetoothInterface?)
if (BluetoothInterface.hasCompanionDeviceApi(this)) {
if (address != null) {
val deviceManager = getSystemService(CompanionDeviceManager::class.java)
val c = address[0]
val rest = address.substring(1)
deviceManager.associations.forEach { old ->
if (rest != old) {
debug("Forgetting old BLE association ${old.anonymize}")
deviceManager.disassociate(old)
}
}
}
}
getPrefs(this).edit(commit = true) { getPrefs(this).edit(commit = true) {
if (address == null) if (address == null)
this.remove(DEVADDR_KEY) this.remove(DEVADDR_KEY)

View file

@ -813,7 +813,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
if (curRadio != null && !MockInterface.addressValid(requireContext(), "")) { if (curRadio != null && !MockInterface.addressValid(requireContext(), "")) {
binding.warningNotPaired.visibility = View.GONE binding.warningNotPaired.visibility = View.GONE
// binding.scanStatusText.text = getString(R.string.current_pair).format(curRadio) // binding.scanStatusText.text = getString(R.string.current_pair).format(curRadio)
} else { } else if (model.bluetoothEnabled.value == true){
binding.warningNotPaired.visibility = View.VISIBLE binding.warningNotPaired.visibility = View.VISIBLE
binding.scanStatusText.text = getString(R.string.not_paired_yet) binding.scanStatusText.text = getString(R.string.not_paired_yet)
} }
@ -883,7 +883,6 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
deviceManager.associate( deviceManager.associate(
pairingRequest, pairingRequest,
object : CompanionDeviceManager.Callback() { object : CompanionDeviceManager.Callback() {
override fun onDeviceFound(chooserLauncher: IntentSender) { override fun onDeviceFound(chooserLauncher: IntentSender) {
debug("Found one device - enabling changeRadioButton") debug("Found one device - enabling changeRadioButton")
binding.changeRadioButton.isEnabled = true binding.changeRadioButton.isEnabled = true
@ -914,8 +913,6 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
updateDevicesButtons(devices) updateDevicesButtons(devices)
startCompanionScan() startCompanionScan()
} }
startCompanionScan()
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -952,13 +949,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
fun weNeedAccess(warningReason: String) { fun weNeedAccess(warningReason: String) {
warn("Telling user we need need location access") warn("Telling user we need need location access")
showSnackbar(warningReason)
Snackbar.make(requireView(), warningReason, Snackbar.LENGTH_INDEFINITE)
.apply { view.findViewById<TextView>(R.id.snackbar_text).isSingleLine = false }
.setAction(R.string.okay) {
// dismiss
}
.show()
} }
locationSettingsResponse.addOnSuccessListener { locationSettingsResponse.addOnSuccessListener {
@ -1001,6 +992,23 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
} }
} }
private fun showSnackbar(msg: String) {
try {
Snackbar.make(
requireView(),
msg,
Snackbar.LENGTH_INDEFINITE
)
.apply { view.findViewById<TextView>(R.id.snackbar_text).isSingleLine = false }
.setAction(R.string.okay) {
// dismiss
}
.show()
} catch (ex: IllegalStateException) {
reportError("Snackbar couldn't find view for msgString $msg")
}
}
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
@ -1022,15 +1030,7 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
if (!hasUSB) { if (!hasUSB) {
// Warn user if BLE is disabled // Warn user if BLE is disabled
if (scanModel.bluetoothAdapter?.isEnabled != true) { if (scanModel.bluetoothAdapter?.isEnabled != true) {
Snackbar.make( showSnackbar(getString(R.string.error_bluetooth))
requireView(),
R.string.error_bluetooth,
Snackbar.LENGTH_INDEFINITE
)
.setAction(R.string.okay) {
// dismiss
}
.show()
} else { } else {
if (binding.provideLocationCheckbox.isChecked) if (binding.provideLocationCheckbox.isChecked)
checkLocationEnabled(getString(R.string.location_disabled)) checkLocationEnabled(getString(R.string.location_disabled))
@ -1038,17 +1038,30 @@ class SettingsFragment : ScreenFragment("Settings"), Logging {
} }
} }
@SuppressLint("MissingPermission")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O if (hasCompanionDeviceApi && myActivity.hasConnectPermission()
&& requestCode == MainActivity.SELECT_DEVICE_REQUEST_CODE && requestCode == MainActivity.SELECT_DEVICE_REQUEST_CODE
&& resultCode == Activity.RESULT_OK && resultCode == Activity.RESULT_OK
) { ) {
val deviceToPair: BluetoothDevice = val deviceToPair: BluetoothDevice =
data?.getParcelableExtra(CompanionDeviceManager.EXTRA_DEVICE)!! data?.getParcelableExtra(CompanionDeviceManager.EXTRA_DEVICE)!!
if (deviceToPair.bondState != BOND_BONDED) {
deviceToPair.createBond() // We only keep an association to one device at a time...
deviceManager.associations.forEach { old ->
if (deviceToPair.address != old) {
debug("Forgetting old BLE association ${old.anonymize}")
deviceManager.disassociate(old)
}
} }
scanModel.changeScanSelection(myActivity, "x${deviceToPair.address}") scanModel.onSelected(
myActivity,
BTScanModel.DeviceListEntry(
deviceToPair.name,
"x${deviceToPair.address}",
deviceToPair.bondState == BOND_BONDED
)
)
} else { } else {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
} }