美文网首页
Android 使用开发者模式允许模拟位置

Android 使用开发者模式允许模拟位置

作者: _凌浩雨 | 来源:发表于2020-05-10 13:45 被阅读0次
1. 添加权限
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <!-- Android 10 需要, 后台读取位置信息 -->
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
    <!-- 模拟位置 -->
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
        tools:ignore="MockLocation,ProtectedPermissions" />
2. 获取位置管理者
        // 获取位置管理服务
       val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
3. 添加请求位置更新
locationManager?.requestLocationUpdates(
            LocationManager.GPS_PROVIDER,
            1000L,
            10F,
            object :
                LocationListener {
                override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {
                    debug("onStatusChanged")
                }

                @SuppressLint("MissingPermission")
                override fun onProviderEnabled(provider: String) {
                    debug("onProviderEnabled")
                    val lastKnownLocation = locationManager?.getLastKnownLocation(provider)
                    upData(lastKnownLocation)
                }

                override fun onProviderDisabled(provider: String) {
                    debug("onProviderDisabled")
                }

                override fun onLocationChanged(location: Location) {
                    // 当GPS定位信息发生改变时,更新位置
                    debug("onLocationChanged")
                    upData(location)
                }
            })
4. 判断是否允许模拟位置
        // 判断是否开启允许模拟位置
        // Android 6.0以下,通过Setting.Secure.ALLOW_MOCK_LOCATION判断
        // Android 6.0及以上,需要【选择模拟位置信息应用】,未找到方法,因此通过addTestProvider是否可用判断
        var canMockPosition =
            (Settings.Secure.getInt(contentResolver, Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0)
                    || Build.VERSION.SDK_INT >= Build.VERSION_CODES.M

5. 添加测试位置提供
                // gps 提供
                val providerStr = LocationManager.GPS_PROVIDER
                // 位置提供者
                val provider = locationManager?.getProvider(providerStr)
                if (null != provider) {
                    // 添加测试位置提供
                    locationManager?.addTestProvider(
                        provider.name,
                        provider.requiresNetwork(),
                        provider.requiresSatellite(),
                        provider.requiresCell(),
                        provider.hasMonetaryCost(),
                        provider.supportsAltitude(),
                        provider.supportsSpeed(),
                        provider.supportsBearing(),
                        provider.powerRequirement,
                        provider.accuracy
                    )
                } else {
                    locationManager?.addTestProvider(
                        providerStr, true, true, false,
                        false, true, true, true, Criteria.POWER_HIGH,
                        Criteria.ACCURACY_FINE
                    )
                }
                // 设置测试提供可用
                locationManager?.setTestProviderEnabled(providerStr, true)
                // 设置测试提供状态
                locationManager?.setTestProviderStatus(
                    providerStr,
                    LocationProvider.AVAILABLE,
                    null,
                    System.currentTimeMillis()
                )
                // 模拟位置可用
                hasAddTestProvider = true
6. 打印位置信息

    private fun upData(location: Location?) {
        if (location != null) {
            val sb = StringBuilder()
            sb.append("实时的位置信息:\n")
            sb.append("经度:")
            sb.append(location.longitude)
            sb.append("\n纬度:")
            sb.append(location.latitude)
            sb.append("\n高度:")
            sb.append(location.altitude)
            sb.append("\n速度:")
            sb.append(location.speed)
            sb.append("\n方向:")
            sb.append(location.bearing)
            sb.append("\n当地时间:")
            sb.append(location.time)

            val geocoder = Geocoder(this)
            val address = geocoder.getFromLocation(location.latitude, location.longitude, 1)[0]
            sb.append("\n国家: ")
            sb.append(address.countryName)
            sb.append("\n城市: ")
            sb.append(address.locality)
            var i = 0
            val addressLine: String? = address.getAddressLine(i)
            while (addressLine.isNullOrEmpty()) {
                sb.append("\n街道$i:")
                sb.append(addressLine)
                i++
            }
            debug(sb.toString())

            updateLocation(location)
        }
    }
7. 更新位置
    /**
     * 更新位置
     */
    private fun updateLocation(location: Location) {
        thread {
            while (true) {
                Thread.sleep(1000)

                if (hasAddTestProvider) {
                    val providerStr = LocationManager.GPS_PROVIDER
                    val mockLocation = Location(providerStr)
//                    mockLocation.latitude = location.latitude + 0.002715f// 维度(度)
//                    mockLocation.longitude = location.longitude - 0.0051f // 经度(度)
                    mockLocation.latitude = 43.870168
                    mockLocation.longitude = 87.562230
                    mockLocation.altitude = location.altitude // 高程(米)
                    mockLocation.bearing = location.bearing // 方向(度)
                    mockLocation.speed = location.speed //速度(米/秒)
                    mockLocation.accuracy = location.accuracy // 精度(米)
                    mockLocation.time = Date().time // 本地时间
                    mockLocation.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
                    locationManager?.setTestProviderLocation(providerStr, mockLocation)
                } else {
                    debug("hasAddTestProvider: $hasAddTestProvider")
                }
            }
        }
    }

注: 需要开启开发者模式及选择模拟位置信息应用

项目地址

相关文章

网友评论

      本文标题:Android 使用开发者模式允许模拟位置

      本文链接:https://www.haomeiwen.com/subject/moadnhtx.html