Android百度地圖之定位圖層
在使用百度地圖結合GPS進行定位一文中,我們已經介紹了利用GPS結合百度地圖進行定位,另外我們也可以使用百度SDK里面集成的方法,直接進行定位,這樣就不需要我們自己去寫GPS定位的方法了,代碼原型來自百度Demo,代碼如下:
Activity:
package com.home; import android.app.Activity; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.AttributeSet; import android.util.Log; import android.view.Menu; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast; import android.widget.RadioGroup.OnCheckedChangeListener; 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.LocationData; import com.baidu.mapapi.map.MapController; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.MyLocationOverlay; import com.baidu.mapapi.map.PopupClickListener; import com.baidu.mapapi.map.PopupOverlay; import com.baidu.platform.comapi.basestruct.GeoPoint; /** * 此demo用來展示如何結合定位SDK實現定位,并使用MyLocationOverlay繪制定位位置 同時展示如何使用自定義圖標繪制并點擊時彈出泡泡 * */ public class LocationOverlayActivity extends Activity { // 定位相關 LocationClient mLocClient; LocationData locData = null; public MyLocationListenner myListener = new MyLocationListenner(); // 定位圖層 locationOverlay myLocationOverlay = null; // 彈出泡泡圖層 private PopupOverlay pop = null;// 彈出泡泡圖層,瀏覽節點時使用 private TextView popupText = null;// 泡泡view private View viewCache = null; // 地圖相關,使用繼承MapView的MyLocationMapView目的是重寫touch事件實現泡泡處理 // 如果不處理touch事件,則無需繼承,直接使用MapView即可 MyLocationMapView mMapView = null; // 地圖View private MapController mMapController = null; // UI相關 OnCheckedChangeListener radioButtonListener = null; Button requestLocButton = null; boolean isRequest = false;// 是否手動觸發請求定位 boolean isFirstLoc = true;// 是否首次定位 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_locationoverlay); CharSequence titleLable = "定位功能"; setTitle(titleLable); requestLocButton = (Button) findViewById(R.id.button1); OnClickListener btnClickListener = new OnClickListener() { @Override public void onClick(View v) { // 手動定位請求 requestLocClick(); } }; requestLocButton.setOnClickListener(btnClickListener); RadioGroup group = (RadioGroup) this.findViewById(R.id.radioGroup); radioButtonListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { if (checkedId == R.id.defaulticon) { // 傳入null則,恢復默認圖標 modifyLocationOverlayIcon(null); } if (checkedId == R.id.customicon) { // 修改為自定義marker modifyLocationOverlayIcon(getResources().getDrawable( R.drawable.icon_geo)); } } }; group.setOnCheckedChangeListener(radioButtonListener); // 地圖初始化 mMapView = (MyLocationMapView) findViewById(R.id.bmapView); mMapController = mMapView.getController(); mMapView.getController().setZoom(14); mMapView.getController().enableClick(true); mMapView.setBuiltInZoomControls(true); // 創建 彈出泡泡圖層 createPaopao(); // 定位初始化 mLocClient = new LocationClient(this); locData = new LocationData(); mLocClient.registerLocationListener(myListener); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true);// 打開gps option.setCoorType("bd09ll"); // 設置坐標類型 option.setScanSpan(5000); mLocClient.setLocOption(option); mLocClient.start(); // 定位圖層初始化 myLocationOverlay = new locationOverlay(mMapView); // 設置定位數據 myLocationOverlay.setData(locData); // 添加定位圖層 mMapView.getOverlays().add(myLocationOverlay); myLocationOverlay.enableCompass(); // 修改定位數據后刷新圖層生效 mMapView.refresh(); } /** * 手動觸發一次定位請求 */ public void requestLocClick() { isRequest = true; mLocClient.requestLocation(); Toast.makeText(LocationOverlayActivity.this, "正在定位……", Toast.LENGTH_SHORT).show(); } /** * 修改位置圖標 * * @param marker */ public void modifyLocationOverlayIcon(Drawable marker) { // 當傳入marker為null時,使用默認圖標繪制 myLocationOverlay.setMarker(marker); // 修改圖層,需要刷新MapView生效 mMapView.refresh(); } /** * 創建彈出泡泡圖層 */ public void createPaopao() { viewCache = getLayoutInflater() .inflate(R.layout.custom_text_view, null); popupText = (TextView) viewCache.findViewById(R.id.textcache); // 泡泡點擊響應回調 PopupClickListener popListener = new PopupClickListener() { @Override public void onClickedPopup(int index) { Log.v("click", "clickapoapo"); } }; pop = new PopupOverlay(mMapView, popListener); MyLocationMapView.pop = pop; } /** * 定位SDK監聽函數 */ public class MyLocationListenner implements BDLocationListener { @Override public void onReceiveLocation(BDLocation location) { if (location == null) return; locData.latitude = location.getLatitude(); locData.longitude = location.getLongitude(); // 如果不顯示定位精度圈,將accuracy賦值為0即可 locData.accuracy = location.getRadius(); locData.direction = location.getDerect(); // 更新定位數據 myLocationOverlay.setData(locData); // 更新圖層數據執行刷新后生效 mMapView.refresh(); // 是手動觸發請求或首次定位時,移動到定位點 if (isRequest || isFirstLoc) { // 移動地圖到定位點 mMapController.animateTo(new GeoPoint( (int) (locData.latitude * 1e6), (int) (locData.longitude * 1e6))); isRequest = false; } // 首次定位完成 isFirstLoc = false; } public void onReceivePoi(BDLocation poiLocation) { if (poiLocation == null) { return; } } } // 繼承MyLocationOverlay重寫dispatchTap實現點擊處理 public class locationOverlay extends MyLocationOverlay { public locationOverlay(MapView mapView) { super(mapView); } @Override protected boolean dispatchTap() { // 處理點擊事件,彈出泡泡 popupText.setBackgroundResource(R.drawable.popup); popupText.setText("我的位置"); pop.showPopup(BMapUtil.getBitmapFromView(popupText), new GeoPoint( (int) (locData.latitude * 1e6), (int) (locData.longitude * 1e6)), 8); return true; } } @Override protected void onPause() { mMapView.onPause(); super.onPause(); } @Override protected void onResume() { mMapView.onResume(); super.onResume(); } @Override protected void onDestroy() { // 退出時銷毀定位 if (mLocClient != null) mLocClient.stop(); mMapView.destroy(); super.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mMapView.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mMapView.onRestoreInstanceState(savedInstanceState); } @Override public boolean onCreateOptionsMenu(Menu menu) { return true; } } /** * 繼承MapView重寫onTouchEvent實現泡泡處理操作 * * @author Administrator * */ class MyLocationMapView extends MapView { static PopupOverlay pop = null;// 彈出泡泡圖層,點擊圖標使用 public MyLocationMapView(Context context) { super(context); } public MyLocationMapView(Context context, AttributeSet attrs) { super(context, attrs); } public MyLocationMapView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onTouchEvent(MotionEvent event) { if (!super.onTouchEvent(event)) { // 消隱泡泡 if (pop != null && event.getAction() == MotionEvent.ACTION_UP) pop.hidePop(); } return true; } }
地圖工具類:
package com.home; import android.graphics.Bitmap; import android.view.View; public class BMapUtil { /** * 從view 得到圖片 * * @param view * @return */ public static Bitmap getBitmapFromView(View view) { view.destroyDrawingCache(); view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec .makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); view.setDrawingCacheEnabled(true); Bitmap bitmap = view.getDrawingCache(true); return bitmap; } }
配置文件:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.home" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="10" /> <!-- 使用網絡功能所需權限 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" > </uses-permission> <uses-permission android:name="android.permission.INTERNET" > </uses-permission> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" > </uses-permission> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" > </uses-permission> <!-- 讀取手機的當前狀態權限,沒有的話會報錯,這個是使用百度地圖API必須的 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" > </uses-permission> <!-- Cache功能需要讀寫外部存儲器 ,若沒這個權限,地圖加載不出來 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" > </uses-permission> <!-- 使用GPS需要的權限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 添加屏幕支持 android:anyDensity="true" 這個屬性指明應用程序是否包含了能夠適用于任何屏幕密度的資源。 對于支持Android1.6(API Level 4)和更高版本的應用程序,這個屬性的默認值是true, 并且除非絕對的確認這是應用程序正常工作所必須的,否則不應該把它設置為false。 只是在應用程序直接操作位圖時才需要禁止這個屬性。 android:largeScreens="true" 這個屬性用于指示應用程序是否支持較大外形的屏幕。 一個large類型的屏幕被定義成一個比normal類型的手持設備的屏幕明顯還要大的屏幕, 并且為了讓應用程序能夠良好的使用,使用這個屬性時要特別小心,盡管可以依賴系統來調整尺寸, 以便能夠填充屏幕。 這個屬性的默認值實際上在某些版本之間是不同的,因此最好在任何時候都明確的聲明這個屬性。 如果設置為false,系統會啟用屏幕兼容模式,這時要格外的小心。 android:normalScreens="true" 這個屬性用于指示應用程序是否支持普通外形的屏幕。 典型的是HVGA中等密度的屏幕,但是WQVGA低密度和WVGA高密度屏幕也被認為是普通屏幕。 這個屬性的默認值是true。 android:smallScreens="true" 這個屬性用于指定應用程序是否支持較小外形的屏幕。 一個small類型的屏幕被定義成一個比normal(傳統的HVGA)類型的屏幕還要小的屏幕。 外部服務(如Google Play)不會把不支持小屏的應用程序提供給小屏設備, 因為很少有能夠確保該應用程序在小屏幕的設備上正常工作的平臺。這個屬性的默認值是true。 android:resizeable="true" 這個屬性用于指示針對不同的屏幕尺寸,應用程序是否可以調整尺寸。默認值是true。 --> <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" /> <application android:name="com.home.DemoApplication" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.home.LocationOverlayActivity" android:label="@string/app_name" > <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>
注意:該配置文件與之前的有個區別,多了一個service,它是百度jar包下的一個服務類,這是定位必須要的,不然就不能定位。
Application類同之前一樣。
布局文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <com.home.MyLocationMapView android:id="@+id/bmapView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginTop="80dip" android:background="#D000" android:minWidth="100dip" android:orientation="vertical" android:padding="2dp" > <RadioGroup android:id="@+id/radioGroup" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="定位icon" > <RadioButton android:id="@+id/defaulticon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="默認圖標" > </RadioButton> <RadioButton android:id="@+id/customicon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="自定義圖標" > </RadioButton> </RadioGroup> </LinearLayout> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginRight="25dp" android:layout_marginTop="10dip" android:background="@drawable/custom_loc" /> </RelativeLayout>
custom_text_view.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/popleft" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/popup_side" android:gravity="center" android:text="更新位置" android:textColor="#3814ed" android:textSize="12sp" android:textStyle="bold" /> <LinearLayout android:id="@+id/popinfo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/textcache" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/popup_middle" android:gravity="center" android:textColor="@android:color/black" android:textSize="12sp" android:textStyle="bold" /> <TextView android:id="@+id/popdown" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/popup_down" android:textColor="@android:color/black" android:textSize="12sp" /> </LinearLayout> <TextView android:id="@+id/popright" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/popup_side" android:gravity="center" android:text="更新marker" android:textColor="#3814ed" android:textSize="12sp" android:textStyle="bold" /> </LinearLayout>
附上圖片效果:
來自:http://blog.csdn.net/u010142437/article/details/11577077
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!