修复:手机GPS禁用时,启用增强功能`GPS定位服务`导致SmsF启动奔溃

This commit is contained in:
pppscn 2024-02-11 11:19:33 +08:00
parent 44ab934873
commit c0afc9f529
7 changed files with 175 additions and 141 deletions

View File

@ -7,6 +7,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.location.Criteria import android.location.Criteria
import android.location.LocationManager
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Environment import android.os.Environment
@ -112,7 +113,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
switchEnableAppNotify(binding!!.sbEnableAppNotify, binding!!.scbCancelAppNotify, binding!!.scbNotUserPresent) switchEnableAppNotify(binding!!.sbEnableAppNotify, binding!!.scbCancelAppNotify, binding!!.scbNotUserPresent)
//启用GPS定位功能 //启用GPS定位功能
switchEnableLocation(binding!!.sbEnableLocation, binding!!.layoutLocationSetting, binding!!.rgAccuracy, binding!!.rgPowerRequirement, binding!!.etMinInterval, binding!!.etMinDistance) switchEnableLocation(binding!!.sbEnableLocation, binding!!.layoutLocationSetting, binding!!.rgAccuracy, binding!!.rgPowerRequirement, binding!!.xsbMinInterval, binding!!.xsbMinDistance)
//短信指令 //短信指令
switchEnableSmsCommand(binding!!.sbEnableSmsCommand, binding!!.etSafePhone) switchEnableSmsCommand(binding!!.sbEnableSmsCommand, binding!!.etSafePhone)
//启动时异步获取已安装App信息 //启动时异步获取已安装App信息
@ -513,7 +514,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
} }
//启用定位功能 //启用定位功能
private fun switchEnableLocation(@SuppressLint("UseSwitchCompatOrMaterialCode") sbEnableLocation: SwitchButton, layoutLocationSetting: LinearLayout, rgAccuracy: RadioGroup, rgPowerRequirement: RadioGroup, etMinInterval: EditText, etMinDistance: EditText) { private fun switchEnableLocation(@SuppressLint("UseSwitchCompatOrMaterialCode") sbEnableLocation: SwitchButton, layoutLocationSetting: LinearLayout, rgAccuracy: RadioGroup, rgPowerRequirement: RadioGroup, xsbMinInterval: XSeekBar, xsbMinDistance: XSeekBar) {
//是否启用定位功能 //是否启用定位功能
sbEnableLocation.isChecked = SettingUtils.enableLocation sbEnableLocation.isChecked = SettingUtils.enableLocation
layoutLocationSetting.visibility = if (SettingUtils.enableLocation) View.VISIBLE else View.GONE layoutLocationSetting.visibility = if (SettingUtils.enableLocation) View.VISIBLE else View.GONE
@ -560,7 +561,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
R.id.rb_accuracy_no_requirement -> Criteria.NO_REQUIREMENT R.id.rb_accuracy_no_requirement -> Criteria.NO_REQUIREMENT
else -> Criteria.ACCURACY_FINE else -> Criteria.ACCURACY_FINE
} }
restartLocationService("rgAccuracy") restartLocationService()
} }
//设置电量消耗:低电耗(默认) //设置电量消耗:低电耗(默认)
@ -581,49 +582,38 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
R.id.rb_power_requirement_no_requirement -> Criteria.NO_REQUIREMENT R.id.rb_power_requirement_no_requirement -> Criteria.NO_REQUIREMENT
else -> Criteria.POWER_LOW else -> Criteria.POWER_LOW
} }
restartLocationService("rgPowerRequirement") restartLocationService()
} }
//设置位置更新最小时间间隔(单位:毫秒); 默认间隔10000毫秒最小间隔1000毫秒 //设置位置更新最小时间间隔(单位:毫秒); 默认间隔10000毫秒最小间隔1000毫秒
etMinInterval.setText((SettingUtils.locationMinInterval / 1000).toString()) xsbMinInterval.setDefaultValue((SettingUtils.locationMinInterval / 1000).toInt())
etMinInterval.addTextChangedListener(object : TextWatcher { xsbMinInterval.setOnSeekBarListener { _: XSeekBar?, newValue: Int ->
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} SettingUtils.locationMinInterval = newValue * 1000L
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable) {
val changedText = s.toString()
if (changedText.isEmpty() || changedText == "0") {
etMinInterval.setText("1")
etMinInterval.setSelection(etMinInterval.text.length) // 将光标移至文本末尾
return
}
SettingUtils.locationMinInterval = changedText.toLong() * 1000
restartLocationService() restartLocationService()
} }
})
//设置位置更新最小距离单位默认距离0米 //设置位置更新最小距离单位默认距离0米
etMinDistance.setText(SettingUtils.locationMinDistance.toString()) xsbMinDistance.setDefaultValue(SettingUtils.locationMinDistance)
etMinDistance.addTextChangedListener(object : TextWatcher { xsbMinDistance.setOnSeekBarListener { _: XSeekBar?, newValue: Int ->
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} SettingUtils.locationMinDistance = newValue
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
override fun afterTextChanged(s: Editable) {
val changedText = s.toString()
if (changedText.isEmpty()) {
etMinDistance.setText("0")
etMinDistance.setSelection(etMinInterval.text.length) // 将光标移至文本末尾
return
}
SettingUtils.locationMinDistance = changedText.toInt()
restartLocationService() restartLocationService()
} }
})
} }
//重启定位服务 //重启定位服务
private fun restartLocationService(action: String = "RESTART") { private fun restartLocationService(action: String = "RESTART") {
Log.d(TAG, "restartLocationService, action: $action") Log.d(TAG, "restartLocationService, action: $action")
val serviceIntent = Intent(requireContext(), LocationService::class.java) val serviceIntent = Intent(requireContext(), LocationService::class.java)
val locationManager = App.context.getSystemService(Context.LOCATION_SERVICE) as LocationManager?
val isGpsEnabled = locationManager?.isProviderEnabled(LocationManager.GPS_PROVIDER) == true
if (!isGpsEnabled && SettingUtils.enableLocation) {
XToastUtils.error(getString(R.string.toast_gps_not_enabled))
SettingUtils.enableLocation = false
binding!!.sbEnableLocation.isChecked = false
serviceIntent.action = "STOP"
} else {
serviceIntent.action = action serviceIntent.action = action
}
requireContext().startService(serviceIntent) requireContext().startService(serviceIntent)
} }

