之前看过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>