mirror of
https://github.com/ZCShou/GoGoGo.git
synced 2026-06-13 21:00:55 +08:00
改进了主界面,以适应广告的显示
This commit is contained in:
parent
5a36983573
commit
55c3641cd1
@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="safecode">15:38:B2:88:83:D9:3C:65:6C:80:4C:B9:22:5A:A2:D4:21:82:EB:90;com.zcshou.gogogo</string>
|
||||
|
||||
<string name="ad_unit_id_welcome" translatable="false">ca-app-pub-3940256099942544/6300978111</string>
|
||||
<!-- ads -->
|
||||
<string name="ad_unit_id_main_banner" translatable="false">ca-app-pub-3940256099942544/6300978111</string>
|
||||
<string name="ad_unit_id_go_start" translatable="false">ca-app-pub-3940256099942544/1033173712</string>
|
||||
</resources>
|
||||
@ -64,6 +64,7 @@ import com.baidu.location.BDLocation;
|
||||
import com.baidu.location.LocationClient;
|
||||
import com.baidu.location.LocationClientOption;
|
||||
import com.baidu.mapapi.map.BaiduMap;
|
||||
import com.baidu.mapapi.map.BaiduMapOptions;
|
||||
import com.baidu.mapapi.map.BitmapDescriptor;
|
||||
import com.baidu.mapapi.map.BitmapDescriptorFactory;
|
||||
import com.baidu.mapapi.map.MapPoi;
|
||||
@ -257,12 +258,7 @@ public class MainActivity extends BaseActivity
|
||||
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||
}
|
||||
|
||||
// 地图初始化
|
||||
mMapView = findViewById(id.bmapView);
|
||||
mBaiduMap = mMapView.getMap();
|
||||
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
|
||||
mBaiduMap.setMyLocationEnabled(true);
|
||||
initMapListener();
|
||||
initBaiduMap();
|
||||
|
||||
//网络是否可用
|
||||
if (!isNetworkAvailable()) {
|
||||
@ -584,6 +580,280 @@ public class MainActivity extends BaseActivity
|
||||
public void onAccuracyChanged(Sensor sensor, int i) {
|
||||
}
|
||||
|
||||
//判断GPS是否打开
|
||||
private boolean isGpsOpened() {
|
||||
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
|
||||
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
|
||||
}
|
||||
|
||||
//模拟位置权限是否开启
|
||||
public boolean isAllowMockLocation() {
|
||||
boolean canMockPosition;
|
||||
|
||||
if (Build.VERSION.SDK_INT <= 22) {//6.0以下
|
||||
canMockPosition = Settings.Secure.getInt(this.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0;
|
||||
} else {
|
||||
try {
|
||||
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);//获得LocationManager引用
|
||||
String providerStr = LocationManager.GPS_PROVIDER;
|
||||
LocationProvider provider = locationManager.getProvider(providerStr);
|
||||
|
||||
// 为防止在已有testProvider的情况下导致addTestProvider抛出异常,先移除testProvider
|
||||
try {
|
||||
locationManager.removeTestProvider(providerStr);
|
||||
Log.d("PERMISSION", "try to move test provider");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e("PERMISSION", "try to move test provider");
|
||||
}
|
||||
|
||||
if (provider != null) {
|
||||
try {
|
||||
locationManager.addTestProvider(
|
||||
provider.getName()
|
||||
, provider.requiresNetwork()
|
||||
, provider.requiresSatellite()
|
||||
, provider.requiresCell()
|
||||
, provider.hasMonetaryCost()
|
||||
, provider.supportsAltitude()
|
||||
, provider.supportsSpeed()
|
||||
, provider.supportsBearing()
|
||||
, provider.getPowerRequirement()
|
||||
, provider.getAccuracy());
|
||||
canMockPosition = true;
|
||||
} catch (Exception e) {
|
||||
Log.e("FUCK", "add origin gps test provider error");
|
||||
canMockPosition = false;
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
locationManager.addTestProvider(
|
||||
providerStr
|
||||
, true, true, false, false, true, true, true
|
||||
, Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
|
||||
canMockPosition = true;
|
||||
} catch (Exception e) {
|
||||
Log.e("FUCK", "add gps test provider error");
|
||||
canMockPosition = false;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟位置可用
|
||||
if (canMockPosition) {
|
||||
locationManager.setTestProviderEnabled(providerStr, true);
|
||||
locationManager.setTestProviderStatus(providerStr, LocationProvider.AVAILABLE, null, System.currentTimeMillis());
|
||||
//remove test provider
|
||||
locationManager.setTestProviderEnabled(providerStr, false);
|
||||
locationManager.removeTestProvider(providerStr);
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
canMockPosition = false;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return canMockPosition;
|
||||
}
|
||||
|
||||
//WIFI是否可用
|
||||
private boolean isWifiConnected() {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mWiFiNetworkInfo = mConnectivityManager
|
||||
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
|
||||
|
||||
if (mWiFiNetworkInfo != null) {
|
||||
return mWiFiNetworkInfo.isAvailable();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//MOBILE网络是否可用
|
||||
private boolean isMobileConnected() {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mMobileNetworkInfo = mConnectivityManager
|
||||
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
|
||||
|
||||
if (mMobileNetworkInfo != null) {
|
||||
return mMobileNetworkInfo.isAvailable();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 断是否有网络连接,但是如果该连接的网络无法上网,也会返回true
|
||||
public boolean isNetworkConnected() {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
|
||||
|
||||
if (mNetworkInfo != null) {
|
||||
return mNetworkInfo.isAvailable();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//网络是否可用
|
||||
private boolean isNetworkAvailable() {
|
||||
return ((isWifiConnected() || isMobileConnected()) && isNetworkConnected());
|
||||
}
|
||||
|
||||
//提醒开启位置模拟的弹框
|
||||
private void showEnableMockLocationDialog() {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle("启用位置模拟")//这里是表头的内容
|
||||
.setMessage("请在\"开发者选项→选择模拟位置信息应用\"中进行设置")//这里是中间显示的具体信息
|
||||
.setPositiveButton("设置",//这个string是设置左边按钮的文字
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
try {
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
|
||||
startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
DisplayToast("无法跳转到开发者选项,请先确保您的设备已处于开发者模式");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
})//setPositiveButton里面的onClick执行的是左边按钮
|
||||
.setNegativeButton("取消",//这个string是设置右边按钮的文字
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
})//setNegativeButton里面的onClick执行的是右边的按钮的操作
|
||||
.show();
|
||||
}
|
||||
|
||||
//提醒开启悬浮窗的弹框
|
||||
private void showEnableFloatWindowDialog() {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle("启用悬浮窗")//这里是表头的内容
|
||||
.setMessage("为了模拟定位的稳定性,建议开启\"显示悬浮窗\"选项")//这里是中间显示的具体信息
|
||||
.setPositiveButton("设置",//这个string是设置左边按钮的文字
|
||||
new DialogInterface.OnClickListener() {
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
try {
|
||||
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
|
||||
startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
DisplayToast("无法跳转到设置界面,请在权限管理中开启该应用的悬浮窗");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
})//setPositiveButton里面的onClick执行的是左边按钮
|
||||
.setNegativeButton("取消",//这个string是设置右边按钮的文字
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
})//setNegativeButton里面的onClick执行的是右边的按钮的操作
|
||||
.show();
|
||||
}
|
||||
|
||||
//显示开启GPS的提示
|
||||
private void showEnableGpsDialog() {
|
||||
new AlertDialog.Builder(MainActivity.this)
|
||||
.setTitle("Tips")//这里是表头的内容
|
||||
.setMessage("是否开启GPS定位服务?")//这里是中间显示的具体信息
|
||||
.setPositiveButton("确定",
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
startActivityForResult(intent, 0);
|
||||
}
|
||||
})
|
||||
.setNegativeButton("取消",
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
//显示输入经纬度的对话框
|
||||
public void showInputLatLngDialog() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
|
||||
builder.setTitle("输入经度和纬度(BD09坐标系)");
|
||||
// 通过LayoutInflater来加载一个xml的布局文件作为一个View对象
|
||||
View view = LayoutInflater.from(MainActivity.this).inflate(layout.latlng_dialog, null);
|
||||
// 设置我们自己定义的布局文件作为弹出框的Content
|
||||
builder.setView(view);
|
||||
final EditText dialog_lng = view.findViewById(id.dialog_longitude);
|
||||
final EditText dialog_lat = view.findViewById(id.dialog_latitude);
|
||||
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
String dialog_lng_str, dialog_lat_str;
|
||||
|
||||
try {
|
||||
dialog_lng_str = dialog_lng.getText().toString().trim();
|
||||
dialog_lat_str = dialog_lat.getText().toString().trim();
|
||||
double dialog_lng_double = Double.parseDouble(dialog_lng_str);
|
||||
double dialog_lat_double = Double.parseDouble(dialog_lat_str);
|
||||
|
||||
// DisplayToast("经度: " + dialog_lng_str + ", 纬度: " + dialog_lat_str);
|
||||
if (dialog_lng_double > 180.0 || dialog_lng_double < -180.0 || dialog_lat_double > 90.0 || dialog_lat_double < -90.0) {
|
||||
DisplayToast("经纬度超出限制!\n-180.0<经度<180.0\n-90.0<纬度<90.0");
|
||||
} else {
|
||||
curMapLatLng = new LatLng(dialog_lat_double, dialog_lng_double);
|
||||
MapStatusUpdate mapstatusupdate = MapStatusUpdateFactory.newLatLng(curMapLatLng);
|
||||
//对地图的中心点进行更新
|
||||
mBaiduMap.setMapStatus(mapstatusupdate);
|
||||
markSelectedPosition();
|
||||
transformCoordinate(dialog_lng_str, dialog_lat_str);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
DisplayToast("获取经纬度出错,请检查输入是否正确");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void showFaqDialog() {
|
||||
final android.app.AlertDialog alertDialog = new android.app.AlertDialog.Builder(this).create();
|
||||
alertDialog.show();
|
||||
// alertDialog.setCancelable(false);
|
||||
Window window = alertDialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setContentView(layout.faq);
|
||||
window.setGravity(Gravity.CENTER);
|
||||
window.setWindowAnimations(R.style.DialogAnimFadeInFadeOut);
|
||||
|
||||
TextView tvContent = window.findViewById(R.id.faq_content);
|
||||
String str = "Q:Android 虚拟定位的实现原理是什么?\n"
|
||||
+ "A:具有 ROOT 权限的,一般直接拦截和位置相关的接口更改位置数据。没有 ROOT 权限的,一种是使用 Android 提供的模拟位置 API,一种基于 VirtualApp。\n"
|
||||
+ "\nQ:为何定位总是闪回真实位置?\n"
|
||||
+ "A:这和虚拟定位的实现方式有关系。Android 提供的模拟位置 API 只能模拟 GPS。而安卓的定位数据会同时使用 GPS、网络/WIFI等来实现更精确的定位\n"
|
||||
+ "\nQ:如何防止虚拟定位闪回真实位置?\n"
|
||||
+ "A:对于多数手机,是可以设置定位数据来源的。可以直接关闭从网络/WIFI定位,只允许 GPS 定位;同时关闭 WIFI,仅使用数据流量来上网可有效防止闪回\n"
|
||||
+ "\nQ:为啥在某些软件上没有效果?\n"
|
||||
+ "A:目前仅适用于百度地图和高德地图的SDK定位. 腾讯系列无法使用\n"
|
||||
+ "\nQ:使用位置的 APP 如何检测有没有虚拟定位?\n"
|
||||
+ "A:对于使用 ROOT 权限的虚拟定位,是无法被检测的(但是会检测到 ROOT 权限);使用 Android 提供的模拟位置 API,在 Android 6.0 之后,系统也没有挺检测方式。基于 VirtualApp 的检测方式要多一些。但是通常,如果位置变化较大、较快,APP 会认为定位异常\n";
|
||||
|
||||
SpannableStringBuilder ssb = new SpannableStringBuilder();
|
||||
ssb.append(str);
|
||||
|
||||
tvContent.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
tvContent.setText(ssb, TextView.BufferType.SPANNABLE);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void initGoogleAD() {
|
||||
// 横幅广告
|
||||
AdView mAdView = findViewById(R.id.ad_view);
|
||||
@ -825,278 +1095,14 @@ public class MainActivity extends BaseActivity
|
||||
}
|
||||
}
|
||||
|
||||
//判断GPS是否打开
|
||||
private boolean isGpsOpened() {
|
||||
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
|
||||
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
|
||||
}
|
||||
|
||||
//模拟位置权限是否开启
|
||||
public boolean isAllowMockLocation() {
|
||||
boolean canMockPosition;
|
||||
|
||||
if (Build.VERSION.SDK_INT <= 22) {//6.0以下
|
||||
canMockPosition = Settings.Secure.getInt(this.getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0;
|
||||
} else {
|
||||
try {
|
||||
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);//获得LocationManager引用
|
||||
String providerStr = LocationManager.GPS_PROVIDER;
|
||||
LocationProvider provider = locationManager.getProvider(providerStr);
|
||||
|
||||
// 为防止在已有testProvider的情况下导致addTestProvider抛出异常,先移除testProvider
|
||||
try {
|
||||
locationManager.removeTestProvider(providerStr);
|
||||
Log.d("PERMISSION", "try to move test provider");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e("PERMISSION", "try to move test provider");
|
||||
}
|
||||
|
||||
if (provider != null) {
|
||||
try {
|
||||
locationManager.addTestProvider(
|
||||
provider.getName()
|
||||
, provider.requiresNetwork()
|
||||
, provider.requiresSatellite()
|
||||
, provider.requiresCell()
|
||||
, provider.hasMonetaryCost()
|
||||
, provider.supportsAltitude()
|
||||
, provider.supportsSpeed()
|
||||
, provider.supportsBearing()
|
||||
, provider.getPowerRequirement()
|
||||
, provider.getAccuracy());
|
||||
canMockPosition = true;
|
||||
} catch (Exception e) {
|
||||
Log.e("FUCK", "add origin gps test provider error");
|
||||
canMockPosition = false;
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
locationManager.addTestProvider(
|
||||
providerStr
|
||||
, true, true, false, false, true, true, true
|
||||
, Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
|
||||
canMockPosition = true;
|
||||
} catch (Exception e) {
|
||||
Log.e("FUCK", "add gps test provider error");
|
||||
canMockPosition = false;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟位置可用
|
||||
if (canMockPosition) {
|
||||
locationManager.setTestProviderEnabled(providerStr, true);
|
||||
locationManager.setTestProviderStatus(providerStr, LocationProvider.AVAILABLE, null, System.currentTimeMillis());
|
||||
//remove test provider
|
||||
locationManager.setTestProviderEnabled(providerStr, false);
|
||||
locationManager.removeTestProvider(providerStr);
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
canMockPosition = false;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return canMockPosition;
|
||||
}
|
||||
|
||||
//WIFI是否可用
|
||||
private boolean isWifiConnected() {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mWiFiNetworkInfo = mConnectivityManager
|
||||
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
|
||||
|
||||
if (mWiFiNetworkInfo != null) {
|
||||
return mWiFiNetworkInfo.isAvailable();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//MOBILE网络是否可用
|
||||
private boolean isMobileConnected() {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mMobileNetworkInfo = mConnectivityManager
|
||||
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
|
||||
|
||||
if (mMobileNetworkInfo != null) {
|
||||
return mMobileNetworkInfo.isAvailable();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 断是否有网络连接,但是如果该连接的网络无法上网,也会返回true
|
||||
public boolean isNetworkConnected() {
|
||||
ConnectivityManager mConnectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
|
||||
|
||||
if (mNetworkInfo != null) {
|
||||
return mNetworkInfo.isAvailable();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//网络是否可用
|
||||
private boolean isNetworkAvailable() {
|
||||
return ((isWifiConnected() || isMobileConnected()) && isNetworkConnected());
|
||||
}
|
||||
|
||||
//提醒开启位置模拟的弹框
|
||||
private void showEnableMockLocationDialog() {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle("启用位置模拟")//这里是表头的内容
|
||||
.setMessage("请在\"开发者选项→选择模拟位置信息应用\"中进行设置")//这里是中间显示的具体信息
|
||||
.setPositiveButton("设置",//这个string是设置左边按钮的文字
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
try {
|
||||
Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
|
||||
startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
DisplayToast("无法跳转到开发者选项,请先确保您的设备已处于开发者模式");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
})//setPositiveButton里面的onClick执行的是左边按钮
|
||||
.setNegativeButton("取消",//这个string是设置右边按钮的文字
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
})//setNegativeButton里面的onClick执行的是右边的按钮的操作
|
||||
.show();
|
||||
}
|
||||
|
||||
//提醒开启悬浮窗的弹框
|
||||
private void showEnableFloatWindowDialog() {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle("启用悬浮窗")//这里是表头的内容
|
||||
.setMessage("为了模拟定位的稳定性,建议开启\"显示悬浮窗\"选项")//这里是中间显示的具体信息
|
||||
.setPositiveButton("设置",//这个string是设置左边按钮的文字
|
||||
new DialogInterface.OnClickListener() {
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
try {
|
||||
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
|
||||
startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
DisplayToast("无法跳转到设置界面,请在权限管理中开启该应用的悬浮窗");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
})//setPositiveButton里面的onClick执行的是左边按钮
|
||||
.setNegativeButton("取消",//这个string是设置右边按钮的文字
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
})//setNegativeButton里面的onClick执行的是右边的按钮的操作
|
||||
.show();
|
||||
}
|
||||
|
||||
//显示开启GPS的提示
|
||||
private void showEnableGpsDialog() {
|
||||
new AlertDialog.Builder(MainActivity.this)
|
||||
.setTitle("Tips")//这里是表头的内容
|
||||
.setMessage("是否开启GPS定位服务?")//这里是中间显示的具体信息
|
||||
.setPositiveButton("确定",
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
|
||||
startActivityForResult(intent, 0);
|
||||
}
|
||||
})
|
||||
.setNegativeButton("取消",
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
//显示输入经纬度的对话框
|
||||
public void showInputLatLngDialog() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
|
||||
builder.setTitle("输入经度和纬度(BD09坐标系)");
|
||||
// 通过LayoutInflater来加载一个xml的布局文件作为一个View对象
|
||||
View view = LayoutInflater.from(MainActivity.this).inflate(layout.latlng_dialog, null);
|
||||
// 设置我们自己定义的布局文件作为弹出框的Content
|
||||
builder.setView(view);
|
||||
final EditText dialog_lng = view.findViewById(id.dialog_longitude);
|
||||
final EditText dialog_lat = view.findViewById(id.dialog_latitude);
|
||||
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
String dialog_lng_str, dialog_lat_str;
|
||||
|
||||
try {
|
||||
dialog_lng_str = dialog_lng.getText().toString().trim();
|
||||
dialog_lat_str = dialog_lat.getText().toString().trim();
|
||||
double dialog_lng_double = Double.parseDouble(dialog_lng_str);
|
||||
double dialog_lat_double = Double.parseDouble(dialog_lat_str);
|
||||
|
||||
// DisplayToast("经度: " + dialog_lng_str + ", 纬度: " + dialog_lat_str);
|
||||
if (dialog_lng_double > 180.0 || dialog_lng_double < -180.0 || dialog_lat_double > 90.0 || dialog_lat_double < -90.0) {
|
||||
DisplayToast("经纬度超出限制!\n-180.0<经度<180.0\n-90.0<纬度<90.0");
|
||||
} else {
|
||||
curMapLatLng = new LatLng(dialog_lat_double, dialog_lng_double);
|
||||
MapStatusUpdate mapstatusupdate = MapStatusUpdateFactory.newLatLng(curMapLatLng);
|
||||
//对地图的中心点进行更新
|
||||
mBaiduMap.setMapStatus(mapstatusupdate);
|
||||
markSelectedPosition();
|
||||
transformCoordinate(dialog_lng_str, dialog_lat_str);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
DisplayToast("获取经纬度出错,请检查输入是否正确");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void showFaqDialog() {
|
||||
final android.app.AlertDialog alertDialog = new android.app.AlertDialog.Builder(this).create();
|
||||
alertDialog.show();
|
||||
// alertDialog.setCancelable(false);
|
||||
Window window = alertDialog.getWindow();
|
||||
if (window != null) {
|
||||
window.setContentView(layout.faq);
|
||||
window.setGravity(Gravity.CENTER);
|
||||
window.setWindowAnimations(R.style.DialogAnimFadeInFadeOut);
|
||||
|
||||
TextView tvContent = window.findViewById(R.id.faq_content);
|
||||
String str = "Q:Android 虚拟定位的实现原理是什么?\n"
|
||||
+ "A:具有 ROOT 权限的,一般直接拦截和位置相关的接口更改位置数据。没有 ROOT 权限的,一种是使用 Android 提供的模拟位置 API,一种基于 VirtualApp。\n"
|
||||
+ "\nQ:为何定位总是闪回真实位置?\n"
|
||||
+ "A:这和虚拟定位的实现方式有关系。Android 提供的模拟位置 API 只能模拟 GPS。而安卓的定位数据会同时使用 GPS、网络/WIFI等来实现更精确的定位\n"
|
||||
+ "\nQ:如何防止虚拟定位闪回真实位置?\n"
|
||||
+ "A:对于多数手机,是可以设置定位数据来源的。可以直接关闭从网络/WIFI定位,只允许 GPS 定位;同时关闭 WIFI,仅使用数据流量来上网可有效防止闪回\n"
|
||||
+ "\nQ:为啥在某些软件上没有效果?\n"
|
||||
+ "A:目前仅适用于百度地图和高德地图的SDK定位. 腾讯系列无法使用\n"
|
||||
+ "\nQ:使用位置的 APP 如何检测有没有虚拟定位?\n"
|
||||
+ "A:对于使用 ROOT 权限的虚拟定位,是无法被检测的(但是会检测到 ROOT 权限);使用 Android 提供的模拟位置 API,在 Android 6.0 之后,系统也没有挺检测方式。基于 VirtualApp 的检测方式要多一些。但是通常,如果位置变化较大、较快,APP 会认为定位异常\n";
|
||||
|
||||
SpannableStringBuilder ssb = new SpannableStringBuilder();
|
||||
ssb.append(str);
|
||||
|
||||
tvContent.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
tvContent.setText(ssb, TextView.BufferType.SPANNABLE);
|
||||
|
||||
}
|
||||
private void initBaiduMap() {
|
||||
// 地图初始化
|
||||
mMapView = findViewById(id.bmapView);
|
||||
mMapView.showZoomControls(false);
|
||||
mBaiduMap = mMapView.getMap();
|
||||
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
|
||||
mBaiduMap.setMyLocationEnabled(true);
|
||||
initMapListener();
|
||||
}
|
||||
|
||||
//开启地图的定位图层
|
||||
@ -1127,6 +1133,16 @@ public class MainActivity extends BaseActivity
|
||||
resetMap();
|
||||
}
|
||||
|
||||
//放大地图
|
||||
public void zoomInMap(View view) {
|
||||
mBaiduMap.animateMapStatus(MapStatusUpdateFactory.zoomIn());
|
||||
}
|
||||
|
||||
//缩小地图
|
||||
public void zoomOutMap(View view) {
|
||||
mBaiduMap.animateMapStatus(MapStatusUpdateFactory.zoomOut());
|
||||
}
|
||||
|
||||
//对地图事件的消息响应
|
||||
private void initMapListener() {
|
||||
mBaiduMap.setOnMapTouchListener(new BaiduMap.OnMapTouchListener() {
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="#99000000"
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M957.59,467.39C936.56,255.62 768.15,87.22 556.38,66.2v-2.22h-89.64v2.22C254.98,87.23 86.59,255.63 65.56,467.39h-2.22v89.65h2.22C86.42,767.16 252.39,934.6 461.85,957.71l-0.08,2.73h94.61v-2.22c211.77,-21.02 380.18,-189.43 401.21,-401.19h2.22v-89.65h-2.22zM867.12,557.04c-21.27,158.05 -152.69,289.49 -310.74,310.75v-86.64h-89.64l-2.39,86.3c-156.99,-22.26 -287.18,-153.17 -308.34,-310.41h86.63v-89.65h-86.63c21.27,-158.04 152.68,-289.48 310.73,-310.75v86.63h89.64v-86.64c158.05,21.26 289.47,152.7 310.74,310.75h-86.61v89.65h86.61zM511.58,362.34c-82.77,0 -149.88,67.1 -149.88,149.88 0,82.77 67.1,149.88 149.88,149.88S661.46,595 661.46,512.22s-67.1,-149.88 -149.88,-149.88z"/>
|
||||
</vector>
|
||||
|
||||
9
app/src/main/res/drawable/ic_zoom_in.xml
Normal file
9
app/src/main/res/drawable/ic_zoom_in.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="m511.97,933.36c231.73,0 420.88,-188.82 422.78,-421.82a422.6,421.99 0,0 0,-422.78 -422.41a422.54,421.94 0,0 0,-422.66 422.05a422.54,421.94 0,0 0,422.72 422.11l-0.06,0.06zM482.81,466.12l-193.19,0a44.6,44.54 0,0 0,0 89.13l193.13,0l0,192.85a44.6,44.54 0,1 0,89.2 0l0,-192.79l193.13,0a44.6,44.54 0,0 0,0 -89.13l-193.13,0l0,-192.79a44.6,44.54 0,1 0,-89.2 0l0,192.73l0.06,0zM512.03,1022.37a511.74,511.01 0,0 1,-511.98 -511.13a511.74,511.01 0,0 1,511.92 -511.24c282.98,0 511.98,228.79 511.98,511.9c-2.2,282.16 -231.08,510.59 -511.92,510.59l0,-0.12z"
|
||||
android:fillColor="#FF000000"/>
|
||||
</vector>
|
||||
5
app/src/main/res/drawable/ic_zoom_out.xml
Normal file
5
app/src/main/res/drawable/ic_zoom_out.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<vector android:height="24dp" android:viewportHeight="1024"
|
||||
android:viewportWidth="1024" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000"
|
||||
android:pathData="m511.97,933.92c231.54,0 420.53,-188.93 422.43,-422.07a422.25,422.25 0,0 0,-422.43 -422.66a422.19,422.19 0,0 0,-422.31 422.31a422.19,422.19 0,0 0,422.37 422.37l-0.06,0.06zM512.03,1022.98a511.31,511.31 0,0 1,-511.55 -511.43a511.31,511.31 0,0 1,511.49 -511.55c282.74,0 511.55,228.92 511.55,512.2c-2.2,282.33 -230.88,510.9 -511.49,510.9l0,-0.12zM289.87,555.52l475.06,0a44.56,44.56 0,0 0,0 -89.18l-475.12,0a44.56,44.56 0,0 0,0 89.18l0.06,0z" />
|
||||
</vector>
|
||||
@ -35,7 +35,8 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|start"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
android:layout_marginStart="30dp"
|
||||
android:layout_marginBottom="80dp"
|
||||
android:contentDescription="@string/fabtn_start"
|
||||
app:elevation="6dp"
|
||||
app:pressedTranslationZ="12dp"
|
||||
@ -47,7 +48,8 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|start"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
android:layout_marginStart="30dp"
|
||||
android:layout_marginBottom="80dp"
|
||||
android:visibility="invisible"
|
||||
app:elevation="6dp"
|
||||
app:pressedTranslationZ="12dp"
|
||||
@ -60,7 +62,7 @@
|
||||
android:layout_height="32dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginBottom="130dp"
|
||||
android:layout_marginBottom="174dp"
|
||||
android:background="@drawable/circle_shape"
|
||||
android:orientation="horizontal">
|
||||
|
||||
@ -75,6 +77,46 @@
|
||||
android:contentDescription="@string/map_home"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginBottom="137dp"
|
||||
android:background="@drawable/circle_shape"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/zoom_in"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:onClick="zoomInMap"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:theme="@style/RippleWhite"
|
||||
app:srcCompat="@drawable/ic_zoom_in"
|
||||
android:contentDescription="@string/map_home"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginBottom="100dp"
|
||||
android:background="@drawable/circle_shape"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/zoom_out"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:onClick="zoomOutMap"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:theme="@style/RippleWhite"
|
||||
app:srcCompat="@drawable/ic_zoom_out"
|
||||
android:contentDescription="@string/map_home"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/search_linear"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user