如何为 gps 使用特定对话框?

Posted

技术标签:

【中文标题】如何为 gps 使用特定对话框?【英文标题】:How can I use a specific dialog for gps? 【发布时间】:2021-09-27 23:03:57 【问题描述】:

当我尝试在不进入手机设置的情况下打开 gps 时,我看到了这个对话框:

如何显示带有这样描述的对话框?

这是我的代码示例:

viewModel.onEnableGpsEvent.observe(this, Observer  event ->
    event.getContentIfNotHandled()?.let 
        activity?.let 
            val locationRequest = LocationRequest.create()
            locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
            val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)
            val task = LocationServices.getSettingsClient(it).checkLocationSettings(builder.build())

            task.addOnSuccessListener  response ->
                val states = response.locationSettingsStates
                if (states.isLocationPresent) 
                    //TODO: Do something if need it
                
            
            task.addOnFailureListener  e ->
                if (e is ResolvableApiException) 
                    try 
                        // Handle result in onActivityResult()
                        e.startResolutionForResult(
                            it,
                            LOCATION_SETTING_REQUEST
                        )
                     catch (sendEx: IntentSender.SendIntentException) 
                    
                
            
        

我还有下一个依赖:

implementation 'com.google.android.gms:play-services-location:18.0.0'

【问题讨论】:

【参考方案1】:

这是我在Fragment中使用的方法:

    创建请求 GPS 功能的扩展函数:

     fun Fragment.requestGPSOn(request: ActivityResultLauncher<IntentSenderRequest>)    //new api
         val locationRequest = LocationRequest.create().apply 
             priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY     //GPS accuracy
         
    
         val settingRequest = LocationSettingsRequest.Builder().run 
             addLocationRequest(locationRequest)
             build()
         
    
         val settingsClient = LocationServices.getSettingsClient(requireContext())
         val task = settingsClient.checkLocationSettings(settingRequest)         //【fire and receive result】
    
         task.addOnFailureListener                              //if GPS is not on currently
             val intentSender = (it as ResolvableApiException).resolution.intentSender
             val intentSenderRequest = IntentSenderRequest.Builder(intentSender).build()
    
             request.launch(intentSenderRequest)
         
     
    

    Fragment中设置:

     class FirstFragment : Fragment() 
         private lateinit var binding: FragmentFirstBinding
         private lateinit var gpsOnRequest: ActivityResultLauncher<IntentSenderRequest>
    
         override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View 
             binding = DataBindingUtil.inflate(inflater, R.layout.fragment_first, container, false)
             gpsOnRequest = getGPSOnRequest()
    
             binding.gpsOnButton.setOnClickListener 
                 requestGPSOn(gpsOnRequest)      //extension function, 【will apply specified accuracy even already on!!】
             
    
             return binding.root
         
    
         private fun getGPSOnRequest() = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult())  result ->
             if (result.resultCode != RESULT_OK) 
                 //do your stuff
             
         
     
    

演示:https://youtu.be/nWsSADUmGzM


用于检查 GPS 状态:

fun Fragment.isGPSOn(): Boolean 
    val locationManager = requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager

    return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)

请注意,startActivityForResult()startIntentSenderForResult() 已被弃用,新的​​ Result api 请查看此官方视频:https://youtu.be/oP-zXjkT0C0。

【讨论】:

结果显示给你什么样的对话框? @Morozov 你想要的那个,你没有看我的演示视频吗? 您的对话框以中文打开,所以我不确定。感谢您的回复。【参考方案2】:

用下一个解决方案解决了这个问题:

override fun enableGps(activity: FragmentActivity) 
    if (googleApiClient == null) 
        googleApiClient = GoogleApiClient.Builder(context)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(object : GoogleApiClient.ConnectionCallbacks 
                override fun onConnected(bundle: Bundle?) 
                override fun onConnectionSuspended(i: Int) 
                    googleApiClient?.connect()
                
            )
            .addOnConnectionFailedListener  connectionResult ->
                Timber.e("$connectionResult.errorCode")
            .build()
        googleApiClient?.connect()
    
    val locationRequest = LocationRequest.create()
    locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    locationRequest.interval = 10000
    locationRequest.fastestInterval = 5000
    val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)
    builder.setAlwaysShow(true)
    val result: PendingResult<LocationSettingsResult> = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build())
    result.setResultCallback  result ->
        val status: Status = result.status
        when (status.statusCode) 
            LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try 
                // Show the dialog by calling startResolutionForResult(),
                status.startResolutionForResult(
                    activity,
                    REQUEST_LOCATION
                )
             catch (e: IntentSender.SendIntentException) 
                Timber.e(e)
            
            LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> 
                activity.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
            
        
    

【讨论】:

以上是关于如何为 gps 使用特定对话框?的主要内容,如果未能解决你的问题,请参考以下文章

如何为特定的星期几设置重复通知?

如何为 mtp 设备构建路径(可在文件夹浏览对话框中使用)?

如何为 >= Vista 自定义 FileOpen 对话框?

如何为自定义对话框设置边距?

在对话窗口中使用 Glade,如何为按钮添加响应

如何为居中的浮动确认对话框设计 CSS?