注:本文中代码使用的是c#语言,是在visual studio2012+xamarin下实现的,给自己做的备份。
实现步骤:
- a. 开启手机定位相关设置并设定位参数
- b. 获取当前bestprovider,尝试通过getLastKnownLocation获取上次定位信息并显示
- c. 开启监听线程,监听位置提供者是否变化
- d. 如有变化,关闭当前监听,获取新的bestprovider获取上次定位信息并显示,之后设置新的监听
1 . 首先创建一个Acyivity,class Activity_Location 继承Activity,实现 ILocationListener接口,该activity中声明如下变量:
//用于显示定位等待进度的提示对话框
private ProgressDialog dialog;
//用于显示定位结果信息的文本框
private TextView locationtxt = null;
//定位管理器
private LocationManager locationManager;
//当前定位提供者,例如 GPS_PROVIDER 为 GPS 定位技术,NETWORK_PROVIDER 为网络定位技术
private string currentProvider;
//当前最好的定位提供者
private string bestProvider;
//当前位置
private Location currentLocation;
//Criteria对象,用于设置定位参数
private Criteria criteria;
2 . oncreate方法,定位参数设置
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.layout_location);//加载定位页面
locationtxt = FindViewById<TextView>(Resource.Id.textView1);
locationManager = (LocationManager)GetSystemService(Context.LocationService);//获取到LocationManager对象
if (!locationManager.IsProviderEnabled(LocationManager.NetworkProvider))
{
Toast.MakeText(this, "请开启GPS功能!", ToastLength.Long).Show();
Intent intent = new Intent(Settings.ActionLocationSourceSettings);
StartActivity(intent);
}
try
{
criteria = new Criteria();//创建一个Criteria对象
criteria.Accuracy = Accuracy.Fine;//设置粗略精确度
criteria.AltitudeRequired = false;//设置是否需要返回海拔信息
criteria.BearingRequired = false;//设置是否需要返回方位信息
criteria.CostAllowed = true;//设置是否允许付费服务
criteria.PowerRequirement = Power.Low;//设置电量消耗等级
criteria.SpeedRequired = false;//设置是否需要返回速度信息
}
catch (IllegalArgumentException e)
{
throw;
}
}
3 . onresume方法,包括定位进度对话框显示,初次定位以及开启线程用于循环获取当前最佳位置提供者,如有变化,关闭当前循环线程,更换当前定位提供者重新定位并开启新的循环线程
/// <summary>
/// activity可见,开启循环监听
/// </summary>
protected override void OnResume()
{
bestProvider = locationManager.GetBestProvider(criteria, true);//根据设置的Criteria对象,获取最符合此标准的provider对象
currentProvider = bestProvider;
// 等待提示
dialog = new ProgressDialog(this);
dialog.SetMessage("正在定位...");
dialog.SetCancelable(true);
dialog.Show();
currentLocation = locationManager.GetLastKnownLocation(currentProvider);//根据当前provider对象获取最后一次位置信息
showLocation(currentLocation);//显示位置信息
locationManager.RequestLocationUpdates(currentProvider, 0, 0, this);//设置监听器,每三秒主动检查一次provider变化
System.Timers.Timer t = new System.Timers.Timer(3000);//实例化Timer类,设置间隔时间为3000毫秒;
t.Elapsed += new System.Timers.ElapsedEventHandler(theout);//到达时间的时候执行事件;
t.AutoReset = true;//设置是执行一次(false)还是一直执行(true);
t.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件;
base.OnResume();
}
4 . 循环线程的实现,检测当前位置提供者是否最佳满足定位要求
/// <summary>
/// 检测当前位置提供者是否最佳满足定位要求并获取最新位置信息
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
public void theout(object source, System.Timers.ElapsedEventArgs e)
{
bestProvider = locationManager.GetBestProvider(criteria, true);//根据设置的Criteria对象,获取最符合此标准的provider对象
if (!currentProvider.Equals(bestProvider))
{
locationManager.RemoveUpdates(this);//关闭当前循环线程
currentProvider = bestProvider;
currentLocation = locationManager.GetLastKnownLocation(currentProvider);//根据当前provider对象获取最后一次位置信息
showLocation(currentLocation);
locationManager.RequestLocationUpdates(currentProvider, 0, 0, this);//重新设置循环监听器
}
}
5 . 用于显示位置信息的方法
/// </summary>
/// 显示位置信息
/// </summary>
/// <param name="networklocation"></param>
/// <param name="gpslocation"></param>
public void showLocation(Location currentLocation)
{
if (currentLocation != null)
{
dialog.Dismiss();
double lat = currentLocation.Latitude;
double lng = currentLocation.Longitude;
float spe = currentLocation.Speed;//速度
float acc = currentLocation.Accuracy;//精度
double alt = currentLocation.Altitude;//海拔
float bea = currentLocation.Bearing;//承轴
long time = currentLocation.Time;//19700101010101
string loc = "位置提供者:" + currentLocation.Provider + "\r\n纬度:" + lat + "\r\n经度:" + lng + "\r\n精度:" + acc + "\r\n时间:" + time;
locationtxt.SetText("\r\n您当前的位置:\r\n\r\n" + loc, null);
}
else
{
locationtxt.SetText("无法获取位置信息", null);
}
}
6 . 其他回调方法
/// <summary>
/// 位置发生改变时调用
/// </summary>
/// <param name="location"></param>
public void OnLocationChanged(Location location)
{
showLocation(location);
}
/// <summary>
/// provider失效时调用
/// </summary>
/// <param name="provider"></param>
public void OnProviderDisabled(string provider)
{
showLocation(null);
}
/// <summary>
/// provider启用时调用
/// </summary>
/// <param name="provider"></param>
public void OnProviderEnabled(string provider)
{
Location location = locationManager.GetLastKnownLocation(provider);
showLocation(location);
}
/// <summary>
/// 状态改变时调用
/// </summary>
/// <param name="provider"></param>
/// <param name="status"></param>
/// <param name="extras"></param>
public void OnStatusChanged(string provider, Availability status, Bundle extras)
{
//状态改变
}
7 . OnPause方法,关闭循环监听线程
/// <summary>
/// activity不可见,关闭监听
/// </summary>
protected override void OnPause()
{
locationManager.RemoveUpdates(this);
base.OnPause();
}
8 . 最后,注意在清单文件添加相关权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
9 . 定位结果
第一图是本人定位结果(主要是他真的会不断更新定位结果哦),第二个图是利用百度地图定位结果,对比哈经纬度,还算可以
一图
二图