之前看过Location的app及framework代码,下面贴个简单的定位程序,以供大家交流,使用百度地图SDK开发的,引用了百度地图的so库文件。
效果图如下:
package com.baidumap.location; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; import com.baidu.R; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; public class BaiduMapActivity extends Activity { private static final String TAG = "BaiduMapActivity"; public static final String KEY_LATITUDE = "Latitude"; public static final String KEY_LONGITUDE = "Longitude"; private static final int MSG_REQUEST_LOCATION = 1; private static final int MSG_TIME_DELAYED = 2000; private LocationClient mLocClient = null; private TextView mLocInfo; private Button mLocBtn; private ProgressBar mProgressView = null; private double mLatitude; private double mLongitude; private MyLocationListenner mLocListener = new MyLocationListenner(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mLocBtn = (Button)findViewById(R.id.location_btn); mLocInfo = (TextView)findViewById(R.id.location_info); mProgressView = (ProgressBar) findViewById(R.id.progress_bar); mProgressView.setVisibility(View.VISIBLE); mProgressView.setIndeterminate(true); mLocClient = new LocationClient(this); mLocClient.registerLocationListener(mLocListener); mLocClient.start(); // send message to update location sendMsgUpdateLocation(); mLocBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // click the button and show the webview activity. requestCurrentLocation(); Log.d(TAG, "onClick: mLatitude = " + mLatitude + " " + "mLongitude = " + mLongitude); Bundle bundle = new Bundle(); bundle.putDouble(KEY_LATITUDE, mLatitude); bundle.putDouble(KEY_LONGITUDE, mLongitude); Intent intent = new Intent(BaiduMapActivity.this, WebViewActivity.class); intent.putExtras(bundle); startActivity(intent); } }); } public Handler mMsgHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); Log.d(TAG, "handleMessage: msg.what = " + msg.what); switch(msg.what) { case MSG_REQUEST_LOCATION: requestCurrentLocation(); break; default: break; } } }; public void sendMsgUpdateLocation() { Message msg = mMsgHandler.obtainMessage(MSG_REQUEST_LOCATION); mMsgHandler.sendMessageDelayed(msg, MSG_TIME_DELAYED); } public void requestCurrentLocation() { Log.d(TAG, "requestCurrentLocation()"); try { if (mLocClient != null && mLocClient.isStarted()) { Log.d(TAG, "requestCurrentLocation()->requestLocation()"); setLocationOption(); mLocClient.requestLocation(); } } catch(Exception err) { Log.d(TAG, "error = " + err); } } /** * show the TextView */ public void showAddressInfo(String location) { try { if (mLocInfo != null) { mLocInfo.setText(location); } } catch (Exception e) { e.printStackTrace(); } } /** * Location Listener */ public class MyLocationListenner implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { Log.d(TAG, "MyLocationListenner: onReceiveLocation"); if (location == null) { return; } String address = location.getAddrStr(); Log.d(TAG, "MyLocationListenner: onReceiveLocation, address = " + address); if(address == null) { mLocClient.requestLocation(); } mLatitude = location.getLatitude(); mLongitude = location.getLongitude(); String newLine = "\n"; StringBuffer sb = new StringBuffer(256); sb.append(getString(R.string.time)); sb.append(location.getTime()); sb.append(newLine + getString(R.string.error_code)); sb.append(location.getLocType()); sb.append(newLine + getString(R.string.Longitude)); sb.append(location.getLongitude()); sb.append(newLine + getString(R.string.Latitude)); sb.append(location.getLatitude()); sb.append(newLine + getString(R.string.radius)); sb.append(location.getRadius()); Log.d(TAG, "MyLocationListenner: onReceiveLocation, getLocType = " + location.getLocType()); if (location.getLocType() == BDLocation.TypeGpsLocation) { sb.append(newLine + getString(R.string.speed)); sb.append(location.getSpeed()); sb.append(newLine + getString(R.string.satellite)); sb.append(location.getSatelliteNumber()); } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) { sb.append(newLine + getString(R.string.address)); sb.append(location.getAddrStr()); } sb.append(newLine + getString(R.string.version)); sb.append(mLocClient.getVersion()); sb.append(newLine + getString(R.string.flag)); sb.append(location.isCellChangeFlag()); // show the details showAddressInfo(sb.toString()); // address is null, send message to update the textview if(address == null) { sendMsgUpdateLocation(); } else { mProgressView.setIndeterminate(false); mProgressView.setVisibility(View.GONE); } } public void onReceivePoi(BDLocation poiLocation) { if (poiLocation == null){ return ; } String newLine = "\n"; StringBuffer sb = new StringBuffer(256); sb.append(getString(R.string.position_time)); sb.append(poiLocation.getTime()); sb.append(newLine + getString(R.string.error_code)); sb.append(poiLocation.getLocType()); sb.append(newLine + getString(R.string.Latitude)); sb.append(poiLocation.getLatitude()); sb.append(newLine + getString(R.string.Longitude)); sb.append(poiLocation.getLongitude()); sb.append(newLine + getString(R.string.radius)); sb.append(poiLocation.getRadius()); if (poiLocation.getLocType() == BDLocation.TypeNetWorkLocation) { sb.append(newLine + getString(R.string.address)); sb.append(poiLocation.getAddrStr()); } if(poiLocation.hasPoi()) { sb.append(newLine + getString(R.string.position)); sb.append(poiLocation.getPoi()); } else { sb.append(newLine + getString(R.string.no_position_info)); } } } private void setLocationOption() { Log.d(TAG, "setLocationOption()"); LocationClientOption option = new LocationClientOption(); option.setServiceName("com.baidu.location.service_v2.6"); // 返回的定位结果包含地址信息 option.setAddrType("all"); // 是否需要POI的电话和地址等详细信息 option.setPoiExtraInfo(true); // 设置产品线名称。强烈建议您使用自定义的产品线名称,方便我们以后为您提供更高效准确的定位服务。 option.setProdName(getString(R.string.location_by_GPS)); // 设置GPS,使用gps前提是用户硬件打开gps。默认是不打开gps的。 option.setOpenGps(true); // 定位的时间间隔,单位:ms // 当所设的整数值大于等于1000(ms)时,定位SDK内部使用定时定位模式。 option.setScanSpan(500); // 查询范围,默认值为500,即以当前定位位置为中心的半径大小。 option.setPoiDistance(500); // 禁用启用缓存定位数据 option.disableCache(true); // 坐标系类型,百度手机地图对外接口中的坐标系默认是bd09ll option.setCoorType("bd09ll"); // 设置最多可返回的POI个数,默认值为3。由于POI查询比较耗费流量,设置最多返回的POI个数,以便节省流量。 option.setPoiNumber(3); // 设置定位方式的优先级, GpsFirst NetWorkFirst // 当gps可用,而且获取了定位结果时,不再发起网络请求,直接返回给用户坐标。这个选项适合希望得到准确坐标位置的用户。如果gps不可用,再发起网络请求,进行定位。 option.setPriority(LocationClientOption.GpsFirst); mLocClient.setLocOption(option); } }代码比较简单,主要思路是:
1、在onCreate的时候,让ProgressBar先转一会,创建一个LocationClient,并注册一个BDLocationListener用于监听定位消息;
2、创建一个Handler用于发消息MSG_REQUEST_LOCATION,用于请求获取定位信息,暂时消息以2s后发送,经测试发送太快往往还得不到数据;
3、收到消息后,可能经纬度都得到了,但是地址还未得到。所以如果未获取到地址的话,再发个消息MSG_REQUEST_LOCATION出去;
4、假如收到消息了,将ProgressBar停掉;
5、点屏幕上的Button按钮,将获取的经纬度信息传给WebViewActivity,并用百度地图的链接打开一个网页。WebViewActivity代码如下:
package com.baidumap.location; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.webkit.WebView; import com.baidu.R; public class WebViewActivity extends Activity { private static String TAG = "webViewActivity"; private String mHtml; private WebView mWebView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.webview); // get Bundle from previous activity. Intent intent = getIntent(); Bundle bundle = intent.getExtras(); Double latitude = bundle.getDouble(BaiduMapActivity.KEY_LATITUDE); Double longitude = bundle.getDouble(BaiduMapActivity.KEY_LONGITUDE); mWebView = (WebView)this.findViewById(R.id.webView); // enable javascript mWebView.getSettings().setJavaScriptEnabled(true); mWebView.addJavascriptInterface(new InJavaScriptLocalObj(), "local_obj"); // load the web mWebView.loadUrl("http://api.map.baidu.com/marker?location=" + latitude + "," + longitude + "&title=" + getString(R.string.mylocation) + "&output=html"); } final class InJavaScriptLocalObj { public void showSource(String html) { try { mHtml = html; Log.d(TAG, "InJavaScriptLocalObj: showSource, mHtml = " + mHtml); } catch (Exception e) { } } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { this.finish(); return super.onKeyDown(keyCode, event); } }上文代码中提到的R.layout.main以及R.layout.webview如下:
main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ProgressBar android:id="@+id/progress_bar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" style="?android:attr/progressBarStyleLarge" /> <Button android:id="@+id/location_btn" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/Location"/> <TextView android:id="@+id/location_info" android:layout_below="@id/location_btn" android:layout_width="fill_parent" android:layout_height="wrap_content"/> </RelativeLayout>webview.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <WebView android:id="@+id/webView" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>