今天开发使用到了百度地图,其中在用到地位功能的时候遇到个问题,并解决之。以此记录一下。
问题1:百度地图默认中心点是北京天安门,而百度地图的定位功能是异步任务,所以,当你地图+定位功能一起用在同个Activity中时就会有个问题,就是每次地图的视角会先在北京天安门那,然后再移动到我们定位的位置.
解决1:解决问题1的思路:先获取到定位点,然后再加载地图。先在一个Activity中获取到定位点,然后再打开另一个Activity加载地图。
这是实现BDLocationListenerD 接口的核心代码,逻辑实现主要是在onReceiveLocation的回调方法上
public class LocationActivity extends Activity implements OnClickListener{
//定位相关
private LocationData locData=null;
private GeoPoint p=null;
private LocationClient mLocClient=null;
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.location_map_main);
Button button=(Button)findViewById(R.id.button1);
button.setOnClickListener(this);
/**
* 定位
*/
mLocClient=new LocationClient(getApplicationContext());
locData=new LocationData();
myLocationListener=new MyLocationListener();
mLocClient.registerLocationListener(myLocationListener);
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);//打开gps
option.setCoorType("bd09ll"); //设置坐标类型
mLocClient.setLocOption(option);
mLocClient.start();
}
/**
* 定位监听函数
*
*/
public class MyLocationListener implements BDLocationListener{
@Override
public void onReceiveLocation(BDLocation location) {
// TODO Auto-generated method stub
if (location == null)
return ;
locData.latitude = location.getLatitude();
locData.longitude = location.getLongitude();
p=new GeoPoint((int)(locData.latitude* 1e6),(int)(locData.longitude * 1e6));
Intent intent=new Intent(this, LocationMap.class);
Bundle bundle=new Bundle();
bundle.putInt("x", p.getLatitudeE6());
bundle.putInt("y", p.getLongitudeE6());
intent.putExtras(bundle);
startActivity(intent);
}
@Override
public void onReceivePoi(BDLocation poiLocation) {
// TODO Auto-generated method stub
if (poiLocation == null){
return ;
}
}
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), "开始定位,请稍等...", 1000).show();
mLocClient.requestLocation();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
if(mLocClient!=null){mLocClient.stop();}
super.onDestroy();
}
}
界面就一个按钮,点击按钮请求定位服务。
问题2:但是在下一个Activity中我要实现的一个功能是:再次定位。因为如果没有这个功能,那么用户每次要定位不就要回到定位的那个界面?这样用户体验就很差了。那么又得像前面一样一大堆声明、实现接口?
解决2:思路:将定位功能抽出来定义一个类,向外提供一个接口,在这接口内实现界面功能。
import javax.security.auth.Destroyable;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import android.content.Context;
/**
* 首先,定位查询是一个异步任务,有时候我们需要等待查询后的结果(定位结果),才进行下一步的操作.例如:
* 在一个Activity中点击查询,然后将查询结果通过Intent传递到另一个Activity(把定位结果显示在地图上的位置);
* 也可以在一个Activity中实现重新定位
* 只要在onDoAfter回调函数中,写入定位后要进行的操作即可,例如刷新地图定位图层。这样,较之前减少了代码冗余,增加了灵活性。
*
*/
public class MyLocation implements Destroyable{
private Context context;
private LocationClient mLocClient=null;
private DoAfterListener doAfterListener;
public MyLocation(Context context){
this.context=context;
init();
}
private void init() {
// TODO Auto-generated method stub
mLocClient=new LocationClient(context.getApplicationContext());
mLocClient.registerLocationListener(new MyLocationListener());
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);//打开gps
option.setCoorType("bd09ll"); //设置坐标类型
mLocClient.setLocOption(option);
mLocClient.start();
}
class MyLocationListener implements BDLocationListener{
@Override
public void onReceiveLocation(BDLocation location) {
// TODO Auto-generated method stub
onDoAfter(location);
}
@Override
public void onReceivePoi(BDLocation arg0) {
// TODO Auto-generated method stub
}
}
public interface DoAfterListener{
public void onDoAfter(BDLocation location);
}
public void setDoAfterListener(DoAfterListener doAfterListener2) {
this.doAfterListener = doAfterListener2;
mLocClient.requestLocation();
}
private void onDoAfter(BDLocation location){
if(doAfterListener!=null){
doAfterListener.onDoAfter(location);
}
}
@Override
public void destroy(){
// TODO Auto-generated method stub
if(mLocClient!=null){
mLocClient.stop();
mLocClient=null;
}
}
@Override
public boolean isDestroyed() {
// TODO Auto-generated method stub
return false;
}
}
然后调用它
public class LocationActivity extends Activity implements OnClickListener{
//定位相关
private LocationData locData=null;
private GeoPoint p=null;
MyLocation myLocation;
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.location_map_main);
Button button=(Button)findViewById(R.id.button1);
button.setOnClickListener(this);
/**
* 定位
*/
locData=new LocationData();
myLocation=new MyLocation(getActivity());
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), "开始定位,请稍等...", 1000).show();
myLocation.setDoAfterListener(new DoAfterListener() {
public void onDoAfter(BDLocation location) {
// TODO Auto-generated method stub
if (location == null)
return ;
locData.latitude = location.getLatitude();
locData.longitude = location.getLongitude();
p=new GeoPoint((int)(locData.latitude* 1e6),(int)(locData.longitude * 1e6));
Intent intent=new Intent(this, LocationMap.class);
Bundle bundle=new Bundle();
bundle.putInt("x", p.getLatitudeE6());
bundle.putInt("y", p.getLongitudeE6());
intent.putExtras(bundle);
startActivity(intent);
}
});
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
myLocation.destroy();
super.onDestroy();
}
}