Android 中定位方式基本能够分为两种:GPS定位,网络定位。php
GPS定位的工做原理是基于手机内置的GPS硬件直接和卫星进行交互来获取当前的经纬度信息,这种方式的精确度很是高,可是缺点是只能在室外使用,并且费电。html
网络定位的工做原理是根据手机当前的网络附近的三个基站进行测速,以此计算出手机和每一个基站之间的距离,再经过三角定位肯定出一个带盖的位置,这种方式优势是在室内外均可以使用,可是精确度通常。java
百度地图类参考:http://wiki.lbsyun.baidu.com/cms/androidsdk/doc/v4_4_1/index.html?overview-summary.htmlandroid
接下来,咱们将基于百度地图SDK来开发。该SDK免费对外开发,且使用无次数限制。不过使用前须要申请秘钥(AK)才可使用。git
首先须要注册一个百度帐号而后申请API Key, 申请地址: http://lbsyun.baidu.com/apiconsole/keyapi
Android 定位SDK 官方指南:http://lbsyun.baidu.com/index.php?title=android-locsdk网络
建立应用:app
http://lbsyun.baidu.com/apiconsole/keyide
关于获取SHA1:函数
(1) cd c:\Users\用户名\.android (2) keytool -list -v -keystore debug.keystore (3)直接回车,不须要输入密码 (4)而后就能够查看到 SHA1 注意这个SHA1为开发版SHA1指纹
提交以后就能够看到咱们申请到的AK了:
下载地址:http://lbsyun.baidu.com/sdk/download
选择咱们须要的功能,而后点击开发包开始下载
下载时候解压,包文件下载到对应目录下:
注意jniLibs目录须要本身建立;
解压后的 so 文件为C/C++语言进行编写,而后在用NDK 编译出来的。
获取当前位置信息官方文档: http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/getloc
public class MainActivity extends AppCompatActivity { public LocationClient mLocationClient; private TextView tvPosition; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLocationClient = new LocationClient(getApplicationContext()); mLocationClient.registerLocationListener(new MyLocationListener()); //注册调用函数 tvPosition = (TextView) findViewById(R.id.activity_main_tv_position); /** * 运行时权限申请 */ List<String> permissionList = new ArrayList<>(); //存储须要申请的全部权限 //GPS 定位信息 if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION); } //读取手机当前状态 if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { permissionList.add(Manifest.permission.READ_PHONE_STATE); } //读写外部存储 if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); } //若没有权限则申请权限 if (!permissionList.isEmpty()) { String[] permissions=permissionList.toArray(new String[permissionList.size()]); ActivityCompat.requestPermissions(MainActivity.this,permissions, 1); } else { requestLocation(); } } /** * 开始定位 */ private void requestLocation() { initLocation(); // 开始定位,回调结果会返回咱们注册的监听器中 MyLocationListener mLocationClient.start(); } private void initLocation(){ //LocationClientOption类,该类用来设置定位SDK的定位方式 LocationClientOption option=new LocationClientOption(); /**设置发起定位请求的时间间隔,默认0,即仅定位一次 */ option.setScanSpan(5000); //可选,默认高精度,设置定位模式,高精度,低功耗,仅设备 option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy); //可选,设置是否须要地址信息,默认不须要 option.setIsNeedAddress(true); //可选,默认false,设置是否使用gps option.setOpenGps(true); //可选,默认false,设置是否须要位置语义化结果,能够在BDLocation.getLocationDescribe里获得,结果相似于“在北京天安门附近” option.setIsNeedLocationDescribe(true); //可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死 option.setIgnoreKillProcess(false); mLocationClient.setLocOption(option); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case 1: if(grantResults.length >0){ for(int result:grantResults){ if(result!=PackageManager.PERMISSION_GRANTED){ Toast.makeText(this, "必须赞成全部权限才能使用该程序", Toast.LENGTH_SHORT).show(); finish(); //退出程序 return; } } requestLocation(); //开始定位 }else { Toast.makeText(this, "发生未知错误", Toast.LENGTH_SHORT).show(); finish(); } break; } } @Override protected void onDestroy() { super.onDestroy(); mLocationClient.stop(); //活动销毁后中止定位,减小电量消耗 } public class MyLocationListener implements BDLocationListener { @Override public void onReceiveLocation(BDLocation bdLocation) { StringBuilder currentPosition = new StringBuilder(); currentPosition.append("纬度:" + bdLocation.getLatitude() + "\n"); currentPosition.append("经度:" + bdLocation.getLongitude() + "\n"); currentPosition.append("定位方式:"); int locType= bdLocation.getLocType(); //获取定位方式 if (locType== BDLocation.TypeGpsLocation) { currentPosition.append("GPS\n"); } else if (locType == BDLocation.TypeNetWorkLocation) { currentPosition.append("网络\n"); } currentPosition.append("LocationDescribe:" + bdLocation.getLocationDescribe() + "\n"); currentPosition.append("Country:" + bdLocation.getCountry() + "\n"); currentPosition.append("Province:" + bdLocation.getProvince() + "\n"); currentPosition.append("City:" + bdLocation.getCity() + "\n"); currentPosition.append("District:" + bdLocation.getDistrict() + "\n"); currentPosition.append("Street:" + bdLocation.getStreet() + "\n"); currentPosition.append("StreetNumber:" + bdLocation.getStreetNumber() + "\n"); currentPosition.append("AddrStr:" + bdLocation.getAddrStr() + "\n"); tvPosition.setText(currentPosition); //显示到界面当中 } } }
在地图中显示位置
首先地图中添加 MapView控件
<com.baidu.mapapi.map.MapView android:id="@+id/activity_map_mapView" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true"/>
MapActivity :
public class MapActivity extends AppCompatActivity { public LocationClient mLocationClient; private MapView mapView; private BaiduMap baiduMap; private boolean isFirstLocate=true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLocationClient = new LocationClient(getApplicationContext()); mLocationClient.registerLocationListener(new MyLocationListener()); SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_map); getSupportActionBar().hide();//隐藏ActionBar mapView=(MapView)findViewById(R.id.activity_map_mapView); baiduMap=mapView.getMap(); baiduMap.setMyLocationEnabled(true); //显示当前设备位置 baiduMap.setCompassEnable(true); //是否显示指南针 //baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);//卫星地图 requestLocation(); } /** * 设置地图显示位置 */ private void navigateTo(BDLocation location){ if(isFirstLocate){ LatLng latLng = new LatLng(location.getLatitude(),location.getLongitude()); //用于存放经纬度 MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(latLng); baiduMap.animateMapStatus(update); update =MapStatusUpdateFactory.zoomTo(16f); //设置缩放级别 baiduMap.animateMapStatus(update); isFirstLocate=false; } //显示当前位置图标 MyLocationData.Builder builder=new MyLocationData.Builder(); builder.latitude(location.getLatitude()); builder.longitude(location.getLongitude()); MyLocationData locationData=builder.build(); baiduMap.setMyLocationData(locationData); } /** * 开始定位 */ private void requestLocation() { initLocation(); // 开始定位,回调结果会返回咱们注册的监听器中 MyLocationListener mLocationClient.start(); } private void initLocation(){ //LocationClientOption类,该类用来设置定位SDK的定位方式 LocationClientOption option=new LocationClientOption(); /**设置发起定位请求的时间间隔,默认0,即仅定位一次 */ option.setScanSpan(5000); mLocationClient.setLocOption(option); } @Override protected void onResume() { super.onResume(); mapView.onResume(); } @Override protected void onPause() { super.onPause(); mapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); } public class MyLocationListener implements BDLocationListener{ @Override public void onReceiveLocation(BDLocation bdLocation) { //若是已经定位成功 if(bdLocation.getLocType()==BDLocation.TypeGpsLocation ||bdLocation.getLocType()==BDLocation.TypeNetWorkLocation){ navigateTo(bdLocation); } } } }