Pro Android学习笔记(一一六):Location(2):LocationManager的位置获取

文章转载只能用于非商业性质,且不能带有虚拟货币、积分、注册等附加条件。转载须注明出处http://blog.csdn.net/flowingflying以及作者@恺风Wei。

LocationManager提供两个主要功能:1、获取设备的地理位置(经纬度);2、当设备进入制定的地理位置,通过通过intent通知。

获取位置信息的基本方法

简单的代码片段如下:

private void getMyLocation(){
   //1、获取LocationManager,LocationManager是系统级别的服务
   LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 
    //2、获取有效的provider,并显示出来
    List providerlist = manager.getAllProviders();       
    showProvider(providerlist); 
    
     //3、在LocationManger获取某个provider的位置信息        
    /* 获取位置更新使用getLastKnownLocation(),参数为provider的名字,系统提供预定义的有LocationManager.GPS_PROVIDER、LocationManager.NETWORK_PROVIDER以及PASSIVE_PROVIDER。如果未能获取任何信息,getLastKnownLocation(provider)将返回null。Location可以获取provider的名字,经纬度,高度,速度,方位(bearing),精确度等等,用getXXX()获取,对于非常规数据在获取之前可以通过hasXXX()来判断有否该信息 */
    Location locate = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    showInfo("loc = " + loc);    
}

private void showProvider(List list){
    showInfo("show providers : ");
    for(int i = 0 ; i < list.size(); i ++){ 
        showInfo("(" +i +")" + list.get(i));
    }
}

private void showInfo(String info){
    Log.i("WEI",info);
}

此外,我们必须在AndroidManifest.xml授予相应的权限。相关权限有两个: 1、android.permission.ACCESS_FINE_LOCATION;2、android.permission.ACCESS_COARSE_LOCATION。其中fine(精确)已经涵盖了coarse(粗糙),如果我们定义了fine,就不需要在授予coarse。GPS和Passive需要fine,而network可以使用coarse。

下面是查看provider的结果:

Pro Android学习笔记(一一六):Location(2):LocationManager的位置获取_第1张图片

network即通过基站或者wifi的方式获取位置信息,GPS不用解释。Passive,即被动方式,是位置更新监测器,当其他App获取地理位置时,向你的App进行位置更新,而你的APP并不需要请求位置更新。至于hybrid是混合方式,不是Android系统的标准方式。而在模拟器中缺省提供gps和passive这两种方式。

模拟器上的位置模拟

在模拟器,我们可以通过DDMS的Emulator control来设定位置信息。

Pro Android学习笔记(一一六):Location(2):LocationManager的位置获取_第2张图片

此外我们还可以通过telnet到模拟器,通过命令上进行设置,下面是通过SecureCRT telnet到值模拟器(telnet localhost 5554),相关命令为geo fix 或者geo fix

Pro Android学习笔记(一一六):Location(2):LocationManager的位置获取_第3张图片

获取provider

getAllProviders()获得的提供商列表,而getProvider(LocationManager.GPS_PROVIDER)则可以获取指定供应商的名称。但是这两种获取方式,获得包括目前无法访问的,也就是最终返回的Location为null。

我们可以通过getProviders(true),只返回有效的供应商列表,或者用isProviderEnabled(String providerName)来看看供应商是否有效。但是这同样亦有问题,如果我们关闭手机的GPS,返回的列表中没有gps,或者查询到无效,当时当我们开启手机的GPS时,有可能并没有搜索到卫星,这是gps仍出现在有效的供应商列表,或者查询是enabled的,但location仍会返回null。

我们希望能获得最适合我们需求的供应商,相关代码如下:

private void getMyLocation1(){
    LocationManager manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    //设置我们的标准Criteria,可以用setXXX(),例如criteria.setAccuracy(int);提出我具体的要求,例如精度要求等,如果没有什么特别的要求,也就无需进行设置
    Criteria criteria = new Criteria();
    //通过getBestProvider获得满足要求的最佳供应商,也可以通过getProviders(criteria, true)获取符合要求的供应商列表。在没有搜索到足够卫星时,系统会返回其他方式,如network。 
    String providerName = manager.getBestProvider(criteria, true/*true表示enabledOnly*/);
    showInfo("Best provider is " + providerName);
   
    if(providerName != null){
        Location locate = manager.getLastKnownLocation(providerName);
        showLocation(locate);
    }
}

进行相关设置

设备可能没有开启GPS,获取关闭了所有的地理信息获取方法,如果检查到没有开启地理服务,弹出系统设置给用户,由用户进行设置,在设置结束后,再次进行位置获取。相关代码如下:

private LocationManager manager = null;
private void getMyLocation2(){
    if(manager == null)
        manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

    boolean isGpsAvalible = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    if(!isGpsAvalible){ //打开location设置的activity
       startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 0);

    }else{
        getFromGps();
    }
}   

@Override //当用户设置后按返回键,触发onActivityResult
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 
    super.onActivityResult(requestCode, resultCode, data);
    getFromGps();
}

private void getFromGps(){
    //用户不一定会在系统设置中开启,故需要再次检测!
    boolean isGpsAvalible = manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    if(isGpsAvalible){
        Location location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        showLocation(location);
    }
}

Pro Android学习笔记(一一六):Location(2):LocationManager的位置获取_第4张图片

Location信息

我们可以用hasXXX()来获得是否供应商提供了某个位置信息,用getXXX()来获取具体的位置信息,下面是例子。如果提供商是GSP,卫星的数目放在extra中。

Log.d("WEI","longtitude = " + loc.getLongitude());
Log.d("WEI","lantitude = " + loc.getLatitude());

boolean isAvalible = loc.hasAccuracy();
Log.d("WEI","hasAccuracy = " + loc.hasAccuracy());
if(isAvalible)
Log.d("WEI","accuracy = " + loc.getAccuracy());

Bundle b = loc.getExtras();

if(b!= null){
      Log.d("WEI","satellites num = " + b.getInt("satellites"));
}

Location类提供两个地点之间的距离计算,distanceTo()和静态方法distanceBetween()。这里给出的是最短的地理距离,而非两者间的交通距离(例如驾车距离),如果要获得最短的驾车线路和距离,需要地图供应商,例如Google Map。

 【注意】虽然,GPS在实际应用中更为常用,但在室内进行开发调测中,使用network更为稳定,因此如果是用实体机调测,建议采用network方式。对于模拟器,最好使用具有Google APIs的版本,以确保DDMS中位置模拟的正常使用。

小例子代码在:Pro Android学习:location小例子

相关链接:我的Android开发相关文章

你可能感兴趣的:(Android)