View File

@ -2,8 +2,12 @@ package com.idormy.sms.forwarder.service
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Service import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter
import android.location.Location import android.location.Location
import android.location.LocationManager
import android.os.IBinder import android.os.IBinder
import androidx.work.OneTimeWorkRequestBuilder import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager import androidx.work.WorkManager
@ -23,14 +27,20 @@ import com.king.location.LocationErrorCode
import com.king.location.OnExceptionListener import com.king.location.OnExceptionListener
import com.king.location.OnLocationListener import com.king.location.OnLocationListener
import com.xuexiang.xaop.util.PermissionUtils import com.xuexiang.xaop.util.PermissionUtils
import com.yanzhenjie.andserver.Server
import java.util.Date import java.util.Date
@SuppressLint("SimpleDateFormat") @SuppressLint("SimpleDateFormat")
@Suppress("PrivatePropertyName", "DEPRECATION") @Suppress("PrivatePropertyName", "DEPRECATION")
class LocationService : Service(), Server.ServerListener { class LocationService : Service() {
private val TAG: String = LocationService::class.java.simpleName private val TAG: String = LocationService::class.java.simpleName
private val gpsStatusReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == LocationManager.PROVIDERS_CHANGED_ACTION) {
handleGpsStatusChanged()
}
}
}
companion object { companion object {
var isRunning = false var isRunning = false
@ -45,13 +55,16 @@ class LocationService : Service(), Server.ServerListener {
super.onCreate() super.onCreate()
if (!SettingUtils.enableLocation) return if (!SettingUtils.enableLocation) return
//注册广播接收器
registerReceiver(gpsStatusReceiver, IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION))
startService() startService()
} }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId) super.onStartCommand(intent, flags, startId)
if (!SettingUtils.enableLocation || intent == null) return START_NOT_STICKY if (intent == null) return START_NOT_STICKY
Log.i(TAG, "onStartCommand: ${intent.action}") Log.i(TAG, "onStartCommand: ${intent.action}")
@ -60,11 +73,10 @@ class LocationService : Service(), Server.ServerListener {
} else if (intent.action == "STOP" && isRunning) { } else if (intent.action == "STOP" && isRunning) {
stopService() stopService()
} else if (intent.action == "RESTART") { } else if (intent.action == "RESTART") {
stopService() restartLocation()
startService()
} }
return START_NOT_STICKY return START_STICKY
} }
override fun onDestroy() { override fun onDestroy() {
@ -73,18 +85,8 @@ class LocationService : Service(), Server.ServerListener {
if (!SettingUtils.enableLocation) return if (!SettingUtils.enableLocation) return
stopService() stopService()
} //在 Service 销毁时记得注销广播接收器
unregisterReceiver(gpsStatusReceiver)
override fun onException(e: Exception?) {
Log.i(TAG, "onException: ")
}
override fun onStarted() {
Log.i(TAG, "onStarted: ")
}
override fun onStopped() {
Log.i(TAG, "onStopped: ")
} }
private fun startService() { private fun startService() {
@ -94,16 +96,6 @@ class LocationService : Service(), Server.ServerListener {
TaskUtils.locationInfoOld = LocationInfo() TaskUtils.locationInfoOld = LocationInfo()
if (SettingUtils.enableLocation && PermissionUtils.isGranted(android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION)) { if (SettingUtils.enableLocation && PermissionUtils.isGranted(android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION)) {
//可根据具体需求设置定位配置参数(这里只列出一些主要的参数)
val locationOption = App.LocationClient.getLocationOption().setAccuracy(SettingUtils.locationAccuracy)//设置位置精度:高精度
.setPowerRequirement(SettingUtils.locationPowerRequirement) //设置电量消耗:低电耗
.setMinTime(SettingUtils.locationMinInterval)//设置位置更新最小时间间隔(单位:毫秒); 默认间隔10000毫秒最小间隔1000毫秒
.setMinDistance(SettingUtils.locationMinDistance)//设置位置更新最小距离单位默认距离0米
.setOnceLocation(false)//设置是否只定位一次,默认为 false当设置为 true 时,则只定位一次后,会自动停止定位
.setLastKnownLocation(false)//设置是否获取最后一次缓存的已知位置,默认为 true
//设置定位配置参数
App.LocationClient.setLocationOption(locationOption)
App.LocationClient.startLocation()
//设置定位监听 //设置定位监听
App.LocationClient.setOnLocationListener(object : OnLocationListener() { App.LocationClient.setOnLocationListener(object : OnLocationListener() {
@ -125,7 +117,7 @@ class LocationService : Service(), Server.ServerListener {
HttpServerUtils.apiLocationCache = locationInfoNew HttpServerUtils.apiLocationCache = locationInfoNew
TaskUtils.locationInfoNew = locationInfoNew TaskUtils.locationInfoNew = locationInfoNew
//TODO: 触发自动任务 //触发自动任务
val locationInfoOld = TaskUtils.locationInfoOld val locationInfoOld = TaskUtils.locationInfoOld
if (locationInfoOld.longitude != locationInfoNew.longitude || locationInfoOld.latitude != locationInfoNew.latitude || locationInfoOld.address != locationInfoNew.address) { if (locationInfoOld.longitude != locationInfoNew.longitude || locationInfoOld.latitude != locationInfoNew.latitude || locationInfoOld.address != locationInfoNew.address) {
Log.d(TAG, "locationInfoOld = $locationInfoOld") Log.d(TAG, "locationInfoOld = $locationInfoOld")
@ -139,34 +131,18 @@ class LocationService : Service(), Server.ServerListener {
TaskUtils.locationInfoOld = locationInfoNew TaskUtils.locationInfoOld = locationInfoNew
} }
} }
override fun onProviderEnabled(provider: String) {
super.onProviderEnabled(provider)
Log.d(TAG, "onProviderEnabled(provider = ${provider})")
}
override fun onProviderDisabled(provider: String) {
super.onProviderDisabled(provider)
Log.d(TAG, "onProviderDisabled(provider = ${provider})")
}
}) })
//设置异常监听 //设置异常监听
App.LocationClient.setOnExceptionListener(object : OnExceptionListener { App.LocationClient.setOnExceptionListener(object : OnExceptionListener {
override fun onException(@LocationErrorCode errorCode: Int, e: Exception) { override fun onException(@LocationErrorCode errorCode: Int, e: Exception) {
//定位出现异常 //定位出现异常 && 尝试重启定位
Log.w(TAG, "onException(errorCode = ${errorCode}, e = ${e})") Log.w(TAG, "onException(errorCode = ${errorCode}, e = ${e})")
restartLocation()
//TODO: 重启定位
App.LocationClient.startLocation()
} }
}) })
if (App.LocationClient.isStarted()) {//如果已经开始定位,则先停止定位 restartLocation()
App.LocationClient.stopLocation()
}
App.LocationClient.startLocation()
isRunning = true isRunning = true
} else if (!SettingUtils.enableLocation && App.LocationClient.isStarted()) { } else if (!SettingUtils.enableLocation && App.LocationClient.isStarted()) {
Log.d(TAG, "stopLocation") Log.d(TAG, "stopLocation")
@ -200,20 +176,59 @@ class LocationService : Service(), Server.ServerListener {
} }
} }
private fun restartLocation() {
//如果已经开始定位,则先停止定位
if (App.LocationClient.isStarted()) {
App.LocationClient.stopLocation()
}
if (isGpsEnabled()) {
//可根据具体需求设置定位配置参数(这里只列出一些主要的参数)
val locationOption = App.LocationClient.getLocationOption().setAccuracy(SettingUtils.locationAccuracy)//设置位置精度:高精度
.setPowerRequirement(SettingUtils.locationPowerRequirement) //设置电量消耗:低电耗
.setMinTime(SettingUtils.locationMinInterval)//设置位置更新最小时间间隔(单位:毫秒); 默认间隔10000毫秒最小间隔1000毫秒
.setMinDistance(SettingUtils.locationMinDistance)//设置位置更新最小距离单位默认距离0米
.setOnceLocation(false)//设置是否只定位一次,默认为 false当设置为 true 时,则只定位一次后,会自动停止定位
.setLastKnownLocation(false)//设置是否获取最后一次缓存的已知位置,默认为 true
//设置定位配置参数
App.LocationClient.setLocationOption(locationOption)
App.LocationClient.startLocation()
} else {
Log.w(TAG, "onException: GPS未开启")
}
}
private fun enqueueLocationWorkerRequest( private fun enqueueLocationWorkerRequest(
conditionType: Int, conditionType: Int, locationJsonOld: String, locationJsonNew: String
locationJsonOld: String,
locationJsonNew: String
) { ) {
val locationWorkerRequest = OneTimeWorkRequestBuilder<LocationWorker>().setInputData( val locationWorkerRequest = OneTimeWorkRequestBuilder<LocationWorker>().setInputData(
workDataOf( workDataOf(
TaskWorker.conditionType to conditionType, TaskWorker.conditionType to conditionType, "locationJsonOld" to locationJsonOld, "locationJsonNew" to locationJsonNew
"locationJsonOld" to locationJsonOld,
"locationJsonNew" to locationJsonNew
) )
).build() ).build()
WorkManager.getInstance(applicationContext).enqueue(locationWorkerRequest) WorkManager.getInstance(applicationContext).enqueue(locationWorkerRequest)
} }
private fun handleGpsStatusChanged() {
val isGpsEnabled = isGpsEnabled()
//处理 GPS 状态变化
if (isGpsEnabled) {
//GPS 已启用
Log.d(TAG, "handleGpsStatusChanged: GPS 已启用")
if (SettingUtils.enableLocation && !App.LocationClient.isStarted()) {
App.LocationClient.startLocation()
}
} else {
//GPS 已停用
Log.d(TAG, "handleGpsStatusChanged: GPS 已停用")
if (SettingUtils.enableLocation && App.LocationClient.isStarted()) {
App.LocationClient.stopLocation()
}
}
}
private fun isGpsEnabled(): Boolean {
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager?
return locationManager?.isProviderEnabled(LocationManager.GPS_PROVIDER) == true
}
} }

View File

@ -502,25 +502,40 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/min_interval" android:text="@string/location_update"
android:textSize="@dimen/text_size_small" android:textSize="@dimen/text_size_small"
android:textStyle="bold" android:textStyle="bold"
tools:ignore="SmallSp" /> tools:ignore="SmallSp" />
<EditText <LinearLayout
android:id="@+id/et_min_interval" android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:text="@string/min_interval"
android:textSize="@dimen/text_size_small"
android:textStyle="bold" />
<com.xuexiang.xui.widget.picker.XSeekBar
android:id="@+id/xsb_min_interval"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="5dp" android:layout_marginStart="5dp"
android:layout_weight="1" android:layout_weight="1"
android:digits="0123456789" android:padding="0dp"
android:importantForAutofill="no" app:xsb_max="120"
android:inputType="number" app:xsb_min="1" />
android:paddingTop="0dp"
android:paddingBottom="3dp"
android:singleLine="true"
android:textAlignment="center"
tools:ignore="LabelFor,SpeakableTextPresentCheck,TouchTargetSizeCheck" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -530,29 +545,31 @@
android:textSize="@dimen/text_size_small" android:textSize="@dimen/text_size_small"
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/config_margin_10dp" android:layout_marginStart="5dp"
android:text="@string/min_distance" android:text="@string/min_distance"
android:textSize="@dimen/text_size_small" android:textSize="@dimen/text_size_small"
android:textStyle="bold" android:textStyle="bold" />
tools:ignore="SmallSp" />
<EditText <com.xuexiang.xui.widget.picker.XSeekBar
android:id="@+id/et_min_distance" android:id="@+id/xsb_min_distance"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="5dp" android:layout_marginStart="5dp"
android:layout_weight="1" android:layout_weight="1"
android:digits="0123456789" android:padding="0dp"
android:importantForAutofill="no" app:xsb_max="100"
android:inputType="number" app:xsb_min="1" />
android:paddingTop="0dp"
android:paddingBottom="3dp"
android:singleLine="true"
android:textAlignment="center"
tools:ignore="LabelFor,SpeakableTextPresentCheck,TouchTargetSizeCheck" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -568,6 +585,10 @@
</LinearLayout> </LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
style="@style/BarStyle.Switch" style="@style/BarStyle.Switch"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -1129,7 +1129,8 @@
<string name="power_requirement_low">Low</string> <string name="power_requirement_low">Low</string>
<string name="power_requirement_medium">Medium</string> <string name="power_requirement_medium">Medium</string>
<string name="power_requirement_high">High</string> <string name="power_requirement_high">High</string>
<string name="min_interval">To Update: Min Interval</string> <string name="location_update">Location Update</string>
<string name="min_interval">Min Interval</string>
<string name="min_distance">Min Distance</string> <string name="min_distance">Min Distance</string>
<string name="meter">m</string> <string name="meter">m</string>
<string name="uid">UID</string> <string name="uid">UID</string>
@ -1339,4 +1340,5 @@
<string name="union_id">Union ID</string> <string name="union_id">Union ID</string>
<string name="chat_id">Chat ID</string> <string name="chat_id">Chat ID</string>
<string name="receive_id">Receive ID</string> <string name="receive_id">Receive ID</string>
<string name="toast_gps_not_enabled">GPS is not enabled, please enable GPS first!</string>
</resources> </resources>

View File

@ -1130,7 +1130,8 @@
<string name="power_requirement_low"></string> <string name="power_requirement_low"></string>
<string name="power_requirement_medium"></string> <string name="power_requirement_medium"></string>
<string name="power_requirement_high"></string> <string name="power_requirement_high"></string>
<string name="min_interval">位置更新:最小时间间隔</string> <string name="location_update">位置更新</string>
<string name="min_interval">最小时间间隔</string>
<string name="min_distance">最小距离间隔</string> <string name="min_distance">最小距离间隔</string>
<string name="meter"></string> <string name="meter"></string>
<string name="uid">UID</string> <string name="uid">UID</string>
@ -1340,4 +1341,5 @@
<string name="union_id">Union ID</string> <string name="union_id">Union ID</string>
<string name="chat_id">Chat ID</string> <string name="chat_id">Chat ID</string>
<string name="receive_id">消息接收者ID</string> <string name="receive_id">消息接收者ID</string>
<string name="toast_gps_not_enabled">GPS未开启请先开启GPS</string>
</resources> </resources>

View File

@ -1130,7 +1130,8 @@
<string name="power_requirement_low"></string> <string name="power_requirement_low"></string>
<string name="power_requirement_medium"></string> <string name="power_requirement_medium"></string>
<string name="power_requirement_high"></string> <string name="power_requirement_high"></string>
<string name="min_interval">位置更新:最小時間間隔</string> <string name="location_update">位置更新</string>
<string name="min_interval">最小時間間隔</string>
<string name="min_distance">最小距離間隔</string> <string name="min_distance">最小距離間隔</string>
<string name="meter"></string> <string name="meter"></string>
<string name="uid">UID</string> <string name="uid">UID</string>
@ -1341,4 +1342,5 @@
<string name="union_id">Union ID</string> <string name="union_id">Union ID</string>
<string name="chat_id">Chat ID</string> <string name="chat_id">Chat ID</string>
<string name="receive_id">訊息接收者ID</string> <string name="receive_id">訊息接收者ID</string>
<string name="toast_gps_not_enabled">GPS未開啟請先開啟GPS</string>
</resources> </resources>

View File

@ -1130,7 +1130,8 @@
<string name="power_requirement_low"></string> <string name="power_requirement_low"></string>
<string name="power_requirement_medium"></string> <string name="power_requirement_medium"></string>
<string name="power_requirement_high"></string> <string name="power_requirement_high"></string>
<string name="min_interval">位置更新:最小时间间隔</string> <string name="location_update">位置更新</string>
<string name="min_interval">最小时间间隔</string>
<string name="min_distance">最小距离间隔</string> <string name="min_distance">最小距离间隔</string>
<string name="meter"></string> <string name="meter"></string>
<string name="uid">UID</string> <string name="uid">UID</string>
@ -1340,4 +1341,5 @@
<string name="union_id">Union ID</string> <string name="union_id">Union ID</string>
<string name="chat_id">Chat ID</string> <string name="chat_id">Chat ID</string>
<string name="receive_id">消息接收者ID</string> <string name="receive_id">消息接收者ID</string>
<string name="toast_gps_not_enabled">GPS未开启请先开启GPS</string>
</resources> </resources>