1、权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION">uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE">uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE">uses-permission>
<uses-permission android:name="android.permission.INTERNET">uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE">uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">uses-permission>
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS">uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH">uses-permission>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN">uses-permission>
2.设置高德的key
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="您的key" />
<service android:name="com.amap.api.location.APSService" />
获取key的帮助文档:http://lbs.amap.com/api/android-location-sdk/guide/create-project/get-key
3.初始化定位
请在主线程中声明AMapLocationClient类对象,需要传Context类型的参数。推荐用getApplicationConext()方法获取全进程有效的context。
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明定位回调监听器
public AMapLocationListener mLocationListener = new AMapLocationListener();
//初始化定位
mLocationClient = new AMapLocationClient(getApplicationContext());
//设置定位回调监听
mLocationClient.setLocationListener(mLocationListener);
4.配置参数并启动定位
创建AMapLocationClientOption对象
AMapLocationClientOption对象用来设置发起定位的模式和相关参数等。
下面是具体代码:
public class MainActivity extends AppCompatActivity {
Button btn;
TextView tv;
/**
* 需要进行检测的权限数组
*/
protected String[] needPermissions = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE
};
private static final int PERMISSON_REQUESTCODE = 0;
/**
* 判断是否需要检测,防止不停的弹框
*/
private boolean isNeedCheck = true;
//声明AMapLocationClient类对象
public AMapLocationClient mLocationClient = null;
//声明定位回调监听器
//public AMapLocationListener mLocationListener = new AMapLocationListener();
// public AMapLocationListener mLocationListener;
//声明AMapLocationClientOption对象
public AMapLocationClientOption mLocationOption = new AMapLocationClientOption();
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn_get);
tv = (TextView) findViewById(R.id.tv_text);
//初始化定位
initLocation();
//设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//定位
//启动定位
// mLocationClient.startLocation();
//设置参数
// mLocationClient.setLocationOption(getDefaultOption());
Log.e("进入", "点击事件" + "=========================================================================");
//定位监听器
// mLocationListener = new AMapLocationListener() {
// @Override
// public void onLocationChanged(AMapLocation aMapLocation) {
// //
// Log.e("进入", "回调" + "=========================================================================");
// if (aMapLocation != null) {
// if (aMapLocation.getErrorCode() == 0) {
// //可在其中解析amapLocation获取相应内容。
// Log.e("进入", "回调返回" + "aMapLocation != null=========================================================================");
// aMapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见定位类型表
// aMapLocation.getLatitude();//获取纬度
// aMapLocation.getLongitude();//获取经度
// aMapLocation.getAccuracy();//获取精度信息
// aMapLocation.getAddress();//地址,如果option中设置isNeedAddress为false,则没有此结果,网络定位结果中会有地址信息,GPS定位不返回地址信息。
// aMapLocation.getCountry();//国家信息
// aMapLocation.getProvince();//省信息
// aMapLocation.getCity();//城市信息
// aMapLocation.getDistrict();//城区信息
// aMapLocation.getStreet();//街道信息
// aMapLocation.getStreetNum();//街道门牌号信息
// aMapLocation.getCityCode();//城市编码
// aMapLocation.getAdCode();//地区编码
// aMapLocation.getAoiName();//获取当前定位点的AOI信息
// aMapLocation.getBuildingId();//获取当前室内定位的建筑物Id
// aMapLocation.getFloor();//获取当前室内定位的楼层
// // aMapLocation.getGpsStatus();//获取GPS的当前状态
// //获取定位时间
// SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// Date date = new Date(aMapLocation.getTime());
// df.format(date);
// tv.setText(aMapLocation.getAddress());
//
// String s = aMapLocation.getAddress();
// Log.e("定位成功,", "地址" + aMapLocation.getAddress());
//// if (!TextUtils.isEmpty(s)) {
//// stopLocation();
//// }
//
//
// } else {
// //定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。
// Log.e("AmapError", "location Error, ErrCode:"
// + aMapLocation.getErrorCode() + ", errInfo:"
// + aMapLocation.getErrorInfo());
// }
// }
// }
// };
//开始定位
startLocation();
}
});
}
private void startLocation() {
//根据控件的选择,重新设置定位参数
//resetOption();
// 设置定位参数
mLocationClient.setLocationOption(mLocationOption);
// 启动定位
mLocationClient.startLocation();
}
private void initLocation() {
//初始化client
mLocationClient = new AMapLocationClient(this.getApplicationContext());
//设置定位参数
mLocationClient.setLocationOption(getDefaultOption());
// 设置定位监听
mLocationClient.setLocationListener(mLocationListener);
}
/**
* 停止定位
*
* @author
* @since 2.8.0
*/
private void stopLocation() {
// 停止定位
mLocationClient.stopLocation();
}
@Override
protected void onDestroy() {
super.onDestroy();
destroyLocation();
}
private void destroyLocation() {
if (null != mLocationClient) {
mLocationClient.onDestroy();
mLocationClient = null;
mLocationOption = null;
}
}
/**
* 默认的定位参数
*
* @author
* @since 2.8.0
*/
private AMapLocationClientOption getDefaultOption() {
AMapLocationClientOption mOption = new AMapLocationClientOption();
mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
mOption.setGpsFirst(false);//可选,设置是否gps优先,只在高精度模式下有效。默认关闭
//mOption.setHttpTimeOut(30000);//可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
// mOption.setInterval(2000);//可选,设置定位间隔。默认为2秒
mOption.setNeedAddress(true);//可选,设置是否返回逆地理地址信息。默认是true
// mOption.setOnceLocation(false);//可选,设置是否单次定位。默认是false
mLocationOption.setOnceLocation(true); //获取一次定位结果:
mOption.setOnceLocationLatest(false);//可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用
AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
mOption.setSensorEnable(false);//可选,设置是否使用传感器。默认是false
mOption.setWifiScan(true); //可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差
mOption.setLocationCacheEnable(true); //可选,设置是否使用缓存定位,默认为true
return mOption;
}
/**
* 定位监听
*/
AMapLocationListener mLocationListener = new AMapLocationListener() {
@Override
public void onLocationChanged(AMapLocation aMapLocation) {
if (null != aMapLocation) {
//解析定位结果
String result = Utils.getLocationStr(aMapLocation);
tv.setText(result);
Log.e("定位", "aMapLocation is null" + result);
} else {
tv.setText("定位失败,aMapLocation is null");
Log.e("定位失败", "aMapLocation is null");
}
}
};
//----------以下动态获取权限---------
@Override
protected void onResume() {
super.onResume();
if (isNeedCheck) {
checkPermissions(needPermissions);
}
}
/**
* 检查权限
*
* @param
* @since 2.5.0
*/
private void checkPermissions(String... permissions) {
//获取权限列表
List needRequestPermissonList = findDeniedPermissions(permissions);
if (null != needRequestPermissonList
&& needRequestPermissonList.size() > 0) {
//list.toarray将集合转化为数组
ActivityCompat.requestPermissions(this,
needRequestPermissonList.toArray(new String[needRequestPermissonList.size()]),
PERMISSON_REQUESTCODE);
}
}
/**
* 获取权限集中需要申请权限的列表
*
* @param permissions
* @return
* @since 2.5.0
*/
private List findDeniedPermissions(String[] permissions) {
List needRequestPermissonList = new ArrayList();
//for (循环变量类型 循环变量名称 : 要被遍历的对象)
for (String perm : permissions) {
if (ContextCompat.checkSelfPermission(this,
perm) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.shouldShowRequestPermissionRationale(
this, perm)) {
needRequestPermissonList.add(perm);
}
}
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;
}
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] paramArrayOfInt) {
if (requestCode == PERMISSON_REQUESTCODE) {
if (!verifyPermissions(paramArrayOfInt)) { //没有授权
showMissingPermissionDialog(); //显示提示信息
isNeedCheck = false;
}
}
}
/**
* 显示提示信息
*
* @since 2.5.0
*/
private void showMissingPermissionDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.notifyTitle);
builder.setMessage(R.string.notifyMsg);
// 拒绝, 退出应用
builder.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.setPositiveButton(R.string.setting,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startAppSettings();
}
});
builder.setCancelable(false);
builder.show();
}
/**
* 启动应用的设置
*
* @since 2.5.0
*/
private void startAppSettings() {
Intent intent = new Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
public class Utils {
/**
* 开始定位
*/
public final static int MSG_LOCATION_START = 0;
/**
* 定位完成
*/
public final static int MSG_LOCATION_FINISH = 1;
/**
* 停止定位
*/
public final static int MSG_LOCATION_STOP= 2;
public final static String KEY_URL = "URL";
public final static String URL_H5LOCATION = "file:///android_asset/location.html";
/**
* 根据定位结果返回定位信息的字符串
* @param loc
* @return
*/
public synchronized static String getLocationStr(AMapLocation location){
if(null == location){
return null;
}
StringBuffer sb = new StringBuffer();
//errCode等于0代表定位成功,其他的为定位失败,具体的可以参照官网定位错误码说明
if(location.getErrorCode() == 0){
sb.append("定位成功" + "\n");
sb.append("定位类型: " + location.getLocationType() + "\n");
sb.append("经 度 : " + location.getLongitude() + "\n");
sb.append("纬 度 : " + location.getLatitude() + "\n");
sb.append("精 度 : " + location.getAccuracy() + "米" + "\n");
sb.append("提供者 : " + location.getProvider() + "\n");
sb.append("速 度 : " + location.getSpeed() + "米/秒" + "\n");
sb.append("角 度 : " + location.getBearing() + "\n");
// 获取当前提供定位服务的卫星个数
sb.append("星 数 : " + location.getSatellites() + "\n");
sb.append("国 家 : " + location.getCountry() + "\n");
sb.append("省 : " + location.getProvince() + "\n");
sb.append("市 : " + location.getCity() + "\n");
sb.append("城市编码 : " + location.getCityCode() + "\n");
sb.append("区 : " + location.getDistrict() + "\n");
sb.append("区域 码 : " + location.getAdCode() + "\n");
sb.append("地 址 : " + location.getAddress() + "\n");
sb.append("兴趣点 : " + location.getPoiName() + "\n");
//定位完成的时间
sb.append("定位时间: " + formatUTC(location.getTime(), "yyyy-MM-dd HH:mm:ss") + "\n");
} else {
//定位失败
sb.append("定位失败" + "\n");
sb.append("错误码:" + location.getErrorCode() + "\n");
sb.append("错误信息:" + location.getErrorInfo() + "\n");
sb.append("错误描述:" + location.getLocationDetail() + "\n");
}
//定位之后的回调时间
sb.append("回调时间: " + formatUTC(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss") + "\n");
return sb.toString();
}
private static SimpleDateFormat sdf = null;
public synchronized static String formatUTC(long l, String strPattern) {
if (TextUtils.isEmpty(strPattern)) {
strPattern = "yyyy-MM-dd HH:mm:ss";
}
if (sdf == null) {
try {
sdf = new SimpleDateFormat(strPattern, Locale.CHINA);
} catch (Throwable e) {
}
} else {
sdf.applyPattern(strPattern);
}
return sdf == null ? "NULL" : sdf.format(l);
}
}
<string name="notifyTitle">提示string>
<string name="notifyMsg">当前应用缺少必要权限。\n\n请点击\"设置\"-\"权限\"-打开所需权限。string>
<string name="gpsNotifyMsg">当前应用需要打开定位功能。\n\n请点击\"设置\"-\"定位服务\"-打开定位功能。string>
<string name="setting">设置string>
<string name="cancel">取消string>
1.检查限限,如果没有就申请,申请权限的方法如下:
ActivityCompat.requestPermissions(this,needRequestPermissonList.toArray(newString[needRequestPermissonList.size()]),PERMISSON_REQUESTCODE);
第一个参数是activity,第二个参数是权限的数组,是数组的格式,,第三个参数是requestCode,requestPermissions()方法内部已经做了判断
2.回调方法
onRequestPermissionsResult(int requestCode,String[] permissions, int[] paramArrayOfInt)
通过判断int[] paramArrayOfInt返回的结果是否 == PackageManager.PERMISSION_GRANTED
如果不等于,则是没有授权,弹出对话框,进行用户选择 如果==于,则说明已经授权完成