本次要实现的效果图
实现调用本机百度地图
- 在上次代码基础上修改AlertDialog样式,如下图所示,实现调用本机地图和程序导航两大功能;
- 若本机未安装百度地图,将进行提示未安装百度地图;
- 若已安装百度地图,程序将跳转到客户端进行导航。
实现程序导航
跳转到路线选择界面,包含驾车、公交、步行三种方式,如下图;
点击某种路线方式,进入到路径导航界面,上方是地图,下方是导航提示,如下图;
代码实现过程
a. AlertDialog样式修改
在上次代码基础上,修改AlertDialog下面的操作按钮
alertDialog.setPositiveButton("导航",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 这里监听程序导航操作
}
});
alertDialog.setNegativeButton("本机地图",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 这里监听调用本机地图操作
}
});
b. 本机地图调用
先判断是否安装百度地图客户端
// 判断是否安装百度地图客户端
private boolean isAvilible(Context context, String packageName) {
// 获取packagemanager
final PackageManager packageManager = context.getPackageManager();
// 获取所有已安装程序的包信息
List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
List<String> pName = new ArrayList<String>();// 用于存储所有已安装程序的包名
// 从pinfo中将包名字逐一取出,压入pName list中
if (pinfo != null) {
for (int i = 0; i < pinfo.size(); i++) {
String pn = pinfo.get(i).packageName;
pName.add(pn);
}
}
// 判断pName中是否有目标程序的包名,有TRUE,没有FALSE
return pName.contains(packageName);
}
若已安装,调用客户端地图
// 获取当前位置
final BDLocation location = locClient.getLastKnownLocation();
alertDialog.setNegativeButton("本机地图",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = null;
if (!isAvilible(MainActivity.this,"com.baidu.BaiduMap")) {
Toast.makeText(MainActivity.this,"您没安装百度地图",Toast.LENGTH_SHORT).show();
return;
}
try {
intent = Intent.getIntent("intent://map/direction?origin=latlng:"
+ location.getLongitude()
+ ","
+ location.getLatitude()
+ "|name:"
+ "我的位置"
+ "&destination=latlng:"
+ poi.location.latitude
+ ","
+ poi.location.longitude
+ "|name:"
+ poi.name
+ "&mode=driving&src=地图测试#Intent;"
+ "scheme=bdapp;package=com.baidu.BaiduMap;end");
startActivity(intent);
} catch (Exception e) {
Toast.makeText(MainActivity.this, "地理位置解析错误!",Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
});
c. 路径选择
alertDialog.setPositiveButton("导航",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
LatLng ll = new LatLng(location.getLatitude(),location.getLongitude());
LatLng dsll = new LatLng(poi.location.latitude,poi.location.longitude);
LxxzActivity.startLatLng = ll;
LxxzActivity.endLatLng = dsll;
Intent intent = new Intent(MainActivity.this,LxxzActivity.class);
intent.putExtra("dsName", poi.name);
intent.putExtra("dsAddress", poi.address);
startActivity(intent);
}
});
创建LxxzActivity,布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff" >
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="我的位置" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/view1"
android:padding="10dp"
android:text="TextView" />
<View
android:id="@+id/view1"
android:layout_width="wrap_content"
android:layout_height="0.5dp"
android:layout_below="@+id/textView1"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="#a3a3a3" />
</RelativeLayout>
<View
android:id="@+id/view2"
android:layout_width="wrap_content"
android:layout_height="0.5dp"
android:background="#a3a3a3" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RadioGroup
android:id="@+id/radioGroup1"
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal"
android:padding="5dp" >
<RadioButton
android:id="@+id/radio0"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.3"
android:background="@drawable/radiobutton"
android:button="@null"
android:checked="true"
android:gravity="center"
android:text="驾车" />
<View
android:id="@+id/view3"
android:layout_width="5dp"
android:layout_height="match_parent" />
<RadioButton
android:id="@+id/radio1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.3"
android:background="@drawable/radiobutton"
android:button="@null"
android:gravity="center"
android:text="公交" />
<View
android:id="@+id/view4"
android:layout_width="5dp"
android:layout_height="match_parent" />
<RadioButton
android:id="@+id/radio2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="0.3"
android:background="@drawable/radiobutton"
android:button="@null"
android:gravity="center"
android:text="步行" />
</RadioGroup>
<View
android:id="@+id/view3"
android:layout_width="wrap_content"
android:layout_height="0.5dp"
android:background="#a3a3a3" />
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="正在规划路线请稍后..." />
</FrameLayout>
</LinearLayout>
</LinearLayout>
效果图如下
LxxzActivit代码如下
public class LxxzActivity extends FragmentActivity implements
OnCheckedChangeListener {
public static LatLng startLatLng;
public static LatLng endLatLng;
// 自定义的替换掉原来的Fragment
LxxzFragment fragment;
public static TextView biao;
TextView name;
RadioGroup radioGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lxxz);
biao = (TextView) findViewById(R.id.textView3);
name = (TextView) findViewById(R.id.textView2);
radioGroup = (RadioGroup) findViewById(R.id.radioGroup1);
name.setText(getIntent().getStringExtra("dsName"));
fragment = new LxxzFragment();
// "D"——驾车方式,"B"——公交方式,"W"——步行方式
fragment.setType("D");
getFragmentManager().beginTransaction()
.replace(R.id.frameLayout, fragment).commit();
radioGroup.setOnCheckedChangeListener(this);
}
@Override
public void onCheckedChanged(RadioGroup arg0, int arg1) {
if (arg1 == R.id.radio0) {
biao.setVisibility(View.VISIBLE);
biao.setText("正在规划路线请稍后...");
fragment = new LxxzFragment();
fragment.setType("D");
getFragmentManager().beginTransaction()
.replace(R.id.frameLayout, fragment).commit();
}
if (arg1 == R.id.radio1) {
biao.setVisibility(View.VISIBLE);
biao.setText("正在规划路线请稍后...");
fragment = new LxxzFragment();
fragment.setType("B");
getFragmentManager().beginTransaction()
.replace(R.id.frameLayout, fragment).commit();
}
if (arg1 == R.id.radio2) {
biao.setVisibility(View.VISIBLE);
biao.setText("正在规划路线请稍后...");
fragment = new LxxzFragment();
fragment.setType("W");
getFragmentManager().beginTransaction()
.replace(R.id.frameLayout, fragment).commit();
}
}
}
接下来定义LxxzFragment,这是比较重要的一步;已经知道起点和终点,进行路线规划要
实现OnGetRoutePlanResultListener(路线规划监听借口),其布局文件就是一个Fragment,Fragment里面一个ListView(宽高fill_parent)
public class LxxzFragment extends Fragment implements
OnGetRoutePlanResultListener {
// 交通方式
String type;
// 路径规划累
RoutePlanSearch mSearch;
ListView listView;
// 自定义的adapter
BusAdapter busAdapter;
WalkingAdapter walkingAdapter;
DrivingAdapter drivingAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.page_lxxz, null);
return view;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
listView = (ListView) view.findViewById(R.id.listView1);
busAdapter = new BusAdapter(getActivity());
drivingAdapter = new DrivingAdapter(getActivity());
walkingAdapter = new WalkingAdapter(getActivity());
mSearch = RoutePlanSearch.newInstance();
mSearch.setOnGetRoutePlanResultListener(this);
// 起点
PlanNode stNode = PlanNode.withLocation(LxxzActivity.startLatLng);
// 终点
PlanNode enNode = PlanNode.withLocation(LxxzActivity.endLatLng);
if ("B".equals(type)) {
// .city("city")——当前所在城市名师
mSearch.transitSearch((new TransitRoutePlanOption()).from(stNode)
.city("烟台").to(enNode));
} else if ("D".equals(type)) {
mSearch.drivingSearch((new DrivingRoutePlanOption()).from(stNode)
.to(enNode));
} else if ("W".equals(type)) {
mSearch.walkingSearch((new WalkingRoutePlanOption()).from(stNode)
.to(enNode));
}
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public void onGetDrivingRouteResult(DrivingRouteResult result) {
// 驾车结果规划
}
@Override
public void onGetTransitRouteResult(TransitRouteResult result) {
// 公交规划结果操作
}
@Override
public void onGetWalkingRouteResult(WalkingRouteResult result) {
// 步行规划结果操作
}
}
d. 自定义规划结果adapter
自定义DrivingAdapter,把路线规划结果以下图方式展示
public class DrivingAdapter extends BaseAdapter {
List<DrivingRouteLine> list;
private Context context;
public DrivingAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {
return getList().size();
}
@Override
public Object getItem(int arg0) {
return null;
}
@Override
public long getItemId(int arg0) {
return 0;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
if (arg1 == null) {
arg1 = LayoutInflater.from(context).inflate(R.layout.cell_lxxz,
null);
}
TextView title = (TextView) arg1.findViewById(R.id.textView1);
TextView time = (TextView) arg1.findViewById(R.id.textView2);
TextView distance = (TextView) arg1.findViewById(R.id.textView3);
String titles = list.get(arg0).getAllStep().get(0)
.getEntraceInstructions();
title.setText(titles);
int miao = list.get(arg0).getDuration();
int shi = miao / 60 / 60;
int fen = (miao / 60) % 60;
if (fen == 0) {
fen = 1;
}
if (shi > 0) {
time.setText("约" + String.valueOf(shi) + "小时" + String.valueOf(fen)
+ "分钟");
} else {
time.setText("约" + String.valueOf(fen) + "分");
}
distance.setText(String.valueOf(list.get(arg0).getDistance()) + "米");
return arg1;
}
public List<DrivingRouteLine> getList() {
return list;
}
public void setList(List<DrivingRouteLine> list) {
this.list = list;
}
}
布局文件cell_lxxz
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/imageView1"
android:text="--" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView1"
android:layout_marginTop="10dp"
android:textColor="#a3a3a3"
android:text="--" />
<View
android:id="@+id/view1"
android:layout_width="0.5dp"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/textView2"
android:layout_alignTop="@+id/textView2"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@+id/textView2"
android:background="#a3a3a3" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/textView2"
android:layout_marginLeft="5dp"
android:layout_toLeftOf="@+id/imageView1"
android:layout_toRightOf="@+id/view1"
android:text="--"
android:textColor="#a3a3a3" />
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/icon_ks" />
</RelativeLayout>
1、BusAdapter、WalkingAdapter与DrivingAdapter类似,这边就不再贴出代码;
2、只需把List< DrivingRouteLine> list分别改为List< WalkingRouteLine> list和List< TransitRouteLine> list,修改getList()和setList()即可;
3、BusAdapter的title设置与其他两个adapter不一样,具体如下
String titles = "";
for (int i = 0; i < allStep.size(); i++) {
if (allStep.get(i).getStepType() == TransitRouteStepType.BUSLINE) {
titles = titles + allStep.get(i).getVehicleInfo().getTitle()
+ " ";
}
}
title.setText(titles);
e. 规划结果操作
驾车规划结果操作
@Override
public void onGetDrivingRouteResult(DrivingRouteResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
LxxzActivity.biao.setText("抱歉,未找到结果");
}
if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
// 起终点或途经点地址有岐义,通过以下接口获取建议查询信息
// result.getSuggestAddrInfo()
return;
}
if (result.error == SearchResult.ERRORNO.NO_ERROR) {
LxxzActivity.biao.setVisibility(View.GONE);
final List<DrivingRouteLine> list = result.getRouteLines();
drivingAdapter.setList(list);
listView.setAdapter(drivingAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
DrivingRouteLine line=list.get(arg2);
LuJingMapActivity.drivingRouteLine = line;
Intent intent = new Intent(getActivity(), LuJingMapActivity.class);
intent.putExtra("type", "D");
startActivity(intent);
}
});
}
}
公交规划结果操作
@Override
public void onGetTransitRouteResult(TransitRouteResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
LxxzActivity.biao.setText("抱歉,未找到结果");
}
if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
// 起终点或途经点地址有岐义,通过以下接口获取建议查询信息
// result.getSuggestAddrInfo()
return;
}
if (result.error == SearchResult.ERRORNO.NO_ERROR) {
LxxzActivity.biao.setVisibility(View.GONE);
final List<TransitRouteLine> list = result.getRouteLines();
busAdapter.setList(list);
listView.setAdapter(busAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
TransitRouteLine line=list.get(arg2);
LuJingMapActivity.transitRouteLine = line;
Intent intent = new Intent(getActivity(), LuJingMapActivity.class);
intent.putExtra("type", "B");
startActivity(intent);
}
});
}
}
步行规划结果操作
@Override
public void onGetWalkingRouteResult(WalkingRouteResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
LxxzActivity.biao.setText("抱歉,未找到结果");
}
if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
// 起终点或途经点地址有岐义,通过以下接口获取建议查询信息
// result.getSuggestAddrInfo()
return;
}
if (result.error == SearchResult.ERRORNO.NO_ERROR) {
LxxzActivity.biao.setVisibility(View.GONE);
final List<WalkingRouteLine> list = result.getRouteLines();
walkingAdapter.setList(list);
listView.setAdapter(walkingAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
WalkingRouteLine line=list.get(arg2);
LuJingMapActivity.walkingRouteLine = line;
Intent intent = new Intent(getActivity(), LuJingMapActivity.class);
intent.putExtra("type", "W");
startActivity(intent);
}
});
}
}
f. 路径规划地图展示
LuJingMapActivity布局文件是RelativeLayout,包含一个MapView和ListView
LuJingMapActivity实现
public class LuJingMapActivity extends Activity {
// 路径规划的具体信息
public static WalkingRouteLine walkingRouteLine;
public static DrivingRouteLine drivingRouteLine;
public static TransitRouteLine transitRouteLine;
public String type;
// 用来存储路径具体信息
List<String> list;
BaiduMap baiduMap;
ListView listView;
MapView mapView;
// 自定义的adapter,跟DrivingAdapter类似,可以自己动手尝试编写
LujingAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.acitvity_ljmap);
listView=(ListView)findViewById(R.id.listView1);
mapView=(MapView)findViewById(R.id.mapView);
type = getIntent().getStringExtra("type");
list = new ArrayList<String>();
mapView.showZoomControls(false);
baiduMap = mapView.getMap();
baiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(16));
adapter = new LujingAdapter(this);
if ("B".equals(type)) {
bus();
} else if ("D".equals(type)) {
drive();
} else if ("W".equals(type)) {
walk();
}
}
public void bus() {
TransitRouteOverlay overlay = new TransitRouteOverlay(baiduMap);
baiduMap.setOnMarkerClickListener(overlay);
overlay.setData(transitRouteLine);
overlay.addToMap();
overlay.zoomToSpan();
list.clear();
List<TransitStep> allStep = transitRouteLine.getAllStep();
for (int i = 0; i < allStep.size(); i++) {
list.add(allStep.get(i).getInstructions());
}
adapter.setList(list);
listView.setAdapter(adapter);
}
public void drive() {
DrivingRouteOverlay overlay = new DrivingRouteOverlay(baiduMap);
baiduMap.setOnMarkerClickListener(overlay);
overlay.setData(drivingRouteLine);
overlay.addToMap();
overlay.zoomToSpan();
list.clear();
List<DrivingStep> allStep = drivingRouteLine.getAllStep();
for (int i = 0; i < allStep.size(); i++) {
list.add(allStep.get(i).getInstructions());
}
adapter.setList(list);
listView.setAdapter(adapter);
}
public void walk() {
WalkingRouteOverlay overlay = new WalkingRouteOverlay(baiduMap);
baiduMap.setOnMarkerClickListener(overlay);
overlay.setData(walkingRouteLine);
overlay.addToMap();
overlay.zoomToSpan();
list.clear();
List<WalkingStep> allStep = walkingRouteLine.getAllStep();
for (int i = 0; i < allStep.size(); i++) {
list.add(allStep.get(i).getInstructions());
}
adapter.setList(list);
listView.setAdapter(adapter);
}
}
LujingAdapter实现的效果图
不熟悉的可以参考官方文档
http://developer.baidu.com/map/index.php?title=android-navsdk/guide/path