百度地图3.3带搜索功能

来源:互联网 发布:c java md5加密解密 编辑:程序博客网 时间:2024/04/28 11:34

百度地图3.3带搜索功能


       寒假参加一个软件的比赛用到了百度地图的定位功能同时还要自带搜索框进行搜索,目前网上的博客大多基于旧版本的百度地图,但是新版本的百度地图较就版本做了很大的改进今天就让我整理一下这块内容。
      首先先简要的介绍一下本程序的功能就是启动应用程序后(特别注意要联网的不管是什么网络)进入界面就是下面界面1先根据网络定位你所处的位置并且检索出你附近2km范围内的医院,因为我们参加比赛是做的是医院的网上挂号功能所以显示出来的兴趣点是医院当然你可以自己定义检索的兴趣关键字。
 界面1
       其次就是如果你想要自己输入地址进行搜索那么你先在界面1输入要前往的城市,点击下一步出现界面2,在界面2的搜索框中输入你的你前往的地址。

界面2
      在界面1我输入了济南市页面没有跳转只是搜索框提示输入内容改变,我这里输入了齐鲁医院点击搜索按钮就会出现界面3的搜索结果,点击搜索按钮后搜索栏自动回位到最初始的状态。

界面3
       百度地图每页最多显示10条搜索的结果,所以可能会检索出很多的数据这块我也考虑到了就是增加一个下一组的按钮由于不好截图我试了几次才成功的截到图。

界面4
       如图界面4每次点击下一组数据的时候就会出现吐西的弹出提示。
       界面介绍完是不是还可以下面就一块来学习一下代码吧!
       首先将还是来看一下我们的布局文件这里有两个布局文件。search_layout.xml和main.xml其中在main.xml文件中包含了search_layout.xml至于不懂include标签的请自觉点百度
search_layout.xml
<span style="font-size:14px;"><span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:orientation="vertical"    tools:context=".activity.PoiSearchActivity" >    <RelativeLayout        android:id="@+id/top"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:background="@drawable/top_background"        android:paddingLeft="10dp"        android:paddingRight="10dp" >        <Button            android:id="@+id/dataNumPage"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_centerVertical="true"            android:background="@drawable/search_btn_background"            android:gravity="center"            android:text="下一组"            android:textSize="12sp"            android:textStyle="bold" />        <Button            android:id="@+id/btnSearch"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerVertical="true"            android:layout_marginRight="3dp"            android:layout_toLeftOf="@id/dataNumPage"            android:background="@drawable/search_btn_background"            android:gravity="center"            android:text="下一步"            android:textSize="12sp"            android:textStyle="bold" />        <RelativeLayout            android:id="@+id/rlSearchFrameDelete"            android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:layout_centerVertical="true"            android:layout_toLeftOf="@id/btnSearch"            android:gravity="center_vertical" >            <EditText                android:id="@+id/etSearch"                android:layout_width="fill_parent"                android:layout_height="wrap_content"                android:layout_marginRight="10dp"                android:background="@drawable/search_frame"                android:hint="请输入前往的城市"                android:paddingLeft="32dp"                android:singleLine="true"                android:textSize="12sp" />            <ImageView                android:id="@+id/ivDeleteText"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_alignParentRight="true"                android:layout_centerInParent="true"                android:paddingRight="20dp"                android:src="@drawable/delete"                android:visibility="gone" />        </RelativeLayout>    </RelativeLayout></RelativeLayout></span></span>
main.xml
<span style="font-size:14px;"><span style="font-size:14px;"><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity" >   <include       android:id="@+id/above"       layout="@layout/search_layout"/>          <com.baidu.mapapi.map.MapView        android:layout_below="@id/above"      android:id="@+id/bmapView"      android:layout_width="fill_parent"      android:layout_height="fill_parent"      android:clickable="true" /></RelativeLayout></span></span>
       上面贴出了布局文件,要特别注意的是要在百度地图的官网下载相应的包放在libs文件件下jar文件要add to build path,本文最后会给出相应的demo你也可以里面拷贝。
