修复:WiFi平板(没有GPS芯片)无法启用GPS定位服务 #391

This commit is contained in:
pppscn 2024-02-16 00:22:15 +08:00
parent eed99b5baf
commit d6623902f3
8 changed files with 94 additions and 33 deletions

View File

@ -7,7 +7,6 @@ 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
@ -68,6 +67,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
private val TAG: String = SettingsFragment::class.java.simpleName private val TAG: String = SettingsFragment::class.java.simpleName
private var titleBar: TitleBar? = null private var titleBar: TitleBar? = null
private val mTimeOption = DataProvider.timePeriodOption private val mTimeOption = DataProvider.timePeriodOption
private var initViewsFinished = false
//已安装App信息列表 //已安装App信息列表
private val appListSpinnerList = ArrayList<AppListAdapterItem>() private val appListSpinnerList = ArrayList<AppListAdapterItem>()
@ -163,6 +163,8 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
switchDebugMode(binding!!.sbDebugMode) switchDebugMode(binding!!.sbDebugMode)
//多语言设置 //多语言设置
switchLanguage(binding!!.rgMainLanguages) switchLanguage(binding!!.rgMainLanguages)
initViewsFinished = true
} }
override fun onResume() { override fun onResume() {
@ -520,6 +522,7 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
layoutLocationSetting.visibility = if (SettingUtils.enableLocation) View.VISIBLE else View.GONE layoutLocationSetting.visibility = if (SettingUtils.enableLocation) View.VISIBLE else View.GONE
sbEnableLocation.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean -> sbEnableLocation.setOnCheckedChangeListener { _: CompoundButton?, isChecked: Boolean ->
SettingUtils.enableLocation = isChecked SettingUtils.enableLocation = isChecked
layoutLocationSetting.visibility = if (isChecked) View.VISIBLE else View.GONE
if (isChecked) { if (isChecked) {
XXPermissions.with(this).permission(Permission.ACCESS_COARSE_LOCATION).permission(Permission.ACCESS_FINE_LOCATION).permission(Permission.ACCESS_BACKGROUND_LOCATION).request(object : OnPermissionCallback { XXPermissions.with(this).permission(Permission.ACCESS_COARSE_LOCATION).permission(Permission.ACCESS_FINE_LOCATION).permission(Permission.ACCESS_BACKGROUND_LOCATION).request(object : OnPermissionCallback {
override fun onGranted(permissions: List<String>, all: Boolean) { override fun onGranted(permissions: List<String>, all: Boolean) {
@ -542,7 +545,6 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
} else { } else {
restartLocationService("STOP") restartLocationService("STOP")
} }
layoutLocationSetting.visibility = if (isChecked) View.VISIBLE else View.GONE
} }
//设置位置精度:高精度(默认) //设置位置精度:高精度(默认)
@ -588,26 +590,30 @@ class SettingsFragment : BaseFragment<FragmentSettingsBinding?>(), View.OnClickL
//设置位置更新最小时间间隔(单位:毫秒); 默认间隔10000毫秒最小间隔1000毫秒 //设置位置更新最小时间间隔(单位:毫秒); 默认间隔10000毫秒最小间隔1000毫秒
xsbMinInterval.setDefaultValue((SettingUtils.locationMinInterval / 1000).toInt()) xsbMinInterval.setDefaultValue((SettingUtils.locationMinInterval / 1000).toInt())
xsbMinInterval.setOnSeekBarListener { _: XSeekBar?, newValue: Int -> xsbMinInterval.setOnSeekBarListener { _: XSeekBar?, newValue: Int ->
SettingUtils.locationMinInterval = newValue * 1000L if (newValue * 1000L != SettingUtils.locationMinInterval) {
restartLocationService() SettingUtils.locationMinInterval = newValue * 1000L
restartLocationService()
}
} }
//设置位置更新最小距离单位默认距离0米 //设置位置更新最小距离单位默认距离0米
xsbMinDistance.setDefaultValue(SettingUtils.locationMinDistance) xsbMinDistance.setDefaultValue(SettingUtils.locationMinDistance)
xsbMinDistance.setOnSeekBarListener { _: XSeekBar?, newValue: Int -> xsbMinDistance.setOnSeekBarListener { _: XSeekBar?, newValue: Int ->
SettingUtils.locationMinDistance = newValue if (newValue != SettingUtils.locationMinDistance) {
restartLocationService() SettingUtils.locationMinDistance = newValue
restartLocationService()
}
} }
} }
//重启定位服务 //重启定位服务
private fun restartLocationService(action: String = "RESTART") { private fun restartLocationService(action: String = "RESTART") {
if (!initViewsFinished) return
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 (SettingUtils.enableLocation && (!LocationUtils.isLocationEnabled(App.context) || !LocationUtils.hasLocationCapability(App.context))) {
if (!isGpsEnabled && SettingUtils.enableLocation) { XToastUtils.error(getString(R.string.toast_location_not_enabled))
XToastUtils.error(getString(R.string.toast_gps_not_enabled))
SettingUtils.enableLocation = false SettingUtils.enableLocation = false
binding!!.sbEnableLocation.isChecked = false binding!!.sbEnableLocation.isChecked = false
binding!!.layoutLocationSetting.visibility = View.GONE binding!!.layoutLocationSetting.visibility = View.GONE

View File

@ -16,6 +16,7 @@ import com.google.gson.Gson
import com.idormy.sms.forwarder.App import com.idormy.sms.forwarder.App
import com.idormy.sms.forwarder.entity.LocationInfo import com.idormy.sms.forwarder.entity.LocationInfo
import com.idormy.sms.forwarder.utils.HttpServerUtils import com.idormy.sms.forwarder.utils.HttpServerUtils
import com.idormy.sms.forwarder.utils.LocationUtils
import com.idormy.sms.forwarder.utils.Log import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SettingUtils import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.utils.TASK_CONDITION_LEAVE_ADDRESS import com.idormy.sms.forwarder.utils.TASK_CONDITION_LEAVE_ADDRESS
@ -34,10 +35,10 @@ import java.util.Date
class LocationService : Service() { class LocationService : Service() {
private val TAG: String = LocationService::class.java.simpleName private val TAG: String = LocationService::class.java.simpleName
private val gpsStatusReceiver = object : BroadcastReceiver() { private val locationStatusReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) { override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == LocationManager.PROVIDERS_CHANGED_ACTION) { if (intent?.action == LocationManager.PROVIDERS_CHANGED_ACTION) {
handleGpsStatusChanged() handleLocationStatusChanged()
} }
} }
} }
@ -57,7 +58,7 @@ class LocationService : Service() {
if (!SettingUtils.enableLocation) return if (!SettingUtils.enableLocation) return
//注册广播接收器 //注册广播接收器
registerReceiver(gpsStatusReceiver, IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION)) registerReceiver(locationStatusReceiver, IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION))
startService() startService()
} }
@ -86,7 +87,7 @@ class LocationService : Service() {
if (!SettingUtils.enableLocation) return if (!SettingUtils.enableLocation) return
stopService() stopService()
//在 Service 销毁时记得注销广播接收器 //在 Service 销毁时记得注销广播接收器
unregisterReceiver(gpsStatusReceiver) unregisterReceiver(locationStatusReceiver)
} }
private fun startService() { private fun startService() {
@ -181,7 +182,7 @@ class LocationService : Service() {
if (App.LocationClient.isStarted()) { if (App.LocationClient.isStarted()) {
App.LocationClient.stopLocation() App.LocationClient.stopLocation()
} }
if (isGpsEnabled()) { if (LocationUtils.isLocationEnabled(App.context) && LocationUtils.hasLocationCapability(App.context)) {
//可根据具体需求设置定位配置参数(这里只列出一些主要的参数) //可根据具体需求设置定位配置参数(这里只列出一些主要的参数)
val locationOption = App.LocationClient.getLocationOption().setAccuracy(SettingUtils.locationAccuracy)//设置位置精度:高精度 val locationOption = App.LocationClient.getLocationOption().setAccuracy(SettingUtils.locationAccuracy)//设置位置精度:高精度
.setPowerRequirement(SettingUtils.locationPowerRequirement) //设置电量消耗:低电耗 .setPowerRequirement(SettingUtils.locationPowerRequirement) //设置电量消耗:低电耗
@ -209,26 +210,21 @@ class LocationService : Service() {
WorkManager.getInstance(applicationContext).enqueue(locationWorkerRequest) WorkManager.getInstance(applicationContext).enqueue(locationWorkerRequest)
} }
private fun handleGpsStatusChanged() { private fun handleLocationStatusChanged() {
val isGpsEnabled = isGpsEnabled() //处理状态变化
//处理 GPS 状态变化 if (LocationUtils.isLocationEnabled(App.context) && LocationUtils.hasLocationCapability(App.context)) {
if (isGpsEnabled) { //已启用
//GPS 已启用 Log.d(TAG, "handleLocationStatusChanged: 已启用")
Log.d(TAG, "handleGpsStatusChanged: GPS 已启用")
if (SettingUtils.enableLocation && !App.LocationClient.isStarted()) { if (SettingUtils.enableLocation && !App.LocationClient.isStarted()) {
App.LocationClient.startLocation() App.LocationClient.startLocation()
} }
} else { } else {
//GPS 已停用 //已停用
Log.d(TAG, "handleGpsStatusChanged: GPS 已停用") Log.d(TAG, "handleLocationStatusChanged: 已停用")
if (SettingUtils.enableLocation && App.LocationClient.isStarted()) { if (SettingUtils.enableLocation && App.LocationClient.isStarted()) {
App.LocationClient.stopLocation() App.LocationClient.stopLocation()
} }
} }
} }
private fun isGpsEnabled(): Boolean {
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager?
return locationManager?.isProviderEnabled(LocationManager.GPS_PROVIDER) == true
}
} }

View File

@ -0,0 +1,60 @@
package com.idormy.sms.forwarder.utils
import android.content.Context
import android.content.pm.PackageManager
import android.location.LocationManager
import android.os.Build
import android.provider.Settings
import androidx.core.content.ContextCompat
@Suppress("DEPRECATION")
object LocationUtils {
private const val LOCATION_MODE_OFF = 0
private fun hasLocationPermission(context: Context): Boolean {
val hasPermission = ContextCompat.checkSelfPermission(
context,
android.Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
Log.d("LocationUtils", "hasLocationPermission: $hasPermission")
return hasPermission
}
fun isLocationEnabled(context: Context): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager?
Log.d("LocationUtils", "isLocationEnabled: ${locationManager?.isLocationEnabled}")
locationManager?.isLocationEnabled == true
} else {
try {
val locationMode = Settings.Secure.getInt(
context.contentResolver,
Settings.Secure.LOCATION_MODE
)
Log.d("LocationUtils", "isLocationEnabled: locationMode=$locationMode")
locationMode != LOCATION_MODE_OFF
} catch (e: Settings.SettingNotFoundException) {
false
}
}
}
fun hasLocationCapability(context: Context): Boolean {
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager?
// 检查是否有位置权限
if (!hasLocationPermission(context)) {
Log.e("LocationUtils", "hasLocationCapability: no location permission")
return false
}
// 检查是否有定位能力
val hasGpsProvider = locationManager?.isProviderEnabled(LocationManager.GPS_PROVIDER) == true
val hasNetworkProvider = locationManager?.isProviderEnabled(LocationManager.NETWORK_PROVIDER) == true
val hasPassiveProvider = locationManager?.isProviderEnabled(LocationManager.PASSIVE_PROVIDER) == true
Log.d("LocationUtils", "hasLocationCapability: hasGpsProvider=$hasGpsProvider, hasNetworkProvider=$hasNetworkProvider, hasPassiveProvider=$hasPassiveProvider")
return hasGpsProvider || hasNetworkProvider || hasPassiveProvider
}
}

View File

@ -392,8 +392,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:orientation="vertical" android:orientation="vertical">
android:visibility="gone">
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -1340,5 +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> <string name="toast_location_not_enabled">Location is not enabled, Please go to system settings and activate it.</string>
</resources> </resources>

View File

@ -1341,5 +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> <string name="toast_location_not_enabled">位置服务未开启,请先前往系统设置中开启</string>
</resources> </resources>

View File

@ -1342,5 +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> <string name="toast_location_not_enabled">定位服務未開啟,請先前往系統設置中開啟</string>
</resources> </resources>

View File

@ -1341,5 +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> <string name="toast_location_not_enabled">位置服务未开启,请先前往系统设置中开启</string>
</resources> </resources>