Android定位的实现

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u010127332/article/details/52222720

注:本文中代码使用的是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 . 定位结果
第一图是本人定位结果(主要是他真的会不断更新定位结果哦),第二个图是利用百度地图定位结果,对比哈经纬度,还算可以
一图
这里写图片描述
二图
这里写图片描述

展开阅读全文

没有更多推荐了,返回首页