Android学习笔记(五六) 位置Location

               

建议更新20130522的ADT版本,无论是Linux下还是Windows下,我觉得速度快了很多。而且将Android SDK Tool升级到ver 22版本后,原来的ADT有很多不明原因问题,加载App到模拟器上出现连接不上的情况。

允许应用具备定位功能

Location是手机功能的一大特色,卫星导航除了GPS外,还有欧洲的伽利略和我国的北斗,此外还有运营商移动基站的三角定位、第三方提供WiFi热点定位等方式。相关推荐可以阅读CDMA的定位方式。利用基站信号的强弱进行三角特定的方式(在市区内受到建筑阻挡和反射等影响),利用上网的AP所出的地理位置来进行定位,都属于粗定位coarse location,利用卫星的精确定位为fine location。应用要具备定位功能,首先必须进行权限许可。

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

在模拟器中设定位置

我们可以通过DDMS在模拟器中设定经纬度,并在程序运行是修改经纬度。Window -> Open perspective -> DDMS

连续位置获取小例子

下面的例子很简单,UI是一个TextView用来显示信息。我们进行设备位置的不断跟踪,也就是跟踪我们的路径。

public class LocationBase extends Activity{
    private TextView myText;
    private String textStr = "";
    private LocationManager mgr=null;     
     
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pure_text_view);
        myText = (TextView) findViewById(R.id.pure_text);
        addText("Location Based-Services Demo...");
       
       //步骤 1: 获取系统的定位管理器
        mgr = (LocationManager)getSystemService(LOCATION_SERVICE);

        addText("get system Location Manager " + mgr);
    }
            
    //步骤2.2 持续跟踪中的停止update:在本例中,我们要求不断获得位置更新,我们必须在人工进行removeUpdates(),否则即使应用中所有的Activity都关闭,App仍继续在不断更新位置信息,导致应用资源无法被回收
    protected void onPause() { 
        super.onPause();
        mgr.removeUpdates(onLocationChange);
        addText("Remove Updates...");
    }  
   //步骤2:设置持续跟踪
   //步骤 2.1(1) :我们在onResume()中持续跟踪,相应的在onPause()中关闭出现跟踪。我们只在Activity运行时进行跟踪。具体见Activity的生命周期
    protected void onResume() {
        super.onResume();  
       //步骤2.1 (2):由于人的位置是不断变化,我要设置一个位置变化的范围,包括同时满足最小的时间间隔和最小的位移变化,如果两个条件要同时满足,将位置监听器将被触发。实际上该方法有多个参数格式,特别是requestLocationUpdates (long minTime, float minDistance, Criteria criteria,PendingIntent intent),当位置变化时可调用其他的Activity。 在本例中,我们制定用GPS,则在权限中必须要求精确定位许可。
        mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000/*10秒,为测试方便*/, 1000/*1公里*/, onLocationChange/*位置监听器*/);
        addText("Request Updates automatically ...");
    }

    //步骤3:位置监听器LocationListener 的设置,当位置发生变化是触发onLocationChanged( )
    LocationListener onLocationChange = new LocationListener(){

        public void onLocationChanged(Location location) { 
            addText("Location Changed : (" + location.getLongitude()+","+location.getLatitude()+")");
        } 
        public void onProviderDisabled(String arg0) { 
            addText("onProviderDisabled");
        } 
        public void onProviderEnabled(String arg0) { 
            addText("onProviderEnabled");
        } 
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) { 
            addText("onStatusChanged");
        }         
    };

    private void addText(String s){
        textStr = textStr.concat(s + "\n\n");
        myText.setText(textStr);
    }
}

我们可能会发现一开始并没有出发到位置监控器的onLocationChanged(),在实际中,可能由于GPS没有打开,或者刚打开,不能马上得到位置信息。在模拟器中,我们在DDMS中将按“send”按钮即可。更改位置信息,同样需按“send”。

关于定位的选定

在例子中,我们指定了采用GPS,实际上位置获取可以通过卫星,运营商,以及第三方服务获取,即有多个信息来源。我们可以想系统查询可用的位置信息源,如下:

List<String> list = mgr.getAllProviders(); //mgr即LocationManager
for(Iterator<String> i = list.iterator();i.hasNext();){
   System.out.println("\t" + i.next()); 
}

我们可以重中进行选择,或者让用户选择,但是更好的方式是让系统帮忙选择。如下:

Criteria criteria = new Criteria();
String providerName = mgr.getBestProvider(criteria, true /*enabledOnly*/); //criteria不能填null,否则出现异常
LocationProvider provider = mgr.getProvider(providerName);

我们可以在criteria中加入一些条件,例如一些精度setAccuracy(),和一些位置信息setAltitudeRequired( ),是否收费setCostAllowed( )等。不是随有的条件都必须满足,将为你匹配最好的一个,当然如果你设置了免费,不会选择收费给你的。我们根据provider的名字获得LocationProvider的对象,但一般不需要,我们知道provider的名字,就可以向系统请求位置信息。

Location location = mgr.getLastKnownLocation(providerName);
if(location != null)
    System.out.println("Get Location from " + providerName + " : " + location.getLatitude()+ "," + location.getLongitude());

Android采用getLastKnownLocation( )来查询,而不是当前的实时信息。有可能由于某种情况无法获取,例如GPS没有打开,或正在启动过程中,有可能返回null。返回的信息可能不仅有经纬度,是否有具有海拔信息,用location.hasAltitude()询问,是否具有速度信息,用hasSpeed()询问。

到达某个位置的提醒触发

当用户位置到达某个目标附近 ,触发提醒,这可以用在很多使用场景,LocationManager中可以通过addProximityAlert(),当在某位置附近可以调起pendingIntent。

public void addProximityAlert (double latitude /*维度*/,
                                               double longitude/*精度*/,
                                               float radius/*半径范围*/,
                                               long expiration/*失效,-1表示没有失效,可以用removeProximityAlert()来进行人工删除*/,
                                               PendingIntent intent /*触发处理*/)

对比两个location数据

对于前后获取的location(可能来自不同的provider,也可能获取位置信息的条件发生变化,例如寻找多一颗卫星或少了一颗卫星,导致前后的精度有明显差异),我们可以判断哪个location更好地代表当前的地点。我们可以用location.getTime()来获得定位信息的更新时间,用location.getAccruacy()来获取精度,用location.getProvider()反过来获取providerName,用于进行提供者的比对。通过这些比较我们可以选取我们仍未最好的数据。在Android的开发者网站中给出 了选择哪个location的例子。

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

 
 
           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值