mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-05 06:33:52 -04:00
Merge remote-tracking branch 'root/master' into dev
This commit is contained in:
@@ -4,6 +4,8 @@ import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.nio.charset.Charset
|
||||
|
||||
|
||||
@Parcelize
|
||||
enum class MessageStatus : Parcelable {
|
||||
@@ -143,6 +145,8 @@ data class DataPacket(
|
||||
override fun newArray(size: Int): Array<DataPacket?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
val utf8 = Charset.forName("UTF-8")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -7,10 +7,7 @@ import android.bluetooth.BluetoothAdapter
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.bluetooth.BluetoothManager
|
||||
import android.companion.CompanionDeviceManager
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.*
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.hardware.usb.UsbDevice
|
||||
@@ -28,7 +25,9 @@ import android.view.View
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
@@ -379,6 +378,9 @@ class MainActivity : AppCompatActivity(), Logging,
|
||||
val prefs = UIViewModel.getPreferences(this)
|
||||
model.ownerName.value = prefs.getString("owner", "")!!
|
||||
|
||||
/// Set theme
|
||||
setUITheme(prefs)
|
||||
|
||||
/// Set initial bluetooth state
|
||||
updateBluetoothEnabled()
|
||||
|
||||
@@ -1068,6 +1070,10 @@ class MainActivity : AppCompatActivity(), Logging,
|
||||
startActivityForResult(intent, CREATE_CSV_FILE)
|
||||
return true
|
||||
}
|
||||
R.id.theme -> {
|
||||
chooseThemeDialog()
|
||||
return true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
@@ -1114,5 +1120,80 @@ class MainActivity : AppCompatActivity(), Logging,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Theme functions
|
||||
|
||||
private fun chooseThemeDialog() {
|
||||
|
||||
/// Prepare dialog and its items
|
||||
val builder = AlertDialog.Builder(this)
|
||||
builder.setTitle(getString(R.string.choose_theme_title))
|
||||
|
||||
val styles = arrayOf(
|
||||
getString(R.string.theme_light),
|
||||
getString(R.string.theme_dark),
|
||||
getString(R.string.theme_system))
|
||||
|
||||
/// Load preferences and its value
|
||||
val prefs = UIViewModel.getPreferences(this)
|
||||
val editor: SharedPreferences.Editor = prefs.edit()
|
||||
val checkedItem = prefs.getInt("theme", 2)
|
||||
|
||||
builder.setSingleChoiceItems(styles, checkedItem) { dialog, which ->
|
||||
|
||||
when (which) {
|
||||
0 -> {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
||||
editor.putInt("theme", 0)
|
||||
editor.apply()
|
||||
|
||||
delegate.applyDayNight()
|
||||
dialog.dismiss()
|
||||
}
|
||||
1 -> {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
||||
editor.putInt("theme", 1)
|
||||
editor.apply()
|
||||
|
||||
delegate.applyDayNight()
|
||||
dialog.dismiss()
|
||||
}
|
||||
2 -> {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||
editor.putInt("theme", 2)
|
||||
editor.apply()
|
||||
|
||||
delegate.applyDayNight()
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
val dialog = builder.create()
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
private fun setUITheme(prefs: SharedPreferences) {
|
||||
/// Read theme settings from preferences and set it
|
||||
/// If nothing is found set FOLLOW SYSTEM option
|
||||
|
||||
when (prefs.getInt("theme", 2)) {
|
||||
0 -> {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
|
||||
delegate.applyDayNight()
|
||||
}
|
||||
1 -> {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
|
||||
delegate.applyDayNight()
|
||||
}
|
||||
2 -> {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||
delegate.applyDayNight()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -191,57 +191,27 @@ class BTScanModel(app: Application) : AndroidViewModel(app), Logging {
|
||||
val oldDevs = devices.value!!
|
||||
val oldEntry = oldDevs[fullAddr]
|
||||
if (oldEntry == null || oldEntry.bonded != isBonded) { // Don't spam the GUI with endless updates for non changing nodes
|
||||
|
||||
val skipBogus = try {
|
||||
// Note Soyes XS has a buggy BLE scan implementation and returns devices we didn't ask for. So we check to see if the
|
||||
// last two chars of the name matches the last two of the address - if not we skip it
|
||||
|
||||
// Note: the address is always two more than the hex string we show in the name
|
||||
|
||||
// nasty parsing of a string that ends with ab:45 as four hex digits
|
||||
val lastAddr = (addr.substring(
|
||||
addr.length - 5,
|
||||
addr.length - 3
|
||||
) + addr.substring(addr.length - 2)).toInt(16)
|
||||
|
||||
val lastName =
|
||||
result.device.name.substring(result.device.name.length - 4).toInt(16)
|
||||
|
||||
// ESP32 macaddr are two higher than the reported device name
|
||||
// NRF52 macaddrs match the portion used in the string
|
||||
// either would be acceptable
|
||||
(lastAddr - 2) != lastName && lastAddr != lastName
|
||||
} catch (ex: Throwable) {
|
||||
false // If we fail parsing anything, don't do this nasty hack
|
||||
val entry = DeviceListEntry(
|
||||
result.device.name
|
||||
?: "unnamed-$addr", // autobug: some devices might not have a name, if someone is running really old device code?
|
||||
fullAddr,
|
||||
isBonded
|
||||
)
|
||||
// If nothing was selected, by default select the first valid thing we see
|
||||
val activity: MainActivity? = try {
|
||||
GeeksvilleApplication.currentActivity as MainActivity? // Can be null if app is shutting down
|
||||
} catch (_: ClassCastException) {
|
||||
// Buggy "Z812" phones apparently have the wrong class type for this
|
||||
errormsg("Unexpected class for main activity")
|
||||
null
|
||||
}
|
||||
|
||||
if (skipBogus)
|
||||
errormsg("Skipping bogus BLE entry $result")
|
||||
else {
|
||||
val entry = DeviceListEntry(
|
||||
result.device.name
|
||||
?: "unnamed-$addr", // autobug: some devices might not have a name, if someone is running really old device code?
|
||||
fullAddr,
|
||||
isBonded
|
||||
if (selectedAddress == null && entry.bonded && activity != null)
|
||||
changeScanSelection(
|
||||
activity,
|
||||
fullAddr
|
||||
)
|
||||
debug("onScanResult ${entry}")
|
||||
|
||||
// If nothing was selected, by default select the first valid thing we see
|
||||
val activity: MainActivity? = try {
|
||||
GeeksvilleApplication.currentActivity as MainActivity? // Can be null if app is shutting down
|
||||
} catch (_: ClassCastException) {
|
||||
// Buggy "Z812" phones apparently have the wrong class type for this
|
||||
errormsg("Unexpected class for main activity")
|
||||
null
|
||||
}
|
||||
|
||||
if (selectedAddress == null && entry.bonded && activity != null)
|
||||
changeScanSelection(
|
||||
activity,
|
||||
fullAddr
|
||||
)
|
||||
addDevice(entry) // Add/replace entry
|
||||
}
|
||||
addDevice(entry) // Add/replace entry
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user