由于毕设需要做一个手机计程器安卓应用,花了一个月时间仔细研究终于算是搞定了。
首先总结一下遇到的问题吧
1 由于我参考的是《安卓开发范例大全》这本书,里面有一个手机计程器的例子,不过里面用的是谷歌地图SDK,可能因为谷歌推出中国的原因,其中SDK有一个getlastknownLocation()的方法是永远也获得不了最后的位置,查阅很多国内外的网站,又说是有while语句,有的说权限没加上等等,都试过都不行,所以劝告大家以后碰到这个还是不要试了,另寻他法吧。
2 百度有定位SDK,也有地图SDK,二者有不同的功能,所以不要少引用一个jar文件。
3 定位本身有误差,正在研究如何将误差减小的办法。
不多说了,上源码吧。
package xiao.xiang.com;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.List;
import xiao.xiang.util.LogCat;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.GeoPoint;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.MKLocationManager;
import com.baidu.mapapi.MapActivity;
import com.baidu.mapapi.MapController;
import com.baidu.mapapi.MapView;
import com.baidu.mapapi.Overlay;
public class Main extends MapActivity {
/** Called when the activity is first created. */
private LocationClient locationClient = null;
private static final int UPDATE_TIME = 1000;
private GeoPoint gp1;
private GeoPoint gp2;
private boolean _run=false;
private double distance =0;
private TextView mTextView,mTextView1;
private Button mButton01;
private Button mButton02;
private MapController mapController;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//初始化一张图
initMapView();
//初始化位置
initLocationManager();
mMapView.setBuiltInZoomControls(true);
mapController = mMapView.getController();
mapController.setZoom(12);
/*对象初始化*/
mTextView = (TextView)findViewById(R.id.myText1);
mTextView1 = (TextView)findViewById(R.id.myText2);
mButton01 = (Button)findViewById(R.id.myButton1);
mButton02 = (Button)findViewById(R.id.myButton2);
/*获取当前GPS*/
locationClient = new LocationClient(this);
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);
option.setCoorType("bd09ll");
option.setPriority(LocationClientOption.NetWorkFirst);
option.setScanSpan(UPDATE_TIME);
locationClient.setLocOption(option);
locationClient.start();
locationClient.requestLocation();
locationClient.registerLocationListener(new BDLocationListener() {
@Override
public void onReceiveLocation(BDLocation location)
{
// TODO 自动生成的方法存根
if (location == null)
{
return;
}
gp2=getGeoByLocation(location);
if(_run)
{
refreshMapView();
}
mButton01.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v)
{
// TODO 自动生成的方法存根
gp1=gp2;
/*清楚OverLay*/
resetOverlay();
/*画起点*/
setStartpoint();
/*更新MapView*/
refreshMapView();
/*重设移动距离为0,并跟新TextView*/
distance=0;
mTextView.setText("移动距离:0M ");
/*启动画线的机制*/
_run=true;
}
});
/*结束记录Button*/
mButton02.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
{
/*画中点*/
setEndPoint();
/*刷新地图*/
refreshMapView();
/*终止画线机制*/
_run=false;
}
});
double i=0;
if(_run)
{
/*记下移动后的位置*/
//gp2=getGeoByLocation(location);
/*画路线*/
setRoute();
/*更新MapView*/
//refreshMapView();
/*取得移动距离*/
distance+=GetDistance(gp1,gp2);
if(distance>999)
{
mTextView.setText("移动距离:"+format(distance/1000)+"KM");
}
else
{
mTextView.setText("移动距离:"+format(distance)+"M");
}
if(gp2!=gp1)
{
gp1=gp2;
}
i=distance;
mTextView1.setText("移动步数:"+format(i/2)+"步");
}
}
@Override
public void onReceivePoi(BDLocation arg0) {
// TODO 自动生成的方法存根
}
});
/*结束记录Button*/
}
private GeoPoint getGeoByLocation(BDLocation location)
{
GeoPoint gp=null;
try
{
if(location!=null)
{
double geolatitude = location.getLatitude()*1E6;
double geolongitude = location.getLongitude()*1E6;
gp= new GeoPoint((int)geolatitude,(int)geolongitude);
}
}
catch(Exception e)
{
e.printStackTrace();
}
return gp;
}
private final static String APPLY_KEY="00F9E33D04A65010FAEB78008A846BF6D54F9066";
private BMapManager mBMapManager=null;
private Context context = Main.this;
private MapView mMapView = null;
private MKLocationManager mLocationManager = null;
private void initLocationManager()
{
// TODO 自动生成的方法存根
mLocationManager = mBMapManager.getLocationManager();
mLocationManager.enableProvider(MKLocationManager.MK_NETWORK_PROVIDER);
}
private String format(double num)
{
// TODO 自动生成的方法存根
NumberFormat formatter = new DecimalFormat("###");
String s=formatter.format(num);
return s;
}
public double GetDistance(GeoPoint gp1, GeoPoint gp2)
{
// TODO 自动生成的方法存根
double Lat1r = ConvertDegreeToRadians(gp1.getLatitudeE6()/1E6);
double Lat2r = ConvertDegreeToRadians(gp2.getLatitudeE6()/1E6);
double Long1r = ConvertDegreeToRadians(gp1.getLongitudeE6()/1E6);
double Long2r = ConvertDegreeToRadians(gp2.getLongitudeE6()/1E6);
/*地球半径(KM)*/
double R=6371;
double d=Math.acos(Math.sin(Lat1r)*Math.sin(Lat2r)+Math.cos(Lat1r)*Math.cos(Lat2r)*Math.cos(Long2r-Long1r))*R;
return d*1000;
}
private double ConvertDegreeToRadians(double degrees)
{
// TODO 自动生成的方法存根
return (Math.PI/180)*degrees;
}
private void setRoute()
{
// TODO 自动生成的方法存根
int mode=2;
MyOverLay mOverlay = new MyOverLay(gp1,gp2,mode);
List<Overlay> overlays = mMapView.getOverlays();
overlays.add(mOverlay);
}
private void setEndPoint()
{
// TODO 自动生成的方法存根
int mode=3;
MyOverLay mOverlay = new MyOverLay(gp1,gp2,mode);
List<Overlay>overlays = mMapView.getOverlays();
overlays.add(mOverlay);
}
public void refreshMapView()
{
mMapView.displayZoomControls(true);
MapController myMC = mMapView.getController();
myMC.animateTo(gp2);
}
private void resetOverlay()
{
// TODO 自动生成的方法存根
List<Overlay> overlays = mMapView.getOverlays();
overlays.clear();
}
private void setStartpoint()
{
// TODO 自动生成的方法存根
int mode = 1;
MyOverLay mOverlays = new MyOverLay(gp1,gp2,mode);
List<Overlay> overlays = mMapView.getOverlays();
overlays.add(mOverlays);
}
private void initMapView()
{
// TODO 自动生成的方法存根
LogCat.i("initMapView----");
mBMapManager = new BMapManager(context);
mBMapManager.init(APPLY_KEY, new MKGeneralListener(){
@Override
public void onGetNetworkState(int arg0)
{
// TODO 自动生成的方法存根
LogCat.i("onGetPermissionState-----");
}
@Override
public void onGetPermissionState(int arg0)
{
// TODO 自动生成的方法存根
LogCat.i("onGetNetworkState-----");
}
});
super.initMapActivity(mBMapManager);
mMapView =(MapView)findViewById(R.id.bmapView);
mMapView.getController();
mBMapManager.start();
}
@Override
protected boolean isRouteDisplayed()
{
// TODO 自动生成的方法存根
return false;
}
protected void onDestory()
{
super.onDestroy();
if(mBMapManager!=null){
mBMapManager.destroy();
mBMapManager=null;
}
}
protected void onResume()
{
super.onResume();
if(mBMapManager!=null){
mBMapManager.start();
}
}
protected void onPause()
{
super.onPause();
if(mBMapManager!=null){
mBMapManager.stop();
}
}
protected void onDestroy()
{
super.onDestroy();
if (locationClient != null && locationClient.isStarted())
{
locationClient.stop();
locationClient = null;
}
}
}
这个是main.java文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android="@+id/widget0"
android:background="@drawable/welome21"
android:orientation="vertical" >
<LinearLayout android:layout_width="240px"
android:layout_height="60px"
android:orientation="horizontal">
<Button android:id="@+id/myButton1"
android:layout_width="120px"
android:layout_height="60px"
android:background="@drawable/ib_forward"
/>
<Button android:id="@+id/myButton2"
android:layout_width="120px"
android:layout_height="60px"
android:background="@drawable/ib_forward1"/>
</LinearLayout>
<TextView android:id="@+id/myText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/str_text1"
android:textColor="@drawable/white"
android:textSize="24sp"
/>
<TextView android:id="@+id/myText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/str_text2"
android:textColor="@drawable/white"
android:textSize="24sp"
/>
<com.baidu.mapapi.MapView
android:id="@+id/bmapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true" />
</LinearLayout>
这个是Main.xml文件
界面就是这个样子
自己写的,程序虽能正常运行,但还是有许多小bug,所以源码暂不提供,我再努力测试一下。