Android那些事儿之LBS定位,实践测试lbs |
您所在的位置:网站首页 › lbs怎么使用 › Android那些事儿之LBS定位,实践测试lbs |
翻了翻Android Developer找到一个不错的东西LocationManager。LocationManager是通过listener的方式来告知调用者,而原来写好的模块是直接return的,于是得稍微改造一下: 首先定义一个Model: public class LocationData { String lat; String lon; String address; }
然后LBS的所有功能都封装到一个工具类里面: 首先在构造函数里面获取系统服务中的LocationManager: public class LBSTool { private Context mContext; private LocationManager mLocationManager; private LocationData mLocation; private LBSThread mLBSThread; private MyLocationListner mNetworkListner; private MyLocationListner mGPSListener; private Looper mLooper; public LBSTool(Context context) { mContext = context; //获取Location manager mLocationManager = (LocationManager)mContext.getSystemService(Context.LOCATION_SERVICE); } ...... }
然后是入口方法,这里会启动一个子线程去获取地理位置信息,并让主线程进入等待,时长通过timeout设置 /** * 开始定位 * @param timeout 超时设置 * @return LocationData位置数据,如果超时则为null */ public LocationData getLocation(long timeout) { mLocation = null; mLBSThread = new LBSThread(); mLBSThread.start();//启动LBSThread timeout = timeout > 0 ? timeout : 0; synchronized (mLBSThread) { try { Log.i(Thread.currentThread().getName(), "Waiting for LocationThread to complete..."); mLBSThread.wait(timeout);//主线程进入等待,等待时长timeout ms Log.i(Thread.currentThread().getName(), "Completed.Now back to main thread"); } catch (InterruptedException e) { e.printStackTrace(); } } mLBSThread = null; return mLocation; }子线程通过调用registerLocationListener开启位置服务的监听,并且讲监听器分配给指定looper private class LBSThread extends Thread { @Override public void run() { setName("location thread"); Log.i(Thread.currentThread().getName(), "--start--"); Looper.prepare();//给LBSThread加上Looper mLooper = Looper.myLooper(); registerLocationListener(); Looper.loop(); Log.e(Thread.currentThread().getName(), "--end--"); } } private void registerLocationListener () { Log.i(Thread.currentThread().getName(), "registerLocationListener"); if (isGPSEnabled()) { mGPSListener=new MyLocationListner(); //五个参数分别为位置服务的提供者,最短通知时间间隔,最小位置变化,listener,listener所在消息队列的looper mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, mGPSListener, mLooper); } if (isNetworkEnabled()) { mNetworkListner=new MyLocationListner(); mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3000, 0, mNetworkListner, mLooper); } }isGPSEnabled和isNetworkEnabled分别为判断当前手机是否开启了GPS以及网络的状况(包含了是否开启wifi和移动网络),以决定使用哪一种服务提供者:GPS_PROVIDER或者NETWORK_PROVIDER。 /** * 判断GPS是否开启 * @return */ public boolean isGPSEnabled() { if(mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { Log.i(Thread.currentThread().getName(), "isGPSEnabled"); return true; } else { return false; } } /** * 判断Network是否开启(包括移动网络和wifi) * @return */ public boolean isNetworkEnabled() { return (isWIFIEnabled() || isTelephonyEnabled()); } /** * 判断移动网络是否开启 * @return */ public boolean isTelephonyEnabled() { boolean enable = false; TelephonyManager telephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); if (telephonyManager != null) { if (telephonyManager.getNetworkType() != TelephonyManager.NETWORK_TYPE_UNKNOWN) { enable = true; Log.i(Thread.currentThread().getName(), "isTelephonyEnabled"); } } return enable; } /** * 判断wifi是否开启 */ public boolean isWIFIEnabled() { boolean enable = false; WifiManager wifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); if(wifiManager.isWifiEnabled()) { enable = true; Log.i(Thread.currentThread().getName(), "isWIFIEnabled"); } return enable; }当LocationManager在大于最短时间且检测到最小位置变化时,就会通知给监听器,然后我们就可以通过返回的经纬度信息去google服务器查找对应的地址,然后停止LocationManger的工作,解除LBSThread中的Looper,让LBSThread结束,最后通知主线程可以继续,整个流程结束。 private class MyLocationListner implements LocationListener{ @Override public void onLocationChanged(Location location) { // 当LocationManager检测到最小位置变化时,就会回调到这里 Log.i(Thread.currentThread().getName(), "Got New Location of provider:"+location.getProvider()); unRegisterLocationListener();//停止LocationManager的工作 try { synchronized (mLBSThread) { parseLatLon(location.getLatitude()+"", location.getLongitude()+"");//解析地理位置 mLooper.quit();//解除LBSThread的Looper,LBSThread结束 mLBSThread.notify();//通知主线程继续 } } catch (Exception e) { e.printStackTrace(); } } //后3个方法此处不做处理 @Override public void onStatusChanged(String provider, int status, Bundle extras) {} @Override public void onProviderEnabled(String provider) {} @Override public void onProviderDisabled(String provider) {} }; /** * 使用经纬度从goole服务器获取对应地址 * @param 经纬度 */ private void parseLatLon(String lat, String lon) throws Exception { Log.e(Thread.currentThread().getName(), "---parseLatLon---"); Log.e(Thread.currentThread().getName(), "---"+lat+"---"); try { HttpClient httpClient = new DefaultHttpClient(); HttpGet get = new HttpGet("http://ditu.google.cn/maps/geo?output=json&q="+lat+","+lon); HttpResponse response = httpClient.execute(get); String resultString = EntityUtils.toString(response.getEntity()); JSONObject jsonresult = new JSONObject(resultString); if(jsonresult.optJSONArray("Placemark") != null) { mLocation = new LocationData(); mLocation.lat = lat; mLocation.lon = lon; mLocation.address = jsonresult.optJSONArray("Placemark").optJSONObject(0).optString("address"); } } catch (Exception e) { e.printStackTrace(); } } /** * 注销监听器 */ private void unRegisterLocationListener () { if(mGPSListener!=null){ mLocationManager.removeUpdates(mGPSListener); mGPSListener=null; } if(mNetworkListner!=null){ mLocationManager.removeUpdates(mNetworkListner); mNetworkListner=null; } }
接下来可以在界面上安放个button: locationBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //return mode LBSTool lbs = new LBSTool(LBStestActivity.this); LocationData location = lbs.getLocation(120000); if (location != null) { Log.i("---lat---",location.lat); Log.i("---lon---",location.lon); Log.i("---address---",location.address); Toast.makeText(LBStestActivity.this, location.lat + " " + location.lon + " " + location.address, Toast.LENGTH_LONG).show(); } } });最后别忘了加入权限:
此外,LocationManager还有些高级的用法,比如设置一些关键参数,以及获取最后一次定位信息等等: Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); // 高精度 criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(true); criteria.setPowerRequirement(Criteria.POWER_LOW); // 低功耗 String bestprovider = locationManager.getBestProvider(criteria, true); // 获取GPS信息 Location location = locationManager.getLastKnownLocation(bestprovider); // 通过GPS获取位置 Log.e("--bestprovider--", bestprovider); Log.e("--bestprovider--", location.getLatitude()+"");
本文出自 “Android那些事儿” 博客,请务必保留此出处http://winwyf.blog.51cto.com/4561999/875617
问题: google api 过时了,google中国退出后, 这种方式:"HttpGet get = new HttpGet("http://ditu.google.cn/maps/geo?output=json&q="+lat+","+lon); "取不到地址信息了。
解决方法: http://maps.google.com/maps/api/geocode/json?latlng=" + lat + "," + lon + "&language=zh-CN&sensor=false
效果:
源码: 这是源码。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |