在Fragment中实现百度地图,定位到当前位置(基于SDKv2.1.0)
使用最新版本的百度地图需要注意的几个地方:
1、libs文件夹下要有android-support-v4.jar、baidumapapi_v2_1_0.jar、locSDK_3.1.jar三个jar包和armeabi文件夹。
2、布局文件要写成<com.baidu.mapapi.map.MapView />,旧版本是写作<com.baidu.mapapi.MapView />的。
3、AndroidMainfest这个配置文件要把该添加的东西都加上。比如各种权限、比如屏幕支持、比如百度地图服务
<service
android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"> </service>
等
4、不要忘了申请自己的密钥。
……时间有限,就写这么多吧,遇到问题就百度一下,基本上也就解决了。
噢,附上自己的demo和各个链接。
百度地图API>Android SDK>相关下载 sdk下载 (http://developer.baidu.com/map/sdkandev-download.htm )
百度地图API>Android SDK>申请Key 申请key的链接 (http://developer.baidu.com/map/android-mobile-apply-key.htm)
百度地图API>定位 SDK>Android 定位SDK> 定位sdk的链接 (http://developer.baidu.com/map/geosdk-android-download.htm)
1、代码结构:
2、各个类的大致作用:
(1) Cheeses.java 填充没有用到的Fragment的内容
(2) DemoApplication.java 从百度地图sdk demo中直接拿来的;主要用来处理与key相关的操作
(3) MainActivity.java 实现适配器,完成不同Fragment之间的切换
(4) MapFragment.java 定位相关的操作
3、附上主要类的源码:
(1) MainActivity.java
import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.ListFragment; import android.support.v4.view.ViewPager; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; public class MainActivity extends FragmentActivity { static final int NUM_ITEMS = 10; MyAdapter mAdapter; ViewPager mPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mAdapter = new MyAdapter(getSupportFragmentManager()); mPager = (ViewPager)findViewById(R.id.pager); mPager.setAdapter(mAdapter); } public static class MyAdapter extends FragmentPagerAdapter { public MyAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return NUM_ITEMS; } @Override public Fragment getItem(int position) { if (position == 0) { return MapFragment.newInstance(); }else{ return ArrayListFragment.newInstance(position); } } } public static class ArrayListFragment extends ListFragment { int mNum; /** * Create a new instance of CountingFragment, providing "num" * as an argument. */ static ArrayListFragment newInstance(int num) { ArrayListFragment f = new ArrayListFragment(); // Supply num input as an argument. Bundle args = new Bundle(); args.putInt("num", num); f.setArguments(args); return f; } /** * When creating, retrieve this instance's number from its arguments. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mNum = getArguments() != null ? getArguments().getInt("num") : 1; } /** * The Fragment's UI is just a simple text view showing its * instance number. */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_pager_list, container, false); View tv = v.findViewById(R.id.text); ((TextView)tv).setText("Fragment #" + mNum); return v; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, Cheeses.sCheeseStrings)); } @Override public void onListItemClick(ListView l, View v, int position, long id) { Log.i("FragmentList", "Item clicked: " + id); } } }
(2) MapFragment.java
import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.mapapi.BMapManager; import com.baidu.mapapi.map.LocationData; import com.baidu.mapapi.map.MapController; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.MyLocationOverlay; import com.baidu.platform.comapi.basestruct.GeoPoint; import android.os.Bundle; import android.support.v4.app.Fragment; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class MapFragment extends Fragment { static MapView mMapView = null; private MapController mMapController = null; // 定位相关 LocationClient mLocClient; public MyLocationListenner myListener = new MyLocationListenner(); MyLocationOverlay myLocationOverlay = null; LocationData locData = null; static MapFragment newInstance() { MapFragment f = new MapFragment(); return f; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); DemoApplication app = (DemoApplication) getActivity().getApplication(); if (app.mBMapManager == null) { app.mBMapManager = new BMapManager(getActivity()); app.mBMapManager.init(DemoApplication.strKey, new DemoApplication.MyGeneralListener()); } // LocationClient just init once; // start() is moved mLocClient = new LocationClient(getActivity()); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true);// 打开gps option.setCoorType("bd09ll"); // 设置坐标类型 // option.setScanSpan(5000); //设置发起定位请求的间隔时间,单位毫秒 mLocClient.setLocOption(option); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.activity_locationoverlay, container, false); mMapView = (MapView) v.findViewById(R.id.bmapView); mMapController = mMapView.getController(); mMapView.getController().setZoom(14); mMapView.getController().enableClick(true); mMapView.setBuiltInZoomControls(true); myLocationOverlay = new MyLocationOverlay(mMapView); locData = new LocationData(); myLocationOverlay.setData(locData); mMapView.getOverlays().add(myLocationOverlay); myLocationOverlay.enableCompass(); mMapView.refresh(); return v; } /** * 监听函数,有新位置的时候,格式化成字符串,输出到屏幕中 */ public class MyLocationListenner implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { if (location == null) return; costTime = System.currentTimeMillis() - startTime; Log.d("MapFragment", "" + costTime); locData.latitude = location.getLatitude(); locData.longitude = location.getLongitude(); locData.accuracy = location.getRadius(); locData.direction = location.getDerect(); myLocationOverlay.setData(locData); mMapView.refresh(); mMapController.animateTo(new GeoPoint((int) (locData.latitude * 1e6), (int) (locData.longitude * 1e6))); // if request location success , stop it stopRequestLocation(); } public void onReceivePoi(BDLocation poiLocation) { if (poiLocation == null) { return; } } } /** * warning: this method is callback by activity manager; Be careful it's * lifecycle : It is called after oncreate , before oncreateview; see * detail: * http://developer.android.com/reference/android/support/v4/app/Fragment * .html#setUserVisibleHint(boolean) */ @Override public void setUserVisibleHint(boolean isVisibleToUser) { //核心方法,避免因Fragment跳转导致地图崩溃 super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser == true) { // if this view is visible to user, start to request user location startRequestLocation(); } else if (isVisibleToUser == false) { // if this view is not visible to user, stop to request user // location stopRequestLocation(); } } private void stopRequestLocation() { if (mLocClient != null) { mLocClient.unRegisterLocationListener(myListener); mLocClient.stop(); } } long startTime; long costTime; private void startRequestLocation() { // this nullpoint check is necessary if (mLocClient != null) { mLocClient.registerLocationListener(myListener); mLocClient.start(); mLocClient.requestLocation(); startTime = System.currentTimeMillis(); } } @Override public void onPause() { mMapView.onPause(); super.onPause(); } @Override public void onResume() { mMapView.onResume(); super.onResume(); } @Override public void onDestroy() { if (mLocClient != null) mLocClient.stop(); mMapView.destroy(); super.onDestroy(); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mMapView.onSaveInstanceState(outState); } }
package baidumapsdk.fragment; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.mapapi.map.BaiduMap; import com.baidu.mapapi.map.BitmapDescriptor; import com.baidu.mapapi.map.BitmapDescriptorFactory; 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.map.MarkerOptions; import com.baidu.mapapi.map.MyLocationData; import com.baidu.mapapi.map.BaiduMap.OnMapTouchListener; import com.baidu.mapapi.model.LatLng; import com.baidu.mapapi.search.core.SearchResult; import com.baidu.mapapi.search.geocode.GeoCodeResult; import com.baidu.mapapi.search.geocode.GeoCoder; import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener; import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption; import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult; import baidumapsdk.demo.MapControlDemo; import baidumapsdk.demo.R; import baidumapsdk.demo.MapControlDemo.MyLocationListenner; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; public class MapFragment extends Fragment implements OnGetGeoCoderResultListener{ private static final String TAG="MapFragment"; /** * MapView 是地图主控件 */ private MapView mMapView; private BaiduMap mBaiduMap; // 定位相关 LocationClient mLocClient; boolean isFirstLoc = true;// 是否首次定位 LocationClientOption option = null; GeoCoder mSearch = null; // 搜索模块,也可去掉地图模块独立使用 public MyLocationListenner myListener = new MyLocationListenner(); private TextView textView_message; private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { switch (msg.what) { case 0: // LatLng target = mBaiduMap.getMapStatus().target; //// MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory //// .newMapStatus(new MapStatus.Builder().target(target) //// .overlook(-15).rotate(180).build()); //// mBaiduMap.setMapStatus(mapStatusUpdate); // MyLocationData locData = new MyLocationData.Builder() // .accuracy(100) // // 此处设置开发者获取到的方向信息,顺时针0-360 // .direction(100).latitude(target.latitude/*+0.00059*/) // .longitude(target.longitude).build(); // Log.i(TAG, "==-->point.latitude:="+target.latitude+" point.longitude:="+target.longitude); // mBaiduMap.setMyLocationData(locData); // 反Geo搜索 mSearch.reverseGeoCode(new ReverseGeoCodeOption() .location(mBaiduMap.getMapStatus().target)); // TextView textView = new TextView(getApplicationContext()); // textView.setText("我在这"); // OverlayOptions ooA = new MarkerOptions().position(target).icon(bdA).title("地图位置") // .zIndex(9).draggable(true); // mMarkerA = (Marker) (mBaiduMap.addOverlay(ooA)); break; default: break; } }; }; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View view = inflater.inflate(R.layout.map_fragment, null); mMapView = (MapView) view.findViewById(R.id.bmapView); textView_message = (TextView) view.findViewById(R.id.textView_message); mBaiduMap = mMapView.getMap(); // 初始化搜索模块,注册事件监听 mSearch = GeoCoder.newInstance(); mSearch.setOnGetGeoCodeResultListener(this); // 开启定位图层 mBaiduMap.setMyLocationEnabled(true); // 定位初始化 mLocClient = new LocationClient(getActivity()); mLocClient.registerLocationListener(myListener); option = new LocationClientOption(); Log.i(TAG, "==-->option:="+option); option.setOpenGps(true);// 打开gps option.setCoorType("bd09ll"); // 设置坐标类型 option.setScanSpan(1000); mLocClient.setLocOption(option); mLocClient.start(); return view; } @Override public void onResume() { // TODO Auto-generated method stub super.onResume(); mBaiduMap.setOnMapTouchListener(new OnMapTouchListener() { @Override public void onTouch(MotionEvent event) { mLocClient.stop(); if (event.getAction() == MotionEvent.ACTION_UP) { clearOverlay(null); handler.sendEmptyMessage(0); } } }); } /** * 清除所有Overlay * * @param view */ public void clearOverlay(View view) { mBaiduMap.clear(); } /** * 定位SDK监听函数 */ public class MyLocationListenner implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { // map view 销毁后不在处理新接收的位置 if (location == null || mMapView == null) return; // // 反Geo搜索 mSearch.reverseGeoCode(new ReverseGeoCodeOption() .location(mBaiduMap.getMapStatus().target)); MyLocationData locData = new MyLocationData.Builder() .accuracy(location.getRadius()) // 此处设置开发者获取到的方向信息,顺时针0-360 .direction(100).latitude(location.getLatitude()) .longitude(location.getLongitude()).build(); mBaiduMap.setMyLocationData(locData); LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); // 设置地图中心点 MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory .newMapStatus(new MapStatus.Builder().target(latLng) .overlook(-15).rotate(180).build()); mBaiduMap.setMapStatus(mapStatusUpdate); if (isFirstLoc) { isFirstLoc = false; LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll); mBaiduMap.animateMapStatus(u); } } public void onReceivePoi(BDLocation poiLocation) { } } @Override public void onGetGeoCodeResult(GeoCodeResult result) { if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) { Toast.makeText(getActivity(), "抱歉,未能找到结果", Toast.LENGTH_LONG) .show(); return; } mBaiduMap.clear(); mBaiduMap.addOverlay(new MarkerOptions().position(result.getLocation()) .icon(BitmapDescriptorFactory .fromResource(R.drawable.icon_marka))); mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(result .getLocation())); String strInfo = String.format("纬度:%f 经度:%f", result.getLocation().latitude, result.getLocation().longitude); // Toast.makeText(MapControlDemo.this, strInfo, Toast.LENGTH_LONG).show(); } @Override public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) { if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) { Toast.makeText(getActivity(), "抱歉,未能找到结果", Toast.LENGTH_LONG) .show(); return; } mBaiduMap.clear(); // mBaiduMap.addOverlay(new MarkerOptions().position(result.getLocation()) // .icon(BitmapDescriptorFactory // .fromResource(R.drawable.icon_marka))); BitmapDescriptor bd; LatLng target = mBaiduMap.getMapStatus().target; Double laDouble = (target.latitude+0.0003); LatLng latLng = new LatLng(laDouble,target.longitude); TextView textView = new TextView(getActivity()); textView.setGravity(Gravity.CENTER); textView.setBackgroundResource(R.drawable.button_on); textView.setTextColor(Color.RED); textView.setText(result.getAddress()); // bd = BitmapDescriptorFactory.fromBitmap(getBitmapFromView(textView)); //这个属于自定义的 // bd = BitmapDescriptorFactory.fromView(textView)/*(getBitmapFromView(textView))*/; //这个是官方自身的 // OverlayOptions oo = new MarkerOptions().icon(bd). // position(latLng); // mBaiduMap.addOverlay(oo); // mBaiduMap.addOverlay(new TextOptions().bgColor(Color.RED).fontSize(40).text(result.getAddress()).rotate(0).position(latLng/*mBaiduMap.getMapStatus().target*/)); mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(result .getLocation())); textView_message.setText(result.getAddress()); textView_message.setTextColor(Color.RED); textView_message.setBackgroundResource(R.drawable.button_on); // Toast.makeText(MapControlDemo.this, result.getAddress(),Toast.LENGTH_LONG).show(); } }