Android 使用开发者模式允许模拟位置
2020-05-10 本文已影响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")
}
}
}
}
注: 需要开启开发者模式及选择模拟位置信息应用