① 注册高德地图的开发者,获取key
过程如图
②下载SDK,导入jar包
注意这里要导入高德地图定位SDK的jar包!!!
如果你先前导入过地图SDK(如2D,3D地图的SDK)再导入定位的SDK运行时就会报错,包名重复!
解决方法:删除所有jar包,只导入定位SDK的jar包
③配置AndroidManifes.xml文件
权限 + service + 密钥
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
......................
<service android:name="com.amap.api.location.APSService" />
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="你先前申请的key" />
</application>
④布局文件
<com.amap.api.maps2d.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.amap.api.maps2d.MapView>
⑤MainActivity.java
结合了大佬代码和官方Demo
继承的PermissionsActivity为官方Demo的权限申请类
public class MainActivity extends PermissionsActivity implements LocationSource,AMapLocationListener {
//
private MapView mapView;
private AMap aMap;
//
private AMapLocationClient mLocationClient = null;//定位发起端
private AMapLocationClientOption mLocationClientOption = null;//定位参数
private OnLocationChangedListener mListener = null;//定位监听器
//
private boolean isFirstLoc = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mapView = (MapView) findViewById(R.id.map);//找到地图控件
//在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
mapView.onCreate(savedInstanceState);
aMap = mapView.getMap();//初始化地图控制器对象
//设置显示定位按钮 并且可以点击
UiSettings settings = aMap.getUiSettings();
//设置定位监听
aMap.setLocationSource(this);
//是否显示定位按钮
settings.setMyLocationButtonEnabled(true);
//是否可触发定位并显示定位层
aMap.setMyLocationEnabled(true);
//设置定位点的图标 默认为蓝色小点
MyLocationStyle myLocationStyle = new MyLocationStyle();
aMap.setMyLocationStyle(myLocationStyle);
//开始定位
initLoc();
}
//定位
private void initLoc() {
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
//设置定位回调监听
mLocationClient.setLocationListener(this);
//初始化参数定位
mLocationClientOption = new AMapLocationClientOption();
//设置定位模式
mLocationClientOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
//设置是否返回地址信息,默认返回
mLocationClientOption.setNeedAddress(true);
//设置是否强制刷新WIFI,默认强制
mLocationClientOption.setWifiScan(true);
//设置定位间隔 ms
mLocationClientOption.setInterval(2000);
//给定客户端对象设置定位参数
mLocationClient.setLocationOption(mLocationClientOption);
//启动定位
mLocationClient.startLocation();
}
//定位回调函数 必须重写
public void onLocationChanged(AMapLocation aMapLocation) {
if (aMapLocation != null) {
if (aMapLocation.getErrorCode() == 0) {
//定位成功 回调信息 设置相关信息
aMapLocation.getLocationType();//获取定位结果来源
aMapLocation.getLatitude();//获取纬度
aMapLocation.getLongitude();//获取经度
aMapLocation.getAccuracy();//获取精确信息
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(aMapLocation.getTime());
df.format(date);
aMapLocation.getAddress();//地址,如果option中设置isNeedAddress为false,则没有此结果,网络定位结果中会有地址信息,GPS定位不返回地址信息。
aMapLocation.getCountry();//国家信息
aMapLocation.getProvince();//省信息
aMapLocation.getCity();//城市信息
aMapLocation.getDistrict();//城区信息
aMapLocation.getStreet();//街道信息
aMapLocation.getStreetNum();//街道门牌号信息
aMapLocation.getCityCode();//城市编码
aMapLocation.getAdCode();//地区编码
if (isFirstLoc) {
//缩放级别
aMap.moveCamera(CameraUpdateFactory.zoomTo(17));
//将地图移动到定位点
aMap.moveCamera(CameraUpdateFactory.changeLatLng(
new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude())));
//点击定位按钮 能够将地图的中心点移动到定位点
mListener.onLocationChanged(aMapLocation);
isFirstLoc = false;
}
} else {
//显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。
Log.e("AmapError", "location Error, ErrCode:"
+ aMapLocation.getErrorCode() + ", errInfo:"
+ aMapLocation.getErrorInfo());
Toast.makeText(getApplicationContext(), "定位失败", Toast.LENGTH_LONG).show();
}
}
}
//激活定位
@Override
public void activate(OnLocationChangedListener listener) {
mListener = listener;
}
//停止定位
@Override
public void deactivate() {
mListener = null;
}
/**
* 方法必须重写
*/
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
/**
* 方法必须重写
*/
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
/**
* 方法必须重写
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
/**
* 方法必须重写
*/
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
}
⑥PermissionsActivity.java
新建一个java文件,或者可以直接从官方Demo中拷贝过来
........\AMap_Android_Demo\AMap_Android_API_Location_Demo\android_studio\AMapLocationDemo\app\src\main
\java\com\amap\location\demo\CheckPermissionsActivity.java
以下代码为精简过的CheckPermissionsActivity.java
public class PermissionsActivity extends Activity {
/**
* 需要进行检测的权限数组
*/
protected String[] needPermissions = {
//在这里添加你所需的权限
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
};
private static final int PERMISSON_REQUESTCODE = 0;
/**
* 判断是否需要检测,防止不停的弹框
*/
private boolean isNeedCheck = true;
@Override
protected void onResume() {
super.onResume();
if (Build.VERSION.SDK_INT >= 23
&& getApplicationInfo().targetSdkVersion >= 23) {
if (isNeedCheck) {
checkPermissions(needPermissions);
}
}
}
/**
*
* @param permissions
* @since 2.5.0
*
*/
private void checkPermissions(String... permissions) {
try {
if (Build.VERSION.SDK_INT >= 23
&& getApplicationInfo().targetSdkVersion >= 23) {
List<String> needRequestPermissonList = findDeniedPermissions(permissions);
if (null != needRequestPermissonList
&& needRequestPermissonList.size() > 0) {
String[] array = needRequestPermissonList.toArray(new String[needRequestPermissonList.size()]);
Method method = getClass().getMethod("requestPermissions", new Class[]{String[].class,
int.class});
method.invoke(this, array, PERMISSON_REQUESTCODE);
}
}
} catch (Throwable e) {
}
}
/**
* 获取权限集中需要申请权限的列表
*
* @param permissions
* @return
* @since 2.5.0
*
*/
private List<String> findDeniedPermissions(String[] permissions) {
List<String> needRequestPermissonList = new ArrayList<String>();
if (Build.VERSION.SDK_INT >= 23
&& getApplicationInfo().targetSdkVersion >= 23){
try {
for (String perm : permissions) {
Method checkSelfMethod = getClass().getMethod("checkSelfPermission", String.class);
Method shouldShowRequestPermissionRationaleMethod = getClass().getMethod("shouldShowRequestPermissionRationale",
String.class);
if ((Integer)checkSelfMethod.invoke(this, perm) != PackageManager.PERMISSION_GRANTED
|| (Boolean)shouldShowRequestPermissionRationaleMethod.invoke(this, perm)) {
needRequestPermissonList.add(perm);
}
}
} catch (Throwable e) {
}
}
return needRequestPermissonList;
}
/**
* 检测是否所有的权限都已经授权
* @param grantResults
* @return
* @since 2.5.0
*
*/
private boolean verifyPermissions(int[] grantResults) {
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
@TargetApi(23)
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] paramArrayOfInt) {
if (requestCode == PERMISSON_REQUESTCODE) {
if (!verifyPermissions(paramArrayOfInt)) {
isNeedCheck = false;
}
}
}
}
效果如图