项目清单文件manifest.xml
<span style="font-size:14px;"><span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="cn.sdjzu.xg12"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="21" />        <!-- 这个权限用于进行网络定位--><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission><!-- 这个权限用于访问GPS定位--><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission><!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位--><uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission><!-- 获取运营商信息,用于支持提供运营商信息相关的接口--><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission><!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位--><uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>        <!-- SD卡读取权限,用户写入离线定位数据--><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission><!--允许应用读取低级别的系统日志文件 --><uses-permission android:name="android.permission.READ_LOGS"></uses-permission>        <uses-permission android:name="android.permission.INTERNET" />        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />        <uses-permission android:name="android.permission.GET_ACCOUNTS" />  <uses-permission android:name="android.permission.USE_CREDENTIALS" />  <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />  <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />  <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />  <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />  <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  <uses-permission android:name="android.permission.READ_PHONE_STATE" />  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  <uses-permission android:name="android.permission.BROADCAST_STICKY" />  <uses-permission android:name="android.permission.WRITE_SETTINGS" />  <uses-permission android:name="android.permission.READ_PHONE_STATE" />       <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <meta-data            android:name="com.baidu.lbsapi.API_KEY"            android:value="AmpD9McOPKWnXILW4yK5GGrg" />        <activity            android:name=".activity.PoiSearchActivity"            android:label="@string/app_name"             android:theme="@android:style/Theme.NoTitleBar">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"></service>    </application></manifest></span></span>
       很多人可能诧异这个文件有什么好贴的听我慢慢道来,由于搜索框的布局采用了相对布局并且没有人为的指定高度所以就出现一个比较难发现的bug如果要是不把界面的标题栏给去掉显示出来的效果很乱,当初我在activity中使用代码把标题栏去掉不管用那么问题来了究竟是什么原因呢后来试了在项目清单文件中配置去除顶部的标题栏结果就好了,原因我只能说个大概如果采用前者在界面加载时才会除去标题栏而后者只要程序运行就会去掉了有时间差的问题,这里要特别的注意。
