kopia lustrzana https://github.com/ge0rg/aprsdroid
Merge 22bcafeac6
into 859033e0d7
commit
001e474ec5
|
@ -89,6 +89,12 @@
|
|||
android:parentActivityName=".PrefsAct"
|
||||
android:launchMode="singleTop"
|
||||
/>
|
||||
<activity android:name=".CompressedPrefs"
|
||||
android:label="@string/p__location_compressed_settings"
|
||||
android:parentActivityName=".PrefsAct"
|
||||
android:launchMode="singleTop"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize" />
|
||||
|
||||
<activity android:name=".GoogleMapAct" android:label="@string/app_map"
|
||||
android:launchMode="singleTop"
|
||||
android:parentActivityName=".HubActivity"
|
||||
|
|
|
@ -110,4 +110,14 @@
|
|||
<item>460800</item>
|
||||
<item>921600</item>
|
||||
</string-array>
|
||||
<string-array name="compressed_mice_status">
|
||||
<item>Off Duty</item>
|
||||
<item>En Route</item>
|
||||
<item>In Service</item>
|
||||
<item>Returning</item>
|
||||
<item>Committed</item>
|
||||
<item>Special</item>
|
||||
<item>Priority</item>
|
||||
<item>EMERGENCY!</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
|
|
@ -249,6 +249,19 @@
|
|||
<string name="p_locsource_summary">Manual, Periodic or SmartBeaconing™</string>
|
||||
<string name="p__location">Location Settings</string>
|
||||
|
||||
<string name="p__location_compressed_beacons">Normal Compressed Beacons</string>
|
||||
<string name="p__location_compressed_beacons_on">Send Compressed Beacons</string>
|
||||
<string name="p__location_compressed_beacons_off">Send Uncompressed Beacons</string>
|
||||
|
||||
<string name="p__location_mice_beacons">Mic-E Compressed Beacons</string>
|
||||
<string name="p__location_mice_beacons_on">Send Mic-E Beacons</string>
|
||||
<string name="p__location_mice_beacons_off">Send Uncompressed Beacons</string>
|
||||
|
||||
<string name="p__location_compressed_settings">Compressed Beacon Settings</string>
|
||||
<string name="p__location_compressed_summary">Normal & Mic-E Compression</string>
|
||||
|
||||
<string name="p__location_mice_status">Mic-E Status</string>
|
||||
|
||||
<string name="p_smartbeaconing">SmartBeaconing™</string>
|
||||
<string name="p_sb_help">SmartBeaconing™ help</string>
|
||||
<string name="p_sb_fast_speed">Fast Speed [km/h]</string>
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="compressed_location"
|
||||
android:summaryOff="@string/p__location_compressed_beacons_off"
|
||||
android:summaryOn="@string/p__location_compressed_beacons_on"
|
||||
android:title="@string/p__location_compressed_beacons" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="compressed_mice"
|
||||
android:summaryOff="@string/p__location_mice_beacons_off"
|
||||
android:summaryOn="@string/p__location_mice_beacons_on"
|
||||
android:title="@string/p__location_mice_beacons" />
|
||||
|
||||
<de.duenndns.ListPreferenceWithValue
|
||||
android:key="p__location_mice_status"
|
||||
android:title="@string/p__location_mice_status"
|
||||
android:entries="@array/compressed_mice_status"
|
||||
android:entryValues="@array/compressed_mice_status"
|
||||
android:defaultValue="Off Duty"
|
||||
android:dialogTitle="@string/p__location_mice_status" />
|
||||
|
||||
</PreferenceScreen>
|
|
@ -52,6 +52,15 @@
|
|||
|
||||
<PreferenceCategory
|
||||
android:title="@string/p__position">
|
||||
<PreferenceScreen
|
||||
android:key="compressed_location"
|
||||
android:title="@string/p__location_compressed_settings"
|
||||
android:summary="@string/p__location_compressed_summary">
|
||||
|
||||
<intent android:action="android.intent.action.MAIN"
|
||||
android:targetPackage="org.aprsdroid.app"
|
||||
android:targetClass="org.aprsdroid.app.CompressedPrefs" />
|
||||
</PreferenceScreen>
|
||||
<PreferenceScreen
|
||||
android:key="p_symbol"
|
||||
android:title="@string/p_symbol"
|
||||
|
|
|
@ -7,6 +7,179 @@ import scala.math.abs
|
|||
|
||||
object AprsPacket {
|
||||
val QRG_RE = ".*?(\\d{2,3}[.,]\\d{3,4}).*?".r
|
||||
val characters = Array(
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D",
|
||||
"E", "F", "G", "H", "I", "J", "K", "L", "P", "Q", "R", "S", "T", "U", "V",
|
||||
"W", "X", "Y", "Z"
|
||||
)
|
||||
|
||||
def statusToBits(status: String): (Int, Int, Int) = status match {
|
||||
case "Off Duty" => (1, 1, 1)
|
||||
case "En Route" => (1, 1, 0)
|
||||
case "In Service" => (1, 0, 1)
|
||||
case "Returning" => (1, 0, 0)
|
||||
case "Committed" => (0, 1, 1)
|
||||
case "Special" => (0, 1, 0)
|
||||
case "Priority" => (0, 0, 1)
|
||||
case "EMERGENCY!" => (0, 0, 0)
|
||||
case _ => (1, 1, 1) // Default if status is not found
|
||||
}
|
||||
|
||||
def degreesToDDM(dd: Double): (Int, Double) = {
|
||||
val degrees = Math.floor(dd).toInt
|
||||
val minutes = (dd - degrees) * 60
|
||||
(degrees, minutes)
|
||||
}
|
||||
|
||||
def miceLong(dd: Double): (Int, Int, Int) = {
|
||||
val (degrees, minutes) = degreesToDDM(Math.abs(dd))
|
||||
val minutesInt = Math.floor(minutes).toInt
|
||||
val minutesHundreths = Math.floor(100 * (minutes - minutesInt)).toInt
|
||||
(degrees, minutesInt, minutesHundreths)
|
||||
}
|
||||
|
||||
|
||||
def encodeDest(dd: Double, longOffset: Int, west: Int, messageA: Int, messageB: Int, messageC: Int, ambiguity: Int): String = {
|
||||
val north = if (dd < 0) 0 else 1
|
||||
|
||||
val (degrees, minutes, minutesHundreths) = miceLong(dd)
|
||||
|
||||
val degrees10 = Math.floor(degrees / 10.0).toInt
|
||||
val degrees1 = degrees - (degrees10 * 10)
|
||||
|
||||
val minutes10 = Math.floor(minutes / 10.0).toInt
|
||||
val minutes1 = minutes - (minutes10 * 10)
|
||||
|
||||
val minutesHundreths10 = Math.floor(minutesHundreths / 10.0).toInt
|
||||
val minutesHundreths1 = minutesHundreths - (minutesHundreths10 * 10)
|
||||
|
||||
val sb = new StringBuilder
|
||||
|
||||
if (messageA == 1) sb.append(characters(degrees10 + 22)) else sb.append(characters(degrees10))
|
||||
if (messageB == 1) sb.append(characters(degrees1 + 22)) else sb.append(characters(degrees1))
|
||||
if (messageC == 1) sb.append(characters(minutes10 + 22)) else sb.append(characters(minutes10))
|
||||
|
||||
if (north == 1) sb.append(characters(minutes1 + 22)) else sb.append(characters(minutes1))
|
||||
if (longOffset == 1) sb.append(characters(minutesHundreths10 + 22)) else sb.append(characters(minutesHundreths10))
|
||||
if (west == 1) sb.append(characters(minutesHundreths1 + 22)) else sb.append(characters(minutesHundreths1))
|
||||
|
||||
val encoded = sb.toString()
|
||||
|
||||
// Replace indices 4 and 5 with 'Z' or 'L', depending on 'west'
|
||||
val validAmbiguity = ambiguity.max(0).min(4)
|
||||
val encodedArray = encoded.toCharArray // Convert the encoded string to a char array
|
||||
|
||||
// A map that specifies the modification rules for each index based on ambiguity
|
||||
val modifyRules = Map(
|
||||
2 -> (messageC, 'Z', 'L'),
|
||||
3 -> (north, 'Z', 'L'),
|
||||
4 -> (longOffset, 'Z', 'L'),
|
||||
5 -> (west, 'Z', 'L')
|
||||
)
|
||||
|
||||
// Loop over the indices based on validAmbiguity
|
||||
for (i <- (6 - validAmbiguity) until 6) {
|
||||
modifyRules.get(i) match {
|
||||
case Some((condition, trueChar, falseChar)) =>
|
||||
val charToUse = if (condition == 1) trueChar else falseChar
|
||||
encodedArray(i) = charToUse
|
||||
case None => // No modification if the index is not in modifyRules
|
||||
}
|
||||
}
|
||||
|
||||
// Return the modified string
|
||||
val finalEncoded = new String(encodedArray)
|
||||
|
||||
finalEncoded
|
||||
}
|
||||
|
||||
def encodeInfo(dd: Double, speed: Double, heading: Double, symbol: String): (String, Int, Int) = {
|
||||
|
||||
val (degrees, minutes, minutesHundreths) = miceLong(dd)
|
||||
|
||||
val west = if (dd < 0) 1 else 0
|
||||
|
||||
val sb = new StringBuilder
|
||||
sb.append("`")
|
||||
|
||||
val speedHT = Math.floor(speed / 10.0).toInt
|
||||
val speedUnits = speed - (speedHT * 10)
|
||||
|
||||
val headingHundreds = Math.floor(heading / 100.0).toInt
|
||||
val headingTensUnits = heading - (headingHundreds * 100)
|
||||
|
||||
var longOffset = 0
|
||||
|
||||
if (degrees <= 9) {
|
||||
sb.append((degrees + 118).toChar)
|
||||
longOffset = 1
|
||||
} else if (degrees >= 10 && degrees <= 99) {
|
||||
sb.append((degrees + 28).toChar)
|
||||
longOffset = 0
|
||||
} else if (degrees >= 100 && degrees <= 109) {
|
||||
sb.append((degrees + 8).toChar)
|
||||
longOffset = 1
|
||||
} else if (degrees >= 110) {
|
||||
sb.append((degrees - 72).toChar)
|
||||
longOffset = 1
|
||||
}
|
||||
|
||||
if (minutes <= 9) sb.append((minutes + 88).toChar) else sb.append((minutes + 28).toChar)
|
||||
sb.append((minutesHundreths + 28).toChar)
|
||||
|
||||
if (speed <= 199) sb.append((speedHT + 108).toChar) else sb.append((speedHT + 28).toChar)
|
||||
sb.append((Math.floor(speedUnits * 10).toInt + headingHundreds + 32).toChar)
|
||||
sb.append((headingTensUnits + 28).toChar)
|
||||
|
||||
sb.append(symbol(1))
|
||||
sb.append(symbol(0))
|
||||
sb.append("`")
|
||||
|
||||
(sb.toString(), west, longOffset)
|
||||
}
|
||||
|
||||
def altitude(alt: Double): String = {
|
||||
val altM = Math.round(alt * 0.3048).toInt
|
||||
val relAlt = altM + 10000
|
||||
|
||||
val val1 = Math.floor(relAlt / 8281.0).toInt
|
||||
val rem = relAlt % 8281
|
||||
val val2 = Math.floor(rem / 91.0).toInt
|
||||
val val3 = rem % 91
|
||||
|
||||
// Ensure that the characters are treated as strings and concatenate properly
|
||||
charFromInt(val1).toString + charFromInt(val2).toString + charFromInt(val3).toString + "}"
|
||||
}
|
||||
|
||||
private def charFromInt(value: Int): Char = (value + 33).toChar
|
||||
|
||||
def formatCourseSpeedMice(location: Location): (Int, Int) = {
|
||||
// Default values
|
||||
val status_spd = if (location.hasSpeed && location.getSpeed > 2) {
|
||||
// Convert speed from m/s to knots, and return as an integer
|
||||
mps2kt(location.getSpeed).toInt
|
||||
} else {
|
||||
0 // If no valid speed or below threshold, set speed to 0
|
||||
}
|
||||
|
||||
val course = if (location.hasBearing) {
|
||||
// Get bearing as an integer (course)
|
||||
location.getBearing.asInstanceOf[Int]
|
||||
} else {
|
||||
0 // If no bearing, set course to 0
|
||||
}
|
||||
|
||||
(status_spd, course)
|
||||
}
|
||||
|
||||
def formatAltitudeMice(location: Location): Option[Int] = {
|
||||
if (location.hasAltitude) {
|
||||
// Convert altitude to feet, round to nearest integer, and wrap in Some
|
||||
Some(math.round(m2ft(location.getAltitude)).toInt)
|
||||
} else {
|
||||
None // If no altitude, return None
|
||||
}
|
||||
}
|
||||
|
||||
def passcode(callssid : String) : Int = {
|
||||
// remove ssid, uppercase, add \0 for odd-length calls
|
||||
|
@ -44,6 +217,20 @@ object AprsPacket {
|
|||
else
|
||||
""
|
||||
}
|
||||
|
||||
def formatAltitudeCompressed(location : Location) : String = {
|
||||
if (location.hasAltitude) {
|
||||
var altitude = m2ft(location.getAltitude)
|
||||
var compressedAltitude = ((math.log(altitude) / math.log(1.002)) + 0.5).asInstanceOf[Int]
|
||||
var c = (compressedAltitude / 91).asInstanceOf[Byte] + 33
|
||||
var s = (compressedAltitude % 91).asInstanceOf[Byte] + 33
|
||||
// Negative altitudes cannot be expressed in base-91 and results in corrupt packets
|
||||
if(c < 33) c = 33
|
||||
if(s < 33) s = 33
|
||||
"%c%c".format(c.asInstanceOf[Char], s.asInstanceOf[Char])
|
||||
} else
|
||||
""
|
||||
}
|
||||
|
||||
def formatCourseSpeed(location : Location) : String = {
|
||||
// only report speeds above 2m/s (7.2km/h)
|
||||
|
@ -55,12 +242,35 @@ object AprsPacket {
|
|||
""
|
||||
}
|
||||
|
||||
def formatCourseSpeedCompressed(location : Location) : String = {
|
||||
// only report speeds above 2m/s (7.2km/h)
|
||||
if (location.hasSpeed && location.hasBearing) {
|
||||
// && location.getSpeed > 2)
|
||||
var compressedBearing = (location.getBearing.asInstanceOf[Int] / 4).asInstanceOf[Int]
|
||||
var compressedSpeed = ((math.log(mps2kt(location.getSpeed)) / math.log(1.08)) - 1).asInstanceOf[Int]
|
||||
var c = compressedBearing.asInstanceOf[Byte] + 33;
|
||||
var s = compressedSpeed.asInstanceOf[Byte] + 33;
|
||||
// Negative speeds a courses cannot be expressed in base-91 and results in corrupt packets
|
||||
if(c < 33) c = 33
|
||||
if(s < 33) s = 33
|
||||
"%c%c".format(c.asInstanceOf[Char], s.asInstanceOf[Char])
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
def formatFreq(csespd : String, freq : Float) : String = {
|
||||
if (freq == 0) "" else {
|
||||
val prefix = if (csespd.length() > 0) "/" else ""
|
||||
prefix + "%07.3fMHz".formatLocal(null, freq)
|
||||
}
|
||||
}
|
||||
|
||||
def formatFreqMice(freq : Float) : String = {
|
||||
if (freq == 0) "" else {
|
||||
"%07.3fMHz".formatLocal(null, freq)
|
||||
}
|
||||
}
|
||||
|
||||
def formatLogin(callsign : String, ssid : String, passcode : String, version : String) : String = {
|
||||
"user %s pass %s vers %s".format(formatCallSsid(callsign, ssid), passcode, version)
|
||||
|
|
|
@ -10,6 +10,7 @@ import _root_.android.widget.Toast
|
|||
|
||||
import _root_.net.ab0oo.aprs.parser._
|
||||
|
||||
|
||||
object AprsService {
|
||||
val PACKAGE = "org.aprsdroid.app"
|
||||
// action intents
|
||||
|
@ -230,18 +231,89 @@ class AprsService extends Service {
|
|||
Digipeater.parseList(digipath, true), payload)
|
||||
}
|
||||
|
||||
def newPacketMice(payload: String, destString: String) = {
|
||||
val digipath = prefs.getString("digi_path", "WIDE1-1")
|
||||
val parsedDigipath = Digipeater.parseList(digipath, true)
|
||||
val callsign_ssid = prefs.getCallSsid()
|
||||
Log.d("newPacketMice", s"digipath retrieved: $digipath")
|
||||
|
||||
// Construct the micePacket string
|
||||
val micePacketString = s"$callsign_ssid>$destString${if (digipath.nonEmpty) s",$digipath" else ""}:$payload"
|
||||
|
||||
// Log or return the constructed packet
|
||||
Log.d("newPacketMice", s"Constructed MICE Packet: $micePacketString")
|
||||
|
||||
val micePacketParsed = Parser.parse(micePacketString)
|
||||
|
||||
micePacketParsed
|
||||
}
|
||||
def formatLoc(symbol : String, status : String, location : Location) = {
|
||||
val pos = new Position(location.getLatitude, location.getLongitude, 0,
|
||||
symbol(0), symbol(1))
|
||||
pos.setPositionAmbiguity(prefs.getStringInt("priv_ambiguity", 0))
|
||||
val status_spd = if (prefs.getBoolean("priv_spdbear", true))
|
||||
AprsPacket.formatCourseSpeed(location) else ""
|
||||
|
||||
// Calculate status_spd
|
||||
val status_spd = if (prefs.getBoolean("priv_spdbear", true)) {
|
||||
if(prefs.getBoolean("compressed_location", false)) {
|
||||
// Compressed format
|
||||
AprsPacket.formatCourseSpeedCompressed(location)
|
||||
} else {
|
||||
AprsPacket.formatCourseSpeed(location)
|
||||
}
|
||||
} else ""
|
||||
// Log status_spd
|
||||
Log.d("formatLoc", s"Status Speed: $status_spd")
|
||||
|
||||
// Calculate status_freq
|
||||
val status_freq = AprsPacket.formatFreq(status_spd, prefs.getStringFloat("frequency", 0.0f))
|
||||
val status_alt = if (prefs.getBoolean("priv_altitude", true))
|
||||
AprsPacket.formatAltitude(location) else ""
|
||||
val comment = status_spd + status_freq + status_alt + " " + status;
|
||||
|
||||
// Calculate status_alt
|
||||
val status_alt = if (prefs.getBoolean("priv_altitude", true)) {
|
||||
// if speed is empty then use compressed altitude, otherwise use full length altitude
|
||||
if(prefs.getBoolean("compressed_location", false) && status_spd == "") {
|
||||
// Compressed format
|
||||
AprsPacket.formatAltitudeCompressed(location)
|
||||
} else {
|
||||
AprsPacket.formatAltitude(location)
|
||||
}
|
||||
} else ""
|
||||
// Log status_alt
|
||||
Log.d("formatLoc", s"Status Altitude: $status_alt")
|
||||
|
||||
if(prefs.getBoolean("compressed_location", false)) {
|
||||
if(status_spd == "") {
|
||||
// Speed is empty, so we can use a compressed altitude
|
||||
if(status_alt == "") {
|
||||
// Altitude is empty, so don't send any altitude data
|
||||
pos.setCsTField(" sT")
|
||||
} else {
|
||||
// 3 signifies current GPS fix, GGA altitude, software compressed.
|
||||
pos.setCsTField(status_alt + "3")
|
||||
}
|
||||
val packet = new PositionPacket(
|
||||
pos, status_freq + " " + status, /* messaging = */ true)
|
||||
packet.setCompressedFormat(true)
|
||||
newPacket(packet)
|
||||
} else {
|
||||
// Speed is present, so we need to append the altitude to the end of the packet using the
|
||||
// uncompressed method
|
||||
// Apply the csT field with speed and course
|
||||
// [ signifies current GPS fix, RMC speed, software compressed.
|
||||
pos.setCsTField(status_spd + "[")
|
||||
val packet = new PositionPacket(
|
||||
pos, status_freq + status_alt + " " + status, /* messaging = */ true)
|
||||
packet.setCompressedFormat(true)
|
||||
newPacket(packet)
|
||||
}
|
||||
} else {
|
||||
val packet = new PositionPacket(
|
||||
pos, status_spd + status_freq + status_alt + " " + status, /* messaging = */ true)
|
||||
newPacket(packet)
|
||||
}
|
||||
|
||||
//val comment = status_spd + status_freq + status_alt + " " + status;
|
||||
// TODO: slice after 43 bytes, not after 43 UTF-8 codepoints
|
||||
newPacket(new PositionPacket(pos, comment.slice(0, 43), /* messaging = */ true))
|
||||
//newPacket(new PositionPacket(pos, comment.slice(0, 43), /* messaging = */ true))
|
||||
}
|
||||
|
||||
def sendPacket(packet : APRSPacket, status_postfix : String) {
|
||||
|
@ -263,13 +335,56 @@ class AprsService extends Service {
|
|||
}
|
||||
def sendPacket(packet : APRSPacket) { sendPacket(packet, "") }
|
||||
|
||||
def formatLocMice(symbol : String, status : String, location : Location) = {
|
||||
val privambiguity = 5 - prefs.getStringInt("priv_ambiguity", 0)
|
||||
val ambiguity = if (privambiguity == 5) 0 else privambiguity
|
||||
|
||||
Log.d("MICE", s"Set Ambiguity $ambiguity")
|
||||
|
||||
val miceStatus = prefs.getString("p__location_mice_status", "Off Duty")
|
||||
val (a, b, c) = AprsPacket.statusToBits(miceStatus)
|
||||
|
||||
val status_freq = AprsPacket.formatFreqMice(prefs.getStringFloat("frequency", 0.0f))
|
||||
val (status_spd, course) = AprsPacket.formatCourseSpeedMice(location)
|
||||
|
||||
// Encoding process
|
||||
val (infoString, west, longOffset) = AprsPacket.encodeInfo(location.getLongitude, status_spd, course, symbol)
|
||||
val destString = AprsPacket.encodeDest(location.getLatitude, longOffset, west, a, b, c, ambiguity)
|
||||
|
||||
val altitudeValue = if (prefs.getBoolean("priv_altitude", true)) {
|
||||
AprsPacket.formatAltitudeMice(location)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
val altString = altitudeValue.map(alt => AprsPacket.altitude(alt.toInt)).getOrElse("")
|
||||
|
||||
val formatPayload = infoString +
|
||||
(if (altString.isEmpty) "" else altString) +
|
||||
(if (status.isEmpty) "" else status) +
|
||||
(if (status.nonEmpty && status_freq.nonEmpty) " " else "") +
|
||||
(if (status_freq.isEmpty) "" else status_freq) + "[1"
|
||||
|
||||
Log.d("formatLoc", s"MICE: $infoString $destString $altString")
|
||||
|
||||
val packet = newPacketMice(formatPayload, destString)
|
||||
|
||||
packet
|
||||
|
||||
}
|
||||
|
||||
def postLocation(location : Location) {
|
||||
var symbol = prefs.getString("symbol", "")
|
||||
if (symbol.length != 2)
|
||||
symbol = getString(R.string.default_symbol)
|
||||
val status = prefs.getString("status", getString(R.string.default_status))
|
||||
val packet = formatLoc(symbol, status, location)
|
||||
|
||||
|
||||
// Use inline prefs.getBoolean to decide the packet format
|
||||
val packet = if (prefs.getBoolean("compressed_mice", false)) {
|
||||
formatLocMice(symbol, status, location)
|
||||
} else {
|
||||
formatLoc(symbol, status, location)
|
||||
}
|
||||
|
||||
Log.d(TAG, "packet: " + packet)
|
||||
sendPacket(packet, " (±%dm)".format(location.getAccuracy.asInstanceOf[Int]))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
package org.aprsdroid.app
|
||||
|
||||
import _root_.android.content.SharedPreferences
|
||||
import _root_.android.os.Bundle
|
||||
import _root_.android.preference.{PreferenceActivity, PreferenceManager, CheckBoxPreference, ListPreference}
|
||||
import _root_.android.util.Log
|
||||
|
||||
class CompressedPrefs extends PreferenceActivity with SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
lazy val prefs = new PrefsWrapper(this)
|
||||
|
||||
def loadXml() {
|
||||
// Load compressed.xml preferences
|
||||
addPreferencesFromResource(R.xml.compressed)
|
||||
}
|
||||
|
||||
override def onCreate(savedInstanceState: Bundle) {
|
||||
super.onCreate(savedInstanceState)
|
||||
loadXml()
|
||||
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this)
|
||||
|
||||
// Update preferences state on activity creation
|
||||
updateCheckBoxState()
|
||||
}
|
||||
|
||||
override def onDestroy() {
|
||||
super.onDestroy()
|
||||
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this)
|
||||
}
|
||||
|
||||
override def onSharedPreferenceChanged(sp: SharedPreferences, key: String) {
|
||||
// Handle preference changes for specific keys
|
||||
key match {
|
||||
case "compressed_location" | "compressed_mice" =>
|
||||
// Update checkbox states when either preference changes
|
||||
updateCheckBoxState()
|
||||
case "p__location_mice_status" =>
|
||||
// Handle changes for the p__location_mice_status preference (if needed)
|
||||
updateStatus()
|
||||
case _ => // No action for other preferences
|
||||
}
|
||||
}
|
||||
|
||||
// This method will enable/disable the checkboxes based on their current state
|
||||
private def updateCheckBoxState(): Unit = {
|
||||
val compressedLocationPref = findPreference("compressed_location").asInstanceOf[CheckBoxPreference]
|
||||
val compressedMicePref = findPreference("compressed_mice").asInstanceOf[CheckBoxPreference]
|
||||
val locationMiceStatusPref = findPreference("p__location_mice_status").asInstanceOf[ListPreference]
|
||||
|
||||
// If "compressed_location" is checked, disable "p__location_mice_status"
|
||||
if (compressedLocationPref.isChecked) {
|
||||
locationMiceStatusPref.setEnabled(false)
|
||||
compressedMicePref.setEnabled(false) // Also disable "compressed_mice" when "compressed_location" is checked
|
||||
} else {
|
||||
locationMiceStatusPref.setEnabled(true) // Enable "p__location_mice_status" when "compressed_location" is not checked
|
||||
compressedMicePref.setEnabled(true) // Re-enable "compressed_mice" if "compressed_location" is unchecked
|
||||
}
|
||||
|
||||
// If "compressed_mice" is checked, disable "compressed_location"
|
||||
if (compressedMicePref.isChecked) {
|
||||
compressedLocationPref.setEnabled(false)
|
||||
} else {
|
||||
compressedLocationPref.setEnabled(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Method to handle updates related to p__location_mice_status
|
||||
private def updateStatus(): Unit = {
|
||||
val statusPref = findPreference("p__location_mice_status").asInstanceOf[ListPreference]
|
||||
val statusValue = statusPref.getValue
|
||||
|
||||
// Here, you can handle actions based on the selected status.
|
||||
// For example, logging the selected status:
|
||||
Log.d("CompressedPrefs", s"Selected Location Mice Status: $statusValue")
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue