編輯:Android開發實例
闡述一個概念,地圖覆蓋物:所有疊加或覆蓋到地圖的內容,我們統稱為地圖覆蓋物。如標注、矢量圖形元素(包括:折線和多邊形和圓)、定位圖標等。覆蓋物擁有自己的地理坐標,當您拖動或縮放地圖時,它們會相應的移動。
要實現的需求:假如我們知道北京天安門(建築物)的GPS緯度經度值:39.915,116.404,想要把它在百度地圖上標注出來。
實現上述需求的步驟:
一、准備工作:
1、創建android工程,並導入百度地圖需要用到的jar包和so文件。
2、在AndroidManifest文件中添加使用百度地圖SDK所需的權限及屏幕配置。
3、在布局文件layout中添加顯示百度地圖的MapView。
4、在繼承了Activity類的子類中:
a. 創建並初始化地圖引擎管理對象;
b. 通過組件ID獲取代表地圖顯示View的MapView對象,並設置相應屬性。
(比如:啟用內置的縮放控件、設置允許的地圖縮放級別等)
c. 重寫Activity的生命周期回調方法onResume()、onPause()和onDestroy(),管理地圖引擎管理類對象和顯示對象生命周期。
5、詳細的請閱讀上一篇:Android 百度地圖SDK (v2.0.0)初探
二、在地圖上標注出北京天安門:
1、想要在地圖上標注一個建築物,總得有一個標識吧?
獲取在地圖上標識建築物的圖標對象:
// 獲取用於在地圖上標注一個地理坐標點的圖標 Drawable drawable = this.getResources().getDrawable(R.drawable.icon_marka);
2、在基礎圖上添加覆蓋物(添加圖層)
a. 編寫覆蓋物類,自己定義一個類,繼承自ItemizedOverlay<OverlayItem>類,需要重寫父類的構造函數、createItem(int index)和size()方法。
注:從2.0.0開始,SDK不支持直接繼承Overlay , 用戶可通過繼承ItemizedOverlay來添加覆蓋物。
b. 在自定義的覆蓋物類(繼承自ItemizedOverlay<OverlayItem>)中, 聲明一個用於存放覆蓋物的集合:
- /**覆蓋物列表集合*/
- private ArrayList<OverlayItem> mOverlayList = new ArrayList<OverlayItem>();
聲明double類型的變量存儲北京天安門的緯度、經度值:
- // 聲明double類型的變量存儲北京天安門的緯度、經度值
- private double mLat1 = 39.915; // point1緯度
- private double mLon1 = 116.404; // point1經度
c. 在構造函數中,將GPS緯度經度值轉換成以微度的整數形式存儲的地理坐標點
- /* 注:GeoPoint對象構造方法的參數列表:第一個是參數表示緯度,第二個是經度
- (我們平時都是經緯度這麼叫的,想著應該是經度在前的,呵呵。)
- 在網上查了下,GPS的值官方給的就是緯度經度,也就是說緯度是在前的,以前一直沒太注意。*/
- GeoPoint geoPoint1 = new GeoPoint((int) (mLat1 * 1E6), (int) (mLon1 * 1E6));
構造OverlayItem對象並添加到mOverlayList集合裡
- mOverlayList.add(new OverlayItem(geoPoint1, "point1", "point1"));
必須調用的方法:
- /*
- * 官方的解釋:在一個新ItemizedOverlay上執行所有操作的工具方法。
- * 沒搞明白啥意思,但是必須的調用這個方法,否則程序運行報錯*/
- populate();
d. 返回的是從指定List集合中,取出的一個OverlayItem對象。
- /*
- * 返回的是從指定List集合中,取出的一個OverlayItem對象。
- * mOverlayList集合裡一旦有了數據,在調用其之前,
- * 一定的在MyOverlayItem的構造函數裡調用這個方法populate();
- */
- @Override
- protected OverlayItem createItem(int index) {
- return mOverlayList.get(index);
- }
e. 獲取當前覆蓋物列表的大小
- @Override
- public int size() {
- return mOverlayList.size();
- }
自定義的覆蓋物類的完整代碼:
- /**
- * 包含了一個覆蓋物列表的覆蓋物類
- * @author android_ls
- */
- final class MyOverlayItem extends ItemizedOverlay<OverlayItem> {
- /**覆蓋物列表集合*/
- private ArrayList<OverlayItem> mOverlayList = new ArrayList<OverlayItem>();
- // 聲明double類型的變量存儲北京天安門的緯度、經度值
- private double mLat1 = 39.915; // point1緯度
- private double mLon1 = 116.404; // point1經度
- // 傳進來的Drawable對象用於在地圖上標注一個地理坐標點
- public MyOverlayItem(Drawable drawable) {
- super(drawable);
- // 將GPS緯度經度值轉換成以微度的整數形式存儲的地理坐標點
- /* 注:GeoPoint對象構造方法的參數列表:第一個是參數表示緯度,第二個是經度
- (我們平時都是經緯度這麼叫的,想著應該是經度在前的,呵呵。)
- 在網上查了下,GPS的值官方給的就是緯度經度,也就是說緯度是在前的,以前一直沒太注意。*/
- GeoPoint geoPoint1 = new GeoPoint((int) (mLat1 * 1E6), (int) (mLon1 * 1E6));
- // 構造OverlayItem對象並添加到mOverlayList集合裡
- mOverlayList.add(new OverlayItem(geoPoint1, "point1", "point1"));
- /*
- * 官方的解釋:在一個新ItemizedOverlay上執行所有操作的工具方法。
- * 沒搞明白啥意思,但是必須的調用這個方法,否則程序運行報錯*/
- populate();
- }
- /*
- * 返回的是從指定List集合中,取出的一個OverlayItem對象。
- * mOverlayList集合裡一旦有了數據,在調用其之前,
- * 一定的在MyOverlayItem的構造函數裡調用這個方法populate();
- */
- @Override
- protected OverlayItem createItem(int index) {
- return mOverlayList.get(index);
- }
- @Override
- public int size() {
- return mOverlayList.size();
- }
- }
創建覆蓋物(MyOverlayItem)對象並添加到覆蓋物列表中:
- mMapView.getOverlays().add(new MyOverlayItem(drawable));
3、刷新地圖
- mMapView.refresh();
運行效果圖如下:
完整代碼:
- package com.android.baidu.map;
- import java.util.ArrayList;
- import android.app.Activity;
- import android.graphics.drawable.Drawable;
- import android.os.Bundle;
- import android.widget.Toast;
- import com.baidu.mapapi.BMapManager;
- import com.baidu.mapapi.MKGeneralListener;
- import com.baidu.mapapi.map.ItemizedOverlay;
- import com.baidu.mapapi.map.MKEvent;
- import com.baidu.mapapi.map.MapController;
- import com.baidu.mapapi.map.MapView;
- import com.baidu.mapapi.map.OverlayItem;
- import com.baidu.platform.comapi.basestruct.GeoPoint;
- /**
- * 在地圖上標注已知GPS緯度經度值的建築物
- * 場景:假如我們知道北京天安門(建築物)的GPS緯度經度值:39.915,116.404,想要把它在地圖上標注出來。
- * @author android_ls
- *
- */
- public class BaiduMapOverlayActivity extends Activity {
- /**地圖引擎管理類*/
- private BMapManager mBMapManager = null;
- /**顯示地圖的View*/
- private MapView mMapView = null;
- /**
- * 經研究發現在申請KEY時:應用名稱一定要寫成my_app_應用名(也就是說"my_app_"是必須要有的)。
- * 百度地圖SDK提供的服務是免費的,接口無使用次數限制。您需先申請密鑰(key),才可使用該套SDK。
- * */
- public static final String BAIDU_MAP_KEY = "07418AEC69BAAB7104C6230A6120C580DFFAEEBB";
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 注意:請在調用setContentView前初始化BMapManager對象,否則會報錯
- mBMapManager = new BMapManager(this.getApplicationContext());
- mBMapManager.init(BAIDU_MAP_KEY, new MKGeneralListener() {
- @Override
- public void onGetNetworkState(int iError) {
- if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
- Toast.makeText(BaiduMapOverlayActivity.this.getApplicationContext(),
- "您的網絡出錯啦!",
- Toast.LENGTH_LONG).show();
- }
- }
- @Override
- public void onGetPermissionState(int iError) {
- if (iError == MKEvent.ERROR_PERMISSION_DENIED) {
- // 授權Key錯誤:
- Toast.makeText(BaiduMapOverlayActivity.this.getApplicationContext(),
- "請在 DemoApplication.java文件輸入正確的授權Key!",
- Toast.LENGTH_LONG).show();
- }
- }
- });
- setContentView(R.layout.main);
- mMapView = (MapView) this.findViewById(R.id.bmapsView);
- // 設置啟用內置的縮放控件
- mMapView.setBuiltInZoomControls(true);
- // 獲取地圖控制器,可以用它控制平移和縮放
- MapController mMapController = mMapView.getController();
- // 設置地圖的縮放級別。 這個值的取值范圍是[3,18]。
- mMapController.setZoom(13);
- // 獲取用於在地圖上標注一個地理坐標點的圖標
- Drawable drawable = this.getResources().getDrawable(R.drawable.icon_marka);
- // 創建覆蓋物(MyOverlayItem)對象並添加到覆蓋物列表中
- mMapView.getOverlays().add(new MyOverlayItem(drawable));
- // 刷新地圖
- mMapView.refresh();
- }
- /**
- * 包含了一個覆蓋物列表的覆蓋物類
- * @author android_ls
- */
- final class MyOverlayItem extends ItemizedOverlay<OverlayItem> {
- /**覆蓋物列表集合*/
- private ArrayList<OverlayItem> mOverlayList = new ArrayList<OverlayItem>();
- // 聲明double類型的變量存儲北京天安門的緯度、經度值
- private double mLat1 = 39.915; // point1緯度
- private double mLon1 = 116.404; // point1經度
- // 傳進來的Drawable對象用於在地圖上標注一個地理坐標點
- public MyOverlayItem(Drawable drawable) {
- super(drawable);
- // 將GPS緯度經度值轉換成以微度的整數形式存儲的地理坐標點
- /* 注:GeoPoint對象構造方法的參數列表:第一個是參數表示緯度,
- * 第二個是經度(我們平時都是經緯度這麼叫的,想著應該是經度在前的,呵呵。)
- * 在網上查了下,GPS的值官方給的就是緯度經度,也就是說緯度是在前的,以前一直沒太注意。*/
- GeoPoint geoPoint1 = new GeoPoint(
- (int) (mLat1 * 1E6),
- (int) (mLon1 * 1E6));
- // 構造OverlayItem對象並添加到mOverlayList集合裡
- mOverlayList.add(new OverlayItem(geoPoint1, "point1", "point1"));
- /*
- * 官方的解釋:在一個新ItemizedOverlay上執行所有操作的工具方法。
- * 沒搞明白啥意思,但是必須的調用這個方法,否則程序運行報錯*/
- populate();
- }
- /*
- * 返回的是從指定List集合中,取出的一個OverlayItem對象。
- * mOverlayList集合裡一旦有了數據,在調用其之前,
- * 一定的在MyOverlayItem的構造函數裡調用這個方法populate();
- */
- @Override
- protected OverlayItem createItem(int index) {
- return mOverlayList.get(index);
- }
- @Override
- public int size() {
- return mOverlayList.size();
- }
- }
- // 重寫以下方法,管理API
- @Override
- protected void onResume() {
- mMapView.onResume();
- if (mBMapManager != null) {
- mBMapManager.start();
- }
- super.onResume();
- }
- @Override
- protected void onPause() {
- mMapView.onPause();
- if (mBMapManager != null) {
- mBMapManager.stop();
- }
- super.onPause();
- }
- @Override
- protected void onDestroy() {
- mMapView.destroy();
- if (mBMapManager != null) {
- mBMapManager.destroy();
- mBMapManager = null;
- }
- super.onDestroy();
- }
- }
三、在地圖上標注出北京天安門附近的幾個點:
從2.0.0開始,SDK不支持直接繼承Overlay 。 在地圖上顯示一個或一組覆蓋物,都可以通過繼承ItemizedOverlay來添加覆蓋物。
在上面講解的基礎上,修改覆蓋物類的部分代碼就可以了。直接上代碼:
- class MyOverlayItem extends ItemizedOverlay<OverlayItem> {
- /**覆蓋物列表集合*/
- private ArrayList<OverlayItem> mOverlayList = new ArrayList<OverlayItem>();
- // 場景:假如我們有一組建築物的GPS經緯度值,想要把這些建築物在地圖上標注出來。
- private double mLat1 = 39.90923; // point1緯度
- private double mLon1 = 116.397428; // point1經度
- private double mLat2 = 39.9022;// point2緯度
- private double mLon2 = 116.3922; // point2經度
- private double mLat3 = 39.917723; // point3緯度
- private double mLon3 = 116.3722; // point3緯度
- private double mLat4 = 39.915; // point4緯度
- private double mLon4 = 116.404; // point4經度
- // 傳進來的Drawable對象用於在地圖上標注一個地理坐標點
- public MyOverlayItem(Drawable drawable) {
- super(drawable);
- // 將GPS緯度經度值轉換成以微度的整數形式存儲的地理坐標點
- /* 注:GeoPoint對象構造方法的參數列表:第一個是參數表示緯度,第二個是經度
- (我們平時都是經緯度這麼叫的,想著應該是經度在前的,呵呵。)
- 在網上查了下,GPS的值官方給的就是緯度經度,也就是說緯度是在前的,以前一直沒太注意。*/
- GeoPoint geoPoint1 = new GeoPoint((int) (mLat1 * 1E6), (int) (mLon1 * 1E6));
- GeoPoint geoPoint2 = new GeoPoint((int) (mLat2 * 1E6), (int) (mLon2 * 1E6));
- GeoPoint geoPoint3 = new GeoPoint((int) (mLat3 * 1E6), (int) (mLon3 * 1E6));
- GeoPoint geoPoint4 = new GeoPoint((int) (mLat4 * 1E6), (int) (mLon4 * 1E6));
- // 構造OverlayItem對象並添加到mOverlayList集合裡
- mOverlayList.add(new OverlayItem(geoPoint1, "point1", "point1"));
- mOverlayList.add(new OverlayItem(geoPoint2, "point2", "point2"));
- mOverlayList.add(new OverlayItem(geoPoint3, "point3", "point3"));
- mOverlayList.add(new OverlayItem(geoPoint4, "point4", "point4"));
- // 必須的調用這個方法,否則程序運行報錯
- populate();
- }
- /*
- * 返回的是從指定List集合中,取出的一個OverlayItem對象。
- * mOverlayList集合裡一旦有了數據,在調用其之前,
- * 一定的在MyOverlayItem的構造函數裡調用這個方法populate();
- */
- @Override
- protected OverlayItem createItem(int index) {
- return mOverlayList.get(index);
- }
- @Override
- public int size() {
- return mOverlayList.size();
- }
- }
對代碼進行優化:
GPSPonit 實體類:
- package com.android.baidu.map.entity;
- /**
- * 類名: Ponit.java
- * 功能描述:存放GPS緯度、經度值
- * @author android_ls
- * 創建日期: 2013-2-10 下午07:43:47
- * @version V1.0
- */
- public class GPSPonit {
- private double mLat; // 緯度
- private double mLon; // 經度
- public double getmLat() {
- return mLat;
- }
- public void setmLat(double mLat) {
- this.mLat = mLat;
- }
- public double getmLon() {
- return mLon;
- }
- public void setmLon(double mLon) {
- this.mLon = mLon;
- }
- public GPSPonit(double mLat, double mLon) {
- this.mLat = mLat;
- this.mLon = mLon;
- }
- public GPSPonit() {
- }
- @Override
- public String toString() {
- return "Ponit [mLat=" + mLat + ", mLon=" + mLon + "]";
- }
- }
優化後的Activity類:
- package com.android.baidu.map;
- import java.util.ArrayList;
- import android.app.Activity;
- import android.graphics.drawable.Drawable;
- import android.os.Bundle;
- import android.widget.Toast;
- import com.android.baidu.map.entity.GPSPonit;
- import com.baidu.mapapi.BMapManager;
- import com.baidu.mapapi.MKGeneralListener;
- import com.baidu.mapapi.map.ItemizedOverlay;
- import com.baidu.mapapi.map.MKEvent;
- import com.baidu.mapapi.map.MapController;
- import com.baidu.mapapi.map.MapView;
- import com.baidu.mapapi.map.OverlayItem;
- import com.baidu.platform.comapi.basestruct.GeoPoint;
- /**
- * 在地圖上標注已知GPS緯度經度值的一組建築物
- * @author android_ls
- *
- */
- public class BaiduMapOverlayItemsActivity extends Activity {
- /**地圖引擎管理類*/
- private BMapManager mBMapManager = null;
- /**顯示地圖的View*/
- private MapView mMapView = null;
- /**
- * 經研究發現在申請KEY時:應用名稱一定要寫成my_app_應用名(也就是說"my_app_"是必須要有的)。
- * 百度地圖SDK提供的服務是免費的,接口無使用次數限制。您需先申請密鑰(key),才可使用該套SDK。
- * */
- public static final String BAIDU_MAP_KEY = "07418AEC69BAAB7104C6230A6120C580DFFAEEBB";
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 注意:請在調用setContentView前初始化BMapManager對象,否則會報錯
- mBMapManager = new BMapManager(this.getApplicationContext());
- mBMapManager.init(BAIDU_MAP_KEY, new MKGeneralListener() {
- @Override
- public void onGetNetworkState(int iError) {
- if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
- Toast.makeText(BaiduMapOverlayItemsActivity.this.getApplicationContext(),
- "您的網絡出錯啦!",
- Toast.LENGTH_LONG).show();
- }
- }
- @Override
- public void onGetPermissionState(int iError) {
- if (iError == MKEvent.ERROR_PERMISSION_DENIED) {
- // 授權Key錯誤:
- Toast.makeText(BaiduMapOverlayItemsActivity.this.getApplicationContext(),
- "請在 DemoApplication.java文件輸入正確的授權Key!",
- Toast.LENGTH_LONG).show();
- }
- }
- });
- setContentView(R.layout.main);
- mMapView = (MapView) this.findViewById(R.id.bmapsView);
- // 設置啟用內置的縮放控件
- mMapView.setBuiltInZoomControls(true);
- // 獲取地圖控制器,可以用它控制平移和縮放
- MapController mMapController = mMapView.getController();
- // 設置地圖的縮放級別。 這個值的取值范圍是[3,18]。
- mMapController.setZoom(13);
- //TODO 構建一組數據
- GPSPonit gp1 = new GPSPonit(39.90923, 116.397428);
- GPSPonit gp2 = new GPSPonit(39.9022, 116.3922);
- GPSPonit gp3 = new GPSPonit(39.917723, 116.3722);
- GPSPonit gp4 = new GPSPonit(39.915, 116.404);
- /**存放GPS緯度、經度值的數組*/
- GPSPonit[] mGPSPonit = new GPSPonit[4];
- mGPSPonit[0] = gp1;
- mGPSPonit[1] = gp2;
- mGPSPonit[2] = gp3;
- mGPSPonit[3] = gp4;
- Drawable drawable = this.getResources().getDrawable(R.drawable.icon_marka);
- // 創建覆蓋物(MyOverlayItem)對象並添加到覆蓋物列表中
- mMapView.getOverlays().add(new MyOverlayItem(drawable, mGPSPonit));
- // 刷新地圖
- mMapView.refresh();
- }
- final class MyOverlayItem extends ItemizedOverlay<OverlayItem> {
- /**覆蓋物列表集合*/
- private ArrayList<OverlayItem> mOverlayList = new ArrayList<OverlayItem>();
- // 場景:假如我們有一組建築物的GPS經緯度值,想要把這些建築物在地圖上標注出來。
- // 傳進來的Drawable對象用於在地圖上標注一個地理坐標點
- public MyOverlayItem(Drawable drawable, GPSPonit[] gPSPonit) {
- super(drawable);
- for(int i = 0; i < gPSPonit.length; i++){
- GPSPonit gpp = gPSPonit[i];
- GeoPoint geoPoint = new GeoPoint(
- (int) (gpp.getmLat() * 1E6),
- (int) (gpp.getmLon() * 1E6));
- mOverlayList.add(new OverlayItem(geoPoint, "point"+i, "point1"+i));
- }
- // 必須的調用這個方法,否則程序運行報錯
- populate();
- }
- /*
- * 返回的是從指定List集合中,取出的一個OverlayItem對象。
- * mOverlayList集合裡一旦有了數據,在調用其之前,
- * 一定的在MyOverlayItem的構造函數裡調用這個方法populate();
- */
- @Override
- protected OverlayItem createItem(int index) {
- return mOverlayList.get(index);
- }
- @Override
- public int size() {
- return mOverlayList.size();
- }
- }
- // 重寫以下方法,管理API
- @Override
- protected void onResume() {
- mMapView.onResume();
- if (mBMapManager != null) {
- mBMapManager.start();
- }
- super.onResume();
- }
- @Override
- protected void onPause() {
- mMapView.onPause();
- if (mBMapManager != null) {
- mBMapManager.stop();
- }
- super.onPause();
- }
- @Override
- protected void onDestroy() {
- mMapView.destroy();
- if (mBMapManager != null) {
- mBMapManager.destroy();
- mBMapManager = null;
- }
- super.onDestroy();
- }
- }
運行效果圖如下:
轉自:http://blog.csdn.net/android_ls/article/details/8578044
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩
大家好,眾所周知,android裡兩個相同方向的ScrollView是不能嵌套的,那要是有這樣的需求怎麼辦?(這個需求一般都是不懂android的人提出來的)難道
Android UI缺省的標題欄由android:label 定義,顯示在屏幕
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放