PoiSearchActivity.class
<span style="font-size:14px;"><span style="font-size:14px;">import android.app.Activity;import android.os.Bundle;import android.text.Editable;import android.text.TextWatcher;import android.view.View;import android.view.View.OnClickListener;import android.view.Window;import android.widget.Button;import android.widget.EditText;import android.widget.ImageView;import android.widget.Toast;import cn.sdjzu.xg12.R;import cn.sdjzu.xg12.util.MyLocationListener;import com.baidu.location.BDLocationListener;import com.baidu.location.LocationClient;import com.baidu.location.LocationClientOption;import com.baidu.location.LocationClientOption.LocationMode;import com.baidu.mapapi.SDKInitializer;import com.baidu.mapapi.map.BaiduMap;import com.baidu.mapapi.map.MapStatus;import com.baidu.mapapi.map.MapStatusUpdate;import com.baidu.mapapi.map.MapStatusUpdateFactory;import com.baidu.mapapi.map.MapView;import com.baidu.mapapi.overlayutil.PoiOverlay;import com.baidu.mapapi.search.core.CityInfo;import com.baidu.mapapi.search.core.PoiInfo;import com.baidu.mapapi.search.core.SearchResult;import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;import com.baidu.mapapi.search.poi.PoiCitySearchOption;import com.baidu.mapapi.search.poi.PoiDetailResult;import com.baidu.mapapi.search.poi.PoiDetailSearchOption;import com.baidu.mapapi.search.poi.PoiResult;import com.baidu.mapapi.search.poi.PoiSearch;import com.baidu.mapapi.search.sug.OnGetSuggestionResultListener;import com.baidu.mapapi.search.sug.SuggestionResult;import com.baidu.mapapi.search.sug.SuggestionSearch;public class PoiSearchActivity extends Activity implementsOnGetPoiSearchResultListener, OnGetSuggestionResultListener {public LocationClient mLocationClient = null;public BDLocationListener myListener;private PoiSearch mPoiSearch = null;private SuggestionSearch mSuggestionSearch = null;private BaiduMap mBaiduMap = null;private ImageView ivDeleteText;private MapView mMapView;private EditText etSearch;private Button operator_btn;private Button dataNumPage_btn;private String city;private String keyWorld;private int load_Index = 0;private int pageNum = 0;private int totalPageNum = 0;private boolean isCustomSeach = true;@Overrideprotected void onCreate(Bundle arg0) {// TODO Auto-generated method stubsuper.onCreate(arg0);//这一句特别注意一定要放在设置界面的前面否则会出错的SDKInitializer.initialize(getApplicationContext());setContentView(R.layout.main);//一些地图和控件的初始化的操作init();//设置地图的俯视角度让地图看起来更有立体感MapStatus ms = new MapStatus.Builder().overlook(-20).zoom(15).build();MapStatusUpdate msu = MapStatusUpdateFactory.newMapStatus(ms);mBaiduMap.setMapStatus(msu);}public void init() {ivDeleteText = (ImageView) findViewById(R.id.ivDeleteText);etSearch = (EditText) findViewById(R.id.etSearch);operator_btn = (Button) findViewById(R.id.btnSearch);dataNumPage_btn = (Button) findViewById(R.id.dataNumPage);ButtonOnClickListener listener = new ButtonOnClickListener();operator_btn.setOnClickListener(listener);dataNumPage_btn.setOnClickListener(listener);mPoiSearch = PoiSearch.newInstance();mPoiSearch.setOnGetPoiSearchResultListener(this);mSuggestionSearch = SuggestionSearch.newInstance();mSuggestionSearch.setOnGetSuggestionResultListener(this);mMapView = (MapView) findViewById(R.id.bmapView);mBaiduMap = mMapView.getMap();ivDeleteText.setOnClickListener(new OnClickListener() {public void onClick(View v) {etSearch.setText("");}});etSearch.addTextChangedListener(new TextWatcher() {public void onTextChanged(CharSequence s, int start, int before,int count) {// TODO Auto-generated method stub}public void beforeTextChanged(CharSequence s, int start, int count,int after) {// TODO Auto-generated method stub}public void afterTextChanged(Editable s) {if (s.length() == 0) {ivDeleteText.setVisibility(View.GONE);} else {ivDeleteText.setVisibility(View.VISIBLE);}}});//下面的这一段代码在百度地图Api上面有可以拷贝过来直接使用mLocationClient = new LocationClient(getApplicationContext()); // 声明LocationClient类myListener = new MyLocationListener(mBaiduMap, mPoiSearch);mLocationClient.registerLocationListener(myListener);LocationClientOption option = new LocationClientOption();option.setLocationMode(LocationMode.Hight_Accuracy);// 设置定位模式option.setCoorType("bd09ll");// 返回的定位结果是百度经纬度,默认值gcj02option.setScanSpan(1000);// 设置发起定位请求的间隔时间为5000msoption.setIsNeedAddress(true);// 返回的定位结果包含地址信息option.setNeedDeviceDirect(true);// 返回的定位结果包含手机机头的方向mLocationClient.setLocOption(option);// 开启定位图层mBaiduMap.setMyLocationEnabled(true);}@Overridepublic void onGetSuggestionResult(SuggestionResult arg0) {// TODO Auto-generated method stub}@Overridepublic void onGetPoiDetailResult(PoiDetailResult result) {if (result.error != SearchResult.ERRORNO.NO_ERROR) {Toast.makeText(PoiSearchActivity.this, "抱歉,未找到结果",Toast.LENGTH_SHORT).show();} else {Toast.makeText(PoiSearchActivity.this,result.getName() + ": " + result.getAddress(),Toast.LENGTH_SHORT).show();}}@Overridepublic void onGetPoiResult(PoiResult result) {//获取兴趣点的检索结果根据error信息判断不同的检索情况if (result == null|| result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {Toast.makeText(PoiSearchActivity.this, "未找到结果", Toast.LENGTH_LONG).show();return;}if (result.error == SearchResult.ERRORNO.NO_ERROR) {if (result.getTotalPageNum() > 1) {pageNum = result.getTotalPageNum();}totalPageNum = result.getTotalPageNum();mBaiduMap.clear();PoiOverlay overlay = new MyPoiOverlay(mBaiduMap);mBaiduMap.setOnMarkerClickListener(overlay);overlay.setData(result);overlay.addToMap();overlay.zoomToSpan();return;}if (result.error == SearchResult.ERRORNO.AMBIGUOUS_KEYWORD) {// 当输入关键字在本市没有找到,但在其他城市找到时,返回包含该关键字信息的城市列表String strInfo = "在";for (CityInfo cityInfo : result.getSuggestCityList()) {strInfo += cityInfo.city;strInfo += ",";}strInfo += "找到结果";Toast.makeText(PoiSearchActivity.this, strInfo, Toast.LENGTH_LONG).show();}}private class ButtonOnClickListener implements OnClickListener {@Overridepublic void onClick(View v) {//这里是设置最主要的按钮的点击事件做到不跳转界面获取到相应的数据if (v.getId() == R.id.btnSearch) {if (operator_btn.getText().equals("下一步")) {//先判断一下输入的城市是不是为空如果为空点击了下一步就给出提示if (etSearch.getText().toString().isEmpty()) {Toast.makeText(PoiSearchActivity.this, "请输入城市再进行下一步",Toast.LENGTH_SHORT).show();} else {//获取相应的城市数据city = etSearch.getText().toString();etSearch.setText("");etSearch.setHint("请输入您要前往的医院");operator_btn.setText("搜索");}} else {//因为第一次进入界面搜索的是根据网络定位周边的医院所以这里要判断一下是不是自动的搜索isCustomSeach = false;keyWorld = etSearch.getText().toString();if (!keyWorld.isEmpty()) {search();etSearch.setText("");etSearch.setHint("请输入您要前往的城市");operator_btn.setText("下一步");} else {Toast.makeText(PoiSearchActivity.this, "请输入关键字再进行检索",Toast.LENGTH_SHORT).show();}}} else if (v.getId() == R.id.dataNumPage) {if (load_Index < pageNum) {if (isCustomSeach) {Toast.makeText(PoiSearchActivity.this,"当前仅是显示您附近的医院如果想获取更多的医院请在搜索框中搜索",Toast.LENGTH_LONG).show();} else {load_Index++;search();Toast.makeText(PoiSearchActivity.this,"当前是第" + load_Index + "页/共" + totalPageNum+ "页", Toast.LENGTH_SHORT).show();}}}}public void search() {mPoiSearch.searchInCity((new PoiCitySearchOption()).city(city).keyword(keyWorld).pageNum(load_Index));}}private class MyPoiOverlay extends PoiOverlay {public MyPoiOverlay(BaiduMap baiduMap) {super(baiduMap);}@Overridepublic boolean onPoiClick(int index) {super.onPoiClick(index);PoiInfo poi = getPoiResult().getAllPoi().get(index);mPoiSearch.searchPoiDetail((new PoiDetailSearchOption()).poiUid(poi.uid));return true;}}//下面的这几条主要的作用就是把地图的生命周期和activity的生命周期进行绑定这样就不会出现锁屏地图出错的情况了@Overrideprotected void onResume() {super.onResume();mMapView.onResume();mLocationClient.start();}@Overrideprotected void onPause() {super.onPause();mMapView.onPause();mLocationClient.stop();}@Overrideprotected void onDestroy() {super.onDestroy();// 关闭定位图层mBaiduMap.setMyLocationEnabled(false);mMapView.onDestroy();mPoiSearch.destroy();}}</span></span>
MyLocationListener.class
<span style="font-size:14px;"><span style="font-size:14px;">import com.baidu.location.BDLocation;import com.baidu.location.BDLocationListener;import com.baidu.mapapi.map.BaiduMap;import com.baidu.mapapi.map.MapStatusUpdate;import com.baidu.mapapi.map.MapStatusUpdateFactory;import com.baidu.mapapi.map.MyLocationData;import com.baidu.mapapi.model.LatLng;import com.baidu.mapapi.search.poi.PoiNearbySearchOption;import com.baidu.mapapi.search.poi.PoiSearch;public class MyLocationListener implements BDLocationListener{private BaiduMap mBaiduMap;private PoiSearch poiSearch;private boolean isFirstLoc = true;public LatLng ll;public MyLocationListener(BaiduMap mBaiduMap,PoiSearch poiSearch) {this.mBaiduMap = mBaiduMap;this.poiSearch = poiSearch;}@Overridepublic void onReceiveLocation(BDLocation location) {if(location==null){System.out.println("我是定位界面我终止了");return;}// 构造定位数据  MyLocationData locData = new MyLocationData.Builder()      .accuracy(location.getRadius())      // 此处设置开发者获取到的方向信息,顺时针0-360      .direction(100).latitude(location.getLatitude())      .longitude(location.getLongitude()).build(); mBaiduMap.setMyLocationData(locData);if (isFirstLoc) {              isFirstLoc = false;             //定位到的经度和纬度信息            ll = new LatLng(location.getLatitude(),                      location.getLongitude());                         MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);             search(ll);            //将地图迁移至定位点            mBaiduMap.animateMapStatus(u);         }  }public void search(LatLng ll) {poiSearch.searchNearby(new PoiNearbySearchOption().keyword("医院").radius(2000).location(ll));}}</span></span>
       写了不少了也差不多解释清楚了,希望大家引用的时候注明出处,请尊重原创……
       demo下载地址源代码下载地址







0 0