社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Build;
import android.os.SystemClock;
import android.provider.Settings;
import java.util.ArrayList;
import java.util.List;
/**
* 模拟位置辅助类
* 需在AndroidManifest.xml中添加模拟位置权限 android.permission.ACCESS_MOCK_LOCATION
*/
public class MockPositionManager {
private static MockPositionManager instance = null;
public static MockPositionManager getInstance() {
if (instance == null) {
instance = new MockPositionManager();
}
return instance;
}
private MockPositionManager() {
}
private Context appCtx = null;
private LocationManager locationManager = null;
/**
* 模拟位置的提供者
*/
private List<String> mockProviders = null;
public List<String> getMockProviders() {
return mockProviders;
}
/**
* 是否成功addTestProvider,默认为true,软件启动时防止意外退出导致未重置,重置一次
* 通过成功addTestProvider判断是否已经设置当前应用进行模拟位置
*/
private boolean hasAddTestProvider = true;
public boolean hasAddTestProvider() {
return hasAddTestProvider || getUseMockPosition();
}
/**
* 是否正在模拟位置
*/
public boolean isMocking() {
return hasAddTestProvider;
}
/**
* 初始化
*/
public boolean init(Context context) {
appCtx = context.getApplicationContext();
locationManager = (LocationManager) appCtx.getSystemService(Context.LOCATION_SERVICE);
if (locationManager == null) {
return false;
}
mockProviders = new ArrayList<>();
mockProviders.add(LocationManager.GPS_PROVIDER);
// mockProviders.add(LocationManager.NETWORK_PROVIDER);
// PASSIVE不允许模拟
// mockProviders.add(locationManager.PASSIVE_PROVIDER);
// 防止程序意外终止,没有及时清除模拟GPS
resetLocationManager();
return true;
}
/**
* 模拟位置,模拟后系统将不输出NMEA数据
*/
public boolean mockLocation(Location location) {
// 系统未开启模拟位置
if (hasAddTestProvider == false && getUseMockPosition() == false) {
return false;
}
try {
for (String provider : mockProviders) {
Location mockLocation = null;
if (location == null) {
mockLocation = new Location(provider);
} else {
mockLocation = new Location(location);
mockLocation.setProvider(provider);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
mockLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
}
locationManager.setTestProviderLocation(provider, mockLocation);
}
return true;
} catch (Exception ex) {
resetLocationManager();
return false;
}
}
/**
* 模拟位置是否启用,若启用,则addTestProvider
*/
private boolean getUseMockPosition() {
if (isSupportGps() == false) {
return false;
}
// Android 6.0以下,通过Setting.Secure.ALLOW_MOCK_LOCATION判断
// Android 6.0及以上,需要【选择模拟位置信息应用】,未找到方法,因此通过addTestProvider是否可用判断
boolean result = (Settings.Secure.getInt(appCtx.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0)
|| Build.VERSION.SDK_INT > 22;
if (result && hasAddTestProvider == false) {
try {
for (String providerStr : mockProviders) {
LocationProvider provider = locationManager.getProvider(providerStr);
if (provider != null) {
locationManager.addTestProvider(
provider.getName()
, provider.requiresNetwork()
, provider.requiresSatellite()
, provider.requiresCell()
, provider.hasMonetaryCost()
, provider.supportsAltitude()
, provider.supportsSpeed()
, provider.supportsBearing()
, provider.getPowerRequirement()
, provider.getAccuracy());
} else {
if (providerStr.equals(LocationManager.GPS_PROVIDER)) {
locationManager.addTestProvider(
providerStr
, true, true, false, false, true, true, true
, Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
} else if (providerStr.equals(LocationManager.NETWORK_PROVIDER)) {
locationManager.addTestProvider(
providerStr
, true, false, true, false, false, false, false
, Criteria.POWER_LOW, Criteria.ACCURACY_FINE);
} else {
locationManager.addTestProvider(
providerStr
, false, false, false, false, true, true, true
, Criteria.POWER_LOW, Criteria.ACCURACY_FINE);
}
}
locationManager.setTestProviderEnabled(providerStr, true);
locationManager.setTestProviderStatus(providerStr, LocationProvider.AVAILABLE, null, System.currentTimeMillis());
}
// 模拟位置可用
hasAddTestProvider = true;
result = true;
} catch (SecurityException e) {
result = false;
}
}
if (result == false) {
resetLocationManager();
}
return result;
}
/**
* 检测设备是否有GPS模块
*/
private boolean isSupportGps() {
if (locationManager == null) {
return false;
}
return locationManager.getAllProviders().contains(LocationManager.GPS_PROVIDER);
}
/**
* 取消位置模拟,以免启用模拟数据后无法还原使用系统位置
* 若模拟位置未开启,则removeTestProvider将会抛出异常;
* 若已addTestProvider后,关闭模拟位置,未removeTestProvider将导致系统GPS无数据更新;
*/
public void resetLocationManager() {
if (locationManager == null) {
return;
}
if (hasAddTestProvider) {
for (String provider : mockProviders) {
try {
if (locationManager.getAllProviders().contains(provider)) {
locationManager.removeTestProvider(provider);
}
} catch (IllegalArgumentException e1) {
// 未成功addTestProvider时报错,为防万一有重复调用remove,因此此处不需要输出日志
} catch (SecurityException e2) {
// 若在程序运行过程中,直接关闭系统的允许模拟位置,会导致removeTestProvider报错,
// 将导致模拟位置无法正常停止、系统位置不更新的问题
}
}
hasAddTestProvider = false;
}
}
}
public class MockPositionActivity extends BaseActivity<AndroidViewModel, ActivityMockPositionBinding> {
@Override
protected int getContentViewId() {
return R.layout.activity_mock_position;
}
private LocationManager locationManager;
/**
* 是否开启模拟位置
*/
private volatile boolean isEnableMockLocation = false;
@SuppressLint("MissingPermission")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 初始化
MockPositionManager.getInstance().init(this);
// 开关模拟位置
toggleMockLocation(isEnableMockLocation);
dataBinding.setOnMockPositionClickListener(v -> {
if (isEnableMockLocation) {
isEnableMockLocation = false;
MockPositionManager.getInstance().resetLocationManager();
} else {
if (MockPositionManager.getInstance().hasAddTestProvider() == false) {
Toast.makeText(this, "请在【开发者选项】中设置模拟位置信息应用!", Toast.LENGTH_LONG).show();
return;
}
isEnableMockLocation = true;
// 先关上,等待达到条件再模拟
MockPositionManager.getInstance().resetLocationManager();
}
toggleMockLocation(isEnableMockLocation);
});
// 获取系统GPS位置
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
RxPermissions permissions = new RxPermissions(this);
permissions.request(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION)
.subscribe(aBoolean -> {
if (aBoolean) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, locationListener);
// 模拟位置
Observable.interval(1, TimeUnit.SECONDS)
.compose(bindToLifecycle())
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> {
if (isEnableMockLocation) {
Location mockLocation = new Location(LocationManager.GPS_PROVIDER);
mockLocation.setLatitude(30.);
mockLocation.setLongitude(121.);
mockLocation.setAltitude(50.);
mockLocation.setTime(System.currentTimeMillis() / 1000);
mockLocation.setAccuracy(0.01f);
mockLocation.setSpeed(100);
mockLocation.setBearing(90);
MockPositionManager.getInstance().mockLocation(mockLocation);
} else {
MockPositionManager.getInstance().resetLocationManager();
}
});
}
});
}
@Override
protected void onDestroy() {
// 取消模拟位置
MockPositionManager.getInstance().resetLocationManager();
// 停止系统定位
locationManager.removeUpdates(locationListener);
locationManager = null;
super.onDestroy();
}
private void toggleMockLocation(boolean isEnable) {
if (isEnable) {
dataBinding.tvMockPosition.setText("开启");
dataBinding.ivMockPosition.setImageResource(R.drawable.ic_enable);
} else {
dataBinding.tvMockPosition.setText("关闭");
dataBinding.ivMockPosition.setImageResource(R.drawable.ic_disable);
}
}
private LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
dataBinding.tvTime.setText(new Date(location.getTime()).toString());
dataBinding.tvLatitude.setText(String.valueOf(location.getLatitude()));
dataBinding.tvLongitude.setText(String.valueOf(location.getLongitude()));
dataBinding.tvAltitude.setText(String.valueOf(location.getAltitude()));
dataBinding.tvSpeed.setText(String.valueOf(location.getSpeed()));
dataBinding.tvBearing.setText(String.valueOf(location.getBearing()));
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
};
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!