Android支持的系统级服务
LocationManager支持定位方法
GPS_PEOVIDER 值是gps , 用GPS定位,精确,但是速度较差.需要权限permissions.ACCESS_FINE_LOCATION
NETWORK_PROVIDER 值是network 网络定位,不过相对位置粗略. 需要权限permissions.ACCESS_FINE_LOCATION 或者permissions.ACCESS_COARSE_LOCATION
获取位置(GPS)
LocationManager lm=(LocationManager) getSystemservice( Context.LOCATION_SERVICE ); //获取系统的地理服务
Location location=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); //使用GPS方法
double let=location.getLatitude(); //经度
double lng =location.getLongitude(); //纬度
位置监听
lm.requestLocationUpdates(provider,2000,10,locationListener);
第一个是方法,用GPS的话就是LocationManager.GPS_PROVIDER
第二个是位置变化时间间隔,2000就是2秒更新一次
第三个是单位,这里是10,就是距离条件是10时更新
第四个是回调函数,满足条件后开始回调.
我下面写了个超简单的位置追踪~~使用的是网络,需要GPS很精确,但是太慢了,搜寻了好久..
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LocationManager lm=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
String provider=LocationManager.NETWORK_PROVIDER;
Location location =lm.getLastKnownLocation(provider);
getLocationInfo(location);
lm.requestLocationUpdates(provider, 2000, 0, locationListener); //这个写了才更新哩
}
private void getLocationInfo(Location location) {
TextView tx_lat=(TextView)findViewById(R.id.Lat);
TextView tx_long=(TextView)findViewById(R.id.Long);
if(location != null){
double Lat=location.getLatitude();
double Long=location.getLongitude();
tx_lat.setText("纬度:"+Lat);
tx_long.setText("经度:"+Long);
}else {
tx_lat.setText("纬度:none");
tx_long.setText("经度:none");
}
}
private final LocationListener locationListener =new LocationListener(){
@Override
public void onLocationChanged(Location location) {
getLocationInfo(location);
}
@Override
public void onProviderDisabled(String provider) {
getLocationInfo(null);
}
@Override
public void onProviderEnabled(String provider) {
getLocationInfo(null);
}
@Override
public void onStatusChanged(String provider, int status, Bundle aextras) {
}
};
}
到此获取到的是经纬度,只是两个double的数据而已,至于怎么用看自己了.可以发短信追踪,可以用地图查具体位置..
地图的使用
1.获取key
现在google被封了,的确很多方面都很麻烦,所以我就用同样是平民化的百度地图了(这没办法嘛,毕竟自己又没有卫星)
同样,使用 地图 ,的确就是需要key ..........获取key的方法网上很多,我就不具体说了..
直接说百度地图怎么获取key吧.
申请一个百度地图的API key,申请地址http://lbsyun.baidu.com/apiconsole/key
点进去之前登陆一个百度账号,申请并登陆好了就就点进去,点创建应用,然后就需要填写以下东西了.
应用名称:这个要跟自己要加入地图的那个应用名一样,而且不能改.
应用类型: 填mobile
安全码:上面也说了,就是 数字签名;包名
一般程序没有数字签名是安装不了的,但是平常其实是ADT已经自动帮我们签了.
我这里的获取方法很简单,直接打开eclipse的 winows -> preferance -> android -> build.
see?
这就是俺的数字签名. 加上 ; com.example.ABCD ~~~这个包名,就能获取到key了.
2.导入百度地图API开发包
下载地址http://developer.baidu.com/map/sdkandev-download.htm,下载Android SDKv2.1.3 lib库就行了
下载之后解压.大概这样.
然后把他们复制黏贴到你的工程中的lib中.其中两个so文件放入armeabi问价夹中.如下.
图中还有的是定位文件,等下也要加,等下就不熬述了.
3.放入可视化的百度地图
首先要在layout文件中放入地图
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
在java中
//使用地图sdk前需先初始化BMapManager,这个必须在setContentView()先初始化
private BMapManager mBMapManaer;
mBMapManager = new BMapManager(this);
//第一个参数是API key,
//第二个参数是常用事件监听,用来处理通常的网络错误,授权验证错误等,你也可以不添加这个回调接口
mBMapManager.init("SYvbd4NrEhmsecaySEsFO6hH", new MKGeneralListenerImpl());
事件监听,一般要重载下面两个函数
public class MKGeneralListenerImpl implements MKGeneralListener{
/**
* 一些网络状态的错误处理回调函数
*/
@Override
public void onGetNetworkState(int iError) {
if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
showToast("您的网络出错啦!");
}
}
/**
* 授权错误的时候调用的回调函数
*/
@Override
public void onGetPermissionState(int iError) {
if (iError == MKEvent.ERROR_PERMISSION_DENIED) {
showToast("API KEY错误, 请检查!");
}
}
}
控制地图,放在setcontextView 之后的
//MapView 是地图主控件
private MapView mMapView = null;
// 用MapController完成地图控制
private MapController mMapController = null;
mMapView = (MapView) findViewById(R.id.bmapView); //获取地图实例
mMapController = mMapView.getController(); //获取地图控制器
mMapController.enableClick(true); //设置地图是否响应点击事件 .
mMapController.setZoom(12); //设置地图缩放级别
mMapView.setBuiltInZoomControls(true); //显示内置缩放控件
//mMapView.setTraffic(true); //设置交通信息图
mMapView.setSatellite(true); //设置卫星图
mMapController.setOverlooking(-45); //设置地图俯视角度 ,范围:0~ -45
//保存精度和纬度的类,
GeoPoint p = new GeoPoint((int)(23.047923 * 1E6), (int)(113.38255 * 1E6)); //我放在我的大学为初始中心了.
mMapController.setCenter(p); //设置p地方为中心点
以上初始化完毕,接着是设置移动等动作
mMapView.regMapViewListener(mBMapManager, new MKMapViewListener() {
/**
* 地图移动完成时会回调此接口 方法
*/
@Override
public void onMapMoveFinish() { }
/**
* 地图加载完毕回调此接口方法
*/
@Override
public void onMapLoadFinish() {
showToast("地图载入完毕!");
}
/**
* 地图完成带动画的操作(如: animationTo())后,此回调被触发
*/
@Override
public void onMapAnimationFinish() { }
/**
* 当调用过 mMapView.getCurrentMap()后,此回调会被触发
* 可在此保存截图至存储设备
*/
@Override
public void onGetCurrentMap(Bitmap arg0) {
}
/**
* 点击地图上被标记的点回调此方法
*
*/
@Override
public void onClickMapPoi(MapPoi arg0) {
if (arg0 != null){
showToast(arg0.strText);
}
}
});
4.地图定位
上面只是一个浏览地图,就是没有指标,什么的.加入一个指标,就需要用到图层,因为他是覆盖在地图上面的.
定位也是需要另外下载的,我这里用的是百度定位SDK4.2 http://developer.baidu.com/map/wiki/index.php?title=android-locsdk/guide/v4-2
具体下载和使用方法参考上面的网址 ,
同样也是下载后解压,把里面的东西放在工程的lib中,图还是上面例子那个图
加入权限
<!-- 这个权限用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!-- 这个权限用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></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.INTERNET" />
<!—SD卡读取权限,用户写入离线定位数据-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
<!--允许应用读取低级别的系统日志文件 -->
<uses-permission android:name="android.permission.READ_LOGS"></uses-permission>
在application标签中声明service组件,每个app拥有自己单独的定位service
使用SDK4.2需要在Mainfest.xml设置Accesskey,设置有误会引起定位和地理围栏服务不能正常使用,必须进行Accesskey的正确设置。
设置AccessKey,在application标签中加入,否则会报空指针.
//定位SDK的核心类
private LocationClient mLocClient;
//实例化定位服务,LocationClient类必须在主线程中声明
mLocClient = new LocationClient(getApplicationContext());
mLocClient.registerLocationListener(new BDLocationListenerImpl());//注册定位监听接口
LocationClientOption 该类用来设置定位SDK的定位方式
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true); //打开GPRS
option.setCoorType("bd09ll");//返回的定位结果是百度经纬度,默认值gcj02
option.setScanSpan(5000); //设置发起定位请求的间隔时间为5000ms
// option.setPoiNumber(5); //最多返回POI个数
// option.setPoiDistance(1000); //poi查询距离
// option.setPoiExtraInfo(true); //是否需要POI的电话和地址等详细信息
mLocClient.setLocOption(option); //设置定位参数
mLocClient.start(); // 调用此方法开始定位
mLocClient.requestLocation(); //定位到现在的位置
package com.example.LocateV;
import android.content.Context;
import android.graphics.Bitmap;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.map.LocationData;
import com.baidu.mapapi.map.MKEvent;
import com.baidu.mapapi.map.MKMapViewListener;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationOverlay;
import com.baidu.mapapi.map.PopupClickListener;
import com.baidu.mapapi.map.PopupOverlay;
import com.baidu.platform.comapi.basestruct.GeoPoint;
public class MainActivity extends ActionBarActivity {
private Toast mToast;
private BMapManager mBMapManager;
//MapView 是地图主控件
private MapView mMapView = null;
// 用MapController完成地图控制
private MapController mMapController = null;
// MKMapViewListener 用于处理地图事件回调
//定位SDK的核心类
private LocationClient mLocClient;
// 用户位置信息
private LocationData mLocData;
//我的位置图层
private LocationOverlay myLocationOverlay = null;
// 弹出窗口图层
private PopupOverlay mPopupOverlay = null;
// 弹出窗口图层的View
private View mPopupView;
private boolean isRequest = false;//是否手动触发请求定位
private boolean isFirstLoc = true;//是否首次定位
private BDLocation location;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//使用地图sdk前需先初始化BMapManager,这个必须在setContentView()先初始化
mBMapManager = new BMapManager(this);
//第一个参数是API key,
//第二个参数是常用事件监听,用来处理通常的网络错误,授权验证错误等,你也可以不添加这个回调接口
mBMapManager.init("SYvbd4NrEhmsecaySEsFO6hH", new MKGeneralListenerImpl());
setContentView(R.layout.activity_main);
//点击按钮手动请求定位
((Button) findViewById(R.id.request)).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
requestLocation();
}
});
LocationManager lm=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
String provider=LocationManager.NETWORK_PROVIDER;
Location location =lm.getLastKnownLocation(provider);
getLocationInfo(location);
lm.requestLocationUpdates(provider, 2000, 0, locationListener);
mMapView = (MapView) findViewById(R.id.bmapView); //获取地图实例
mMapController = mMapView.getController(); //获取地图控制器
mMapController.enableClick(true); //设置地图是否响应点击事件 .
mMapController.setZoom(12); //设置地图缩放级别
mMapView.setBuiltInZoomControls(true); //显示内置缩放控件
//mMapView.setTraffic(true); //设置交通信息图
mMapView.setSatellite(true); //设置卫星图
mMapController.setOverlooking(-45); //设置地图俯视角度 ,范围:0~ -45
mPopupView = LayoutInflater.from(this).inflate(R.layout.pop_layout, null);
//实例化弹出窗口图层
mPopupOverlay = new PopupOverlay(mMapView ,new PopupClickListener() {
//点击弹出窗口图层回调的方法
@Override
public void onClickedPopup(int arg0) {
mPopupOverlay.hidePop(); //隐藏弹出窗口图层
}
});
//实例化定位服务,LocationClient类必须在主线程中声明
mLocClient = new LocationClient(getApplicationContext());
mLocClient.registerLocationListener(new BDLocationListenerImpl());//注册定位监听接口
/**
* LocationClientOption 该类用来设置定位SDK的定位方式。
*/
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true); //打开GPRS
option.setCoorType("bd09ll");//返回的定位结果是百度经纬度,默认值gcj02
option.setScanSpan(5000); //设置发起定位请求的间隔时间为5000ms
// option.setPoiNumber(5); //最多返回POI个数
// option.setPoiDistance(1000); //poi查询距离
// option.setPoiExtraInfo(true); //是否需要POI的电话和地址等详细信息
mLocClient.setLocOption(option); //设置定位参数
mLocClient.start(); // 调用此方法开始定位
//定位图层初始化
myLocationOverlay = new LocationOverlay(mMapView);
//实例化定位数据,并设置在我的位置图层
mLocData = new LocationData();
myLocationOverlay.setData(mLocData);
//添加定位图层
mMapView.getOverlays().add(myLocationOverlay);
//修改定位数据后刷新图层生效
mMapView.refresh();
/**
* 保存精度和纬度的类,
*/
GeoPoint p = new GeoPoint((int)(23.047923 * 1E6), (int)(113.38255 * 1E6));
mMapController.setCenter(p); //设置p地方为中心点
mMapView.regMapViewListener(mBMapManager, new MKMapViewListener() {
/**
* 地图移动完成时会回调此接口 方法
*/
@Override
public void onMapMoveFinish() { }
/**
* 地图加载完毕回调此接口方法
*/
@Override
public void onMapLoadFinish() {
showToast("地图载入完毕!");
}
/**
* 地图完成带动画的操作(如: animationTo())后,此回调被触发
*/
@Override
public void onMapAnimationFinish() { }
/**
* 当调用过 mMapView.getCurrentMap()后,此回调会被触发
* 可在此保存截图至存储设备
*/
@Override
public void onGetCurrentMap(Bitmap arg0) {
}
/**
* 点击地图上被标记的点回调此方法
*
*/
@Override
public void onClickMapPoi(MapPoi arg0) {
if (arg0 != null){
showToast(arg0.strText);
}
}
});
}
public void requestLocation() {
isRequest = true;
if(mLocClient != null && mLocClient.isStarted()){
showToast("正在定位......");
mLocClient.requestLocation();
}
}
private void getLocationInfo(Location location) {
TextView tx_lat=(TextView)findViewById(R.id.Lat);
TextView tx_long=(TextView)findViewById(R.id.Long);
if(location != null){
double Lat=location.getLatitude();
double Long=location.getLongitude();
tx_lat.setText("纬度:"+Lat);
tx_long.setText("经度:"+Long);
}else {
tx_lat.setText("纬度:none");
tx_long.setText("经度:none");
}
}
private final LocationListener locationListener =new LocationListener(){
@Override
public void onLocationChanged(Location location) {
getLocationInfo(location);
}
@Override
public void onProviderDisabled(String provider) {
getLocationInfo(null);
}
@Override
public void onProviderEnabled(String provider) {
getLocationInfo(null);
}
@Override
public void onStatusChanged(String provider, int status, Bundle aextras) {
}
};
/**
* 显示弹出窗口图层PopupOverlay
* @param location
*/
private void showPopupOverlay(BDLocation location){
TextView popText = ((TextView)mPopupView.findViewById(R.id.location_tips));
popText.setText("[我的位置]\n" + location.getAddrStr());
mPopupOverlay.showPopup(getBitmapFromView(popText),
new GeoPoint((int)(location.getLatitude()*1e6), (int)(location.getLongitude()*1e6)),
15);
}
private void showToast(String msg){
if(mToast == null){
mToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
}else{
mToast.setText(msg);
mToast.setDuration(Toast.LENGTH_SHORT);
}
mToast.show();
}
/**
* 将View转换成Bitmap的方法
* @param view
* @return
*/
public static Bitmap getBitmapFromView(View view) {
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
return bitmap;
}
//继承MyLocationOverlay重写dispatchTap方法
private class LocationOverlay extends MyLocationOverlay{
public LocationOverlay(MapView arg0) {
super(arg0);
}
/**
* 在“我的位置”坐标上处理点击事件。
*/
@Override
protected boolean dispatchTap() {
//点击我的位置显示PopupOverlay
showPopupOverlay(location);
return super.dispatchTap();
}
}
/**
* 定位接口,需要实现两个方法
*/
public class BDLocationListenerImpl implements BDLocationListener {
/**
* 接收异步返回的定位结果,参数是BDLocation类型参数
*/
@Override
public void onReceiveLocation(BDLocation location) {
if (location == null) {
return;
}
StringBuffer sb = new StringBuffer(256);
sb.append("time : ");
sb.append(location.getTime());
sb.append("\nerror code : ");
sb.append(location.getLocType());
sb.append("\nlatitude : ");
sb.append(location.getLatitude());
sb.append("\nlontitude : ");
sb.append(location.getLongitude());
sb.append("\nradius : ");
sb.append(location.getRadius());
if (location.getLocType() == BDLocation.TypeGpsLocation){
sb.append("\nspeed : ");
sb.append(location.getSpeed());
sb.append("\nsatellite : ");
sb.append(location.getSatelliteNumber());
} else if (location.getLocType() == BDLocation.TypeNetWorkLocation){
sb.append("\naddr : ");
sb.append(location.getAddrStr());
}
MainActivity.this.location = location;
mLocData.latitude = location.getLatitude();
mLocData.longitude = location.getLongitude();
//如果不显示定位精度圈,将accuracy赋值为0即可
mLocData.accuracy = location.getRadius();
mLocData.direction = location.getDirection();
//将定位数据设置到定位图层里
myLocationOverlay.setData(mLocData);
//更新图层数据执行刷新后生效
mMapView.refresh();
if(isFirstLoc || isRequest){
//将给定的位置点以动画形式移动至地图中心
mMapController.animateTo(new GeoPoint(
(int) (location.getLatitude() * 1e6), (int) (location
.getLongitude() * 1e6)));
showPopupOverlay(location);
isRequest = false;
}
isFirstLoc = false;
}
/**
* 接收异步返回的POI查询结果,参数是BDLocation类型参数
*/
}
/**
* 常用事件监听,用来处理通常的网络错误,授权验证错误等
*/
public class MKGeneralListenerImpl implements MKGeneralListener{
/**
* 一些网络状态的错误处理回调函数
*/
@Override
public void onGetNetworkState(int iError) {
if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
showToast("您的网络出错啦!");
}
}
/**
* 授权错误的时候调用的回调函数
*/
@Override
public void onGetPermissionState(int iError) {
if (iError == MKEvent.ERROR_PERMISSION_DENIED) {
showToast("API KEY错误, 请检查!");
}
}
}
@Override
protected void onResume() {
//MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()
mMapView.onResume();
super.onResume();
}
@Override
protected void onPause() {
//MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()
mMapView.onPause();
super.onPause();
}
@Override
protected void onDestroy() {
//MapView的生命周期与Activity同步,当activity销毁时需调用MapView.destroy()
mMapView.destroy();
//退出应用调用BMapManager的destroy()方法
if(mBMapManager != null){
mBMapManager.destroy();
mBMapManager = null;
}
//退出时销毁定位
if (mLocClient != null){
mLocClient.stop();
}
super.onDestroy();
}
}
写得有点急...吃饭先.
参考地址:http://blog.csdn.net/xiaanming/article/details/11171581