Android 百度地圖的應用

來源:互聯網
上載者:User

最近在搞一個地圖應用,主要也沒什麼技術痛點,主要就是定位,還有就是對應的資訊顯示,這裡就介紹一下百度的地圖應用吧,有興趣的同學可以看一下百度API Android開發裡面的例子,裡面的代碼主要就是寫得有點亂,這裡自己做一下總結。

首先我們來看一下:如下


要實現如這樣的效果,接下來我們一步一步來實現:

首先要註冊百度服務,這個我就不說了,大家可以百度一下,網上有很多的。

http://developer.baidu.com/map/sdk-android.htm

接下來下載百度Android SDK

http://developer.baidu.com/map/sdkandev-download.htm

我們下載Android SDKv2.1.1這個包

直接解壓BaiduMap_AndroidSDK_v2.1.1_Sample.zip這個壓縮包,把包裡的libs目錄下的所有檔案都拷到我們自己的工程的libs裡

這裡麵包含了定位跟地圖調用的方法。接下來就是給我們的工程加入一些許可權。(許可權不知道在哪設?Oh,my God)

那好吧,我來說一下吧,把Sample工程裡的AndroidManifest.xml中的

    <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" />    <permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >    </permission>    <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >    </uses-permission>    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >    </uses-permission>    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >    </uses-permission>    <uses-permission android:name="android.permission.INTERNET" >    </uses-permission>    <uses-permission android:name="android.permission.ACCES_MOCK_LOCATION" >    </uses-permission>    <!-- <uses-permission android:name="android.permission.WRITE_APN_SETTINGS"></uses-permission> -->    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >    </uses-permission>    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />    <uses-permission android:name="android.permission.WAKE_LOCK" >    </uses-permission>    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />    <uses-permission android:name="android.permission.ACCESS_GPS" />    <uses-permission android:name="android.permission.READ_PHONE_STATE" />    <uses-permission android:name="android.permission.READ_CONTACTS" />    <uses-permission android:name="android.permission.CALL_PHONE" />    <uses-permission android:name="android.permission.READ_SMS" />    <uses-permission android:name="android.permission.SEND_SMS" />    <!-- SDK1.5需要android.permission.GET_TASKS許可權判斷本程式是否為當前啟動並執行應用? -->    <uses-permission android:name="android.permission.GET_TASKS" />    <uses-permission android:name="android.permission.CAMERA" >    </uses-permission>    <uses-permission android:name="android.permission.RECORD_AUDIO" >    </uses-permission>    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >    </uses-permission>    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />    <uses-permission android:name="android.permission.BROADCAST_STICKY" />    <uses-permission android:name="android.permission.WRITE_SETTINGS" />    <!-- 來電消音 -->    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" >    </uses-permission>    <uses-permission android:name="android.permission.READ_PHONE_STATE" />    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

都拷到我們自己的AndroidManifest.xml中。(拷貝,粘貼總會了吧)

如果要用到定位服務的話,還要把

<service            android:name="com.baidu.location.f"            android:enabled="true"            android:process=":remote" > </service>

這個服務加上,開始的時候沒注意,老是定位不到自己所處的方位,加上這個就OK了,百度這方面做得還是不錯的。定位精度也不錯。

好了,都加好了,接下來就是編碼了

首先要定義一個主要的程式運行環境,這裡Demo裡有一個DemoApplication.java,這個類繼承了Application,一般寫程式都會在程式啟動的時候載入一些資料或配置,都可以寫在這個類裡,而且這個類作為程式的主運行類,只要程式不退出,這個類是不會被銷毀的,所以可以把一些全域的方法也寫在這個類裡。

    private static DemoApplication mInstance = null; //單例    public boolean m_bKeyRight = true;    BMapManager mBMapManager = null;    public static final String strKey = "請輸入你的key";@Override    public void onCreate() {    super.onCreate();mInstance = this;initEngineManager(this); //初始化百度引擎}@Override//建議在您app的退出之前調用mapadpi的destroy()函數,避免重複初始化帶來的時間消耗public void onTerminate() {// TODO Auto-generated method stub    if (mBMapManager != null) {            mBMapManager.destroy();            mBMapManager = null;        }super.onTerminate();}public void initEngineManager(Context context) {        if (mBMapManager == null) {            mBMapManager = new BMapManager(context);        }        if (!mBMapManager.init(strKey,new MyGeneralListener())) {            Toast.makeText(DemoApplication.getInstance().getApplicationContext(),                     "BMapManager  初始化錯誤!", Toast.LENGTH_LONG).show();        }}public static DemoApplication getInstance() {return mInstance;}// 常用事件監聽,用來處理通常的網路錯誤,授權驗證錯誤等    static class MyGeneralListener implements MKGeneralListener {                @Override        public void onGetNetworkState(int iError) {            if (iError == MKEvent.ERROR_NETWORK_CONNECT) {                Toast.makeText(DemoApplication.getInstance().getApplicationContext(), "您的網路出錯啦!",                    Toast.LENGTH_LONG).show();            }            else if (iError == MKEvent.ERROR_NETWORK_DATA) {                Toast.makeText(DemoApplication.getInstance().getApplicationContext(), "輸入正確的檢索條件!",                        Toast.LENGTH_LONG).show();            }            // ...        }        @Override        public void onGetPermissionState(int iError) {            if (iError ==  MKEvent.ERROR_PERMISSION_DENIED) {                //授權Key錯誤:                Toast.makeText(DemoApplication.getInstance().getApplicationContext(),                         "請在 DemoApplication.java檔案輸入正確的授權Key!", Toast.LENGTH_LONG).show();                DemoApplication.getInstance().m_bKeyRight = false;            }        }    }

這裡DemoApplication裡的代碼,不多,我們可以將代碼拷貝到我們自己的Application裡,我們也可以把我們的定位程式寫在這裡,這樣我們程式一啟動,就可以定位到我們的位置。(如果再進一步,啟動的時候就開啟一個Service,就可以不停地把我們的座標發送到我們自己的伺服器了,這樣你的一舉一動就都在伺服器記錄了)呵呵,這是後話,當然,我個人是不建議這樣做的。

接下來就是百度地圖Activity了

這裡百度地圖Activity就是繼承了普通的Activity,這裡需要說一下的是,現在Google建議開發程式的時候盡量用Fragment,但我試了老半天,也沒辦法把百度Activity放入Fragment,可能是我的水平還有限,呵呵,如果可以將百度地圖做為一個Fragment的話,那就可以更靈活地使用百度地圖了。希望百度地圖在以後能改進,Google地圖倒是用的Fragment。這個我們以後再說。

在Activity的onCreate裡

        DemoApplication app = (DemoApplication)this.getApplication();        if (app.mBMapManager == null) {            app.mBMapManager = new BMapManager(this);            app.mBMapManager.init(DemoApplication.strKey,new DemoApplication.MyGeneralListener());        }        setContentView(R.layout.activity_itemizedoverlay);        // 取得地圖控制項        mMapView = (MapView) findViewById(R.id.bmapView);        mMapView.setLongClickable(true);        //設定地圖顯示放大縮小控制項        mMapView.setBuiltInZoomControls(true);        // 取得地圖控制器        mMapController=mMapView.getController();        // 設定地圖中心        mMapController.setCenter(INIT_POINT);         // INIT_POINT = new GeoPoint((int) (31.57942800 * 1e6), (int) (120.30795300 * 1e6));    //這裡初始化了顯示中心,一啟動就以當前位置為中心顯示地圖        //設定地圖顯示層級,一般13,14就是顯示道路名稱了        mMapController.setZoom(14);        //地圖可以單擊        mMapController.enableClick(true);

這樣基本地圖就能顯示出來了,接下來要加入圖層,其實地圖上顯示的資訊都是往地圖層上加圖層,也不是特別深奧的知識。

這裡我們盡量用非同步來計算座標,載入圖層。

        /** * 將資訊加入圖層 *  * @param list * @return */private Overlay getOverlay(List<Info> list) {// 標記圖片Drawable dr = getResources().getDrawable(R.drawable.icon_marka);Overlay ov = new Overlay(dr, this);int lat, lon;Info item;for (Info info : list) {lat = (int) (info.getLat() * 1e6);lon = (int) (info.getLon() * 1e6);item = new InfoItem(new GeoPoint(lat, lon),info.getName(), info.getAddress(),info.getsex(),info.getNum());item.setMarker(dr);ov.addItem(item);}return ov;}

這裡將從網路擷取的列錶轉換成Overlay層,然後將擷取的層加入mapView中

mMapView.getOverlays().add(overlay);

這個層類在這裡給出

static class Overlay extends ItemizedOverlay<InfoItem> {public List<InfoItem> mGeoList = new ArrayList<InfoItem>();private Context mContext = null;static PopupOverlay pop = null;private View popView = null;private InfoItem mItem;private Bitmap map;static class ItemView { // 自訂控制項集合public TextView NameTextView;public TextView SexTextView;public TextView NumTextView;public TextView AddressTextView;} public Overlay(Drawable marker, Context context) {super(marker);this.mContext = context;pop = new PopupOverlay(BaiduMap.mMapView, new PopupClickListener() {@Overridepublic void onClickedPopup(int index) {}});populate();} //表徵圖單擊事件protected boolean onTap(int index) {mOverlayItem = mGeoList.get(index);ItemView item = null;if (popView == null) {popView = LayoutInflater.from(mContext).inflate(R.layout.popup_view, null);// 擷取要轉換的View資源item = new ItemView();item.TitleTextView = (TextView) popView.findViewById(R.id.pop_title);item.TotalNumTextView = (TextView) popView.findViewById(R.id.pop_num);item.CurrentNumTextView = (TextView) popView.findViewById(R.id.pop_leftnum);item.AddressTextView = (TextView) popView.findViewById(R.id.pop_address);popView.setTag(item);} else {item = (ItemView) popView.getTag();}item.NameTextView.setText(mItem.getName());// 將每個點的Title在彈窗中以文本形式顯示出來item.SexTextView.setText(mItem.getSex());item.NumTextView.setText(mItem.getNum());item.AddressTextView.setText(mItem.getSnippet());//圖片大小,將View轉換成Bitmapmap = convertViewToBitmap(popView, 300, 200);// 顯示poppop.showPopup(map, mGeoList.get(index).getPoint(), 32);map.recycle();  //回收資源map = null;return true;}public boolean onTap(GeoPoint pt, MapView mapView) {if (pop != null) {pop.hidePop();}super.onTap(pt, mapView);return false;}@Overrideprotected InfoItem createItem(int i) {return mGeoList.get(i);}@Overridepublic int size() {return mGeoList.size();}public void addItem(InfoItem item) {mGeoList.add(item);populate();}public void removeItem(int index) {mGeoList.remove(index);populate();}}/** * 把View繪製到Bitmap上 *  * @param view *            需要繪製的View * @param width *            該View的寬度 * @param height *            該View的高度 * @return 返回Bitmap對象 */public static Bitmap convertViewToBitmap(View view, int width, int height) {int widthSpec = View.MeasureSpec.makeMeasureSpec(width,View.MeasureSpec.EXACTLY);int heightSpec = View.MeasureSpec.makeMeasureSpec(height,View.MeasureSpec.EXACTLY);view.measure(widthSpec, heightSpec);view.layout(0, 0, width, height);// Bitmap bitmap = Bitmap.createBitmap(width, height,// Bitmap.Config.ARGB_8888);// Canvas canvas = new Canvas(bitmap);// view.draw(canvas);view.clearFocus();view.setPressed(false);boolean willNotCache = view.willNotCacheDrawing();view.setWillNotCacheDrawing(false);// Reset the drawing cache background color to fully transparent// for the duration of this operationint color = view.getDrawingCacheBackgroundColor();view.setDrawingCacheBackgroundColor(0);if (color != 0) {view.destroyDrawingCache();}view.buildDrawingCache();Bitmap cacheBitmap = view.getDrawingCache();if (cacheBitmap == null) {Log.e(TAG, "failed getViewBitmap(" + view + ")",new RuntimeException());return null;}Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);// Restore the viewview.destroyDrawingCache();view.setWillNotCacheDrawing(willNotCache);view.setDrawingCacheBackgroundColor(color);return bitmap;}

這裡要注意的是百度的PopupOverlay只能顯示Bitmap,所以我們要把View轉換成Bitmap,Bitmap使用完以後要及時回收,如果圖片多的話會造成out of memory的異常。

現在應該就可以顯示如上的效果了,源碼因為是客戶的,所以沒辦法給出,但如果有什麼問題的話,可以給我留言。謝謝。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.