本文使用两种方法实现,一种是使用Android自身原生的API,要稍微复杂一些,而且因为笔者自身的水平有限,做的很简陋。第二种是使用ArGIS API for Android封装好的API,要稍微简单一些,而且页面也要好看很多,具体可以参考官网API。
目录
扫描二维码关注公众号,回复:
4994460 查看本文章
一、 获取手机GPS权限
(1)在manifest页面添加使用手机GPS的权限请求
<!-- GPS定位权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
(2)Android6.0后需要动态获取权限
动态获取权限即大家使用手机软件时弹出的是否同意给xxx软件xxx权限的提示页面,系统版本Android6.0后就必须要动态获取。本文未单独列出,写在函数体里面了。
二、新建地图控件
在地图设计页面上新建两个Button,分别用于两种方式开始定位,当然也可以写在onCreate里直接运行。
一个TextView用于显示提示信息。
<Button
android:id="@+id/gpsLocateBT"
android:layout_width="60dp"
android:layout_height="50dp"
android:layout_marginTop="100dp"
android:layout_marginLeft="180dp"
android:background="@color/colorAccent"
android:text="Android原生"
/>
<Button
android:id="@+id/esriLocateBT"
android:layout_width="60dp"
android:layout_height="50dp"
android:layout_marginTop="100dp"
android:layout_marginLeft="240dp"
android:background="@color/colorAccent"
android:text="esri定位"
/>
<TextView
android:id="@+id/textView_info"
android:layout_width="match_parent"
android:layout_marginTop="150dp"
android:background="@color/colorPrimary"
android:visibility="visible"
android:layout_height="80dp" />
三、定义变量并与页面控件绑定
private Button gpsLocateBT,esriLocateBT;
private TextView info;
gpsLocateBT = findViewById(R.id.gpsLocateBT);
esriLocateBT = findViewById(R.id.esriLocateBT);
info = (TextView) findViewById(R.id.textView_info);
四、两种方式实现封装的函数
(1)调用Esri API实现
private LocationDisplay mLocationDisplay;
函数封装
//Esri封装好的定位(测试无误)
private void setupLocationDisplay() {
mLocationDisplay = mMapView.getLocationDisplay();
mLocationDisplay.addDataSourceStatusChangedListener(dataSourceStatusChangedEvent -> {
// If LocationDisplay started OK or no error is reported, then continue.
if (dataSourceStatusChangedEvent.isStarted() || dataSourceStatusChangedEvent.getError() == null) {
return;
}
int requestPermissionsCode = 2;
String[] requestPermissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
// If an error is found, handle the failure to start.
// Check permissions to see if failure may be due to lack of permissions.
if (!(ContextCompat.checkSelfPermission(EsriMap.this, requestPermissions[0]) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(EsriMap.this, requestPermissions[1]) == PackageManager.PERMISSION_GRANTED)) {
// If permissions are not already granted, request permission from the user.
ActivityCompat.requestPermissions(EsriMap.this, requestPermissions, requestPermissionsCode);
} else {
// Report other unknown failure types to the user - for example, location services may not
// be enabled on the device.
String message = String.format("Error in DataSourceStatusChangedListener: %s", dataSourceStatusChangedEvent
.getSource().getLocationDataSource().getError().getMessage());
Toast.makeText(EsriMap.this, message, Toast.LENGTH_LONG).show();
}
});
mLocationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.COMPASS_NAVIGATION);
mLocationDisplay.startAsync();
}
(2)Android原生API实现
结合上篇博客移动GIS开发之输入经纬度在地图上画点线面,获取手机GPS经纬度后在地图上把点和路线标出来。
private double latitude;
private double longitude;
private LocationManager locationManager;
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
函数封装
private void getgpsLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
//进行授权
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
info.setText("正在获取授权");
}else{
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, (float) 10, locationListener);
if (longitude != 0)
DrawPoint(longitude,latitude);
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, (float) 10, locationListener);
info.setText("纬度:" + latitude + "\n" + "经度:" + longitude);
if (longitude != 0)
DrawPoint(longitude,latitude);
}
}
添加监听器并设置参数,当坐标改变时画折线。
LocationListener locationListener = new LocationListener() {
// Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
info.setText("Provider的状态在可用、暂时不可用和无服务三个状态之间切换");
}
// Provider被enable时触发此函数,比如GPS被打开
@Override
public void onProviderEnabled(String provider) {
Log.e(TAG, provider);
info.setText("Provider被打开");
}
// Provider被disable时触发此函数,比如GPS被关闭
@Override
public void onProviderDisabled(String provider) {
Log.e(TAG, provider);
info.setText("Provider被关闭");
}
// 当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发
@Override
public void onLocationChanged(Location location) {
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
info.setText("纬度:" + latitude + "\n" + "经度:" + longitude);
SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.RED, 5);
Point buoy1Loc = new Point(longitude, latitude, SPATIAL_REFERENCE);
gpspolyline.add(buoy1Loc);
Polyline polyline = new Polyline(gpspolyline);
graphicsOverlay.getGraphics().add(new Graphic(polyline, lineSymbol));
}
}
};
五、添加两个按钮的监听事件
gpsLocateBT.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getgpsLocation();
}
});
esriLocateBT.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setupLocationDisplay();
}
});