[转贴]JAVA 百度地图SDK地图学习——实现定位功能

时间:2022-11-09 21:46:15

之前已经完成了百度地图SDK和百度定位SDK的配置。

http://my.oschina.net/u/1051634/blog/180880

实现百度定位的功能,最好仔细看看官方的文档,看了好几次才有点明白。

开发指南:http://developer.baidu.com/map/geosdk-android-developv3.3.htm

类参考:http://developer.baidu.com/map/geosdk-android-classv3.3.htm

我初步想实现如下功能:点击findme按钮,进入新的activity,即在地图上显示我的位置。

[转贴]JAVA 百度地图SDK地图学习——实现定位功能   [转贴]JAVA 百度地图SDK地图学习——实现定位功能

首先是完成androidManifest.xml的相关设置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.TraceMe">
    <!--<uses-sdk android:minSdkVersion="19"/>-->
    <application
            android:name="com.example.TraceMe.TraceMe"
            android:icon="@drawable/icon"
            android:label="@string/app_name">
        <activity
                android:name="com.example.TraceMe.Activity_Main"
                android:configChanges="orientation"
                android:label="TraceMe"
                android:screenOrientation="sensor" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".Activity_showMyLocation"/>
        <service
                android:name="com.baidu.location.f"
                android:enabled="true"
                android:process=":remote" >
        </service>

</application>

<!--权限设置-->
    <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.ACCESS_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" />

<supports-screens
            android:anyDensity="true"
            android:largeScreens="true"
            android:normalScreens="false"
            android:resizeable="true"
            android:smallScreens="true" />

</manifest>

然后在layout目录下完成相关activtiy的设计

其中百度地图的控件声明如下:

<com.baidu.mapapi.map.MapView android:id="@+id/bmapView"
                                  android:layout_width="fill_parent"
                                  android:layout_height="fill_parent"
                                  android:clickable="true"
                                  android:layout_weight="1"

然后在Activity_showMyLocation中完成定位操作并显示在地图上

package com.example.TraceMe;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.Toast;
import com.baidu.location.BDLocation;
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.*;
import com.baidu.platform.comapi.basestruct.GeoPoint;

/**
 * Created with IntelliJ IDEA.
 * User: mac
 * Date: 12/1/13
 * Time: 5:12 下午
 * To change this template use File | Settings | File Templates.
 */
public class Activity_showMyLocation extends Activity {
    
    private MapView mMapView = null;//MapView 是地图主控件
    private MapController mMapController = null;//用MapController完成地图控制
    MKMapViewListener mMapListener = null;//MKMapViewListener 用于处理地图事件回调

//定位相关
    LocationClient mLocClient;
    LocationData locData = null;
    public MyLocationListenner myListener = new MyLocationListenner();
//定位图层
    locationOverlay myLocationOverlay = null;

//    Button map_FindMe = null;
    boolean isRequest = false;//是否手动触发请求定位
    boolean isFirstLoc = true;//是否首次定位
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);

/**
 * 使用地图sdk前需先初始化BMapManager.
 * BMapManager是全局的,可为多个MapView共用,它需要地图模块创建前创建,
 * 并在地图地图模块销毁后销毁,只要还有地图模块在使用,BMapManager就不应该销毁
 */
        TraceMe app = (TraceMe)this.getApplication();
        if (app.mBMapManager == null) {
            app.mBMapManager = new BMapManager(this);
            app.mBMapManager.init(TraceMe.strKey,new TraceMe.MyGeneralListener());
        }
       mMapView = (MapView)findViewById(R.id.bmapView);
        /**
         * 获取地图控制器
         */
        mMapController = mMapView.getController();
        /**
         *  设置地图是否响应点击事件  .
         */
        mMapController.enableClick(true);
        /**
         * 设置地图缩放级别
         */
        mMapController.setZoom(18);

/**
         *  MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()
         */
        mMapListener = new MKMapViewListener() {
            @Override
            public void onMapMoveFinish() {
                /**
                 * 在此处理地图移动完成回调
                 * 缩放,平移等操作完成后,此回调被触发
                 */
            }

@Override
            public void onClickMapPoi(MapPoi mapPoiInfo) {
                /**
                 * 在此处理底图poi点击事件
                 * 显示底图poi名称并移动至该点
                 * 设置过: mMapController.enableClick(true); 时,此回调才能被触发
                 *
                 */
                String title = "";
                if (mapPoiInfo != null){
                    title = mapPoiInfo.strText;
                    Toast.makeText(Activity_showMyLocation.this, title, Toast.LENGTH_SHORT).show();
                    mMapController.animateTo(mapPoiInfo.geoPt);
                }
            }

@Override
            public void onGetCurrentMap(Bitmap b) {
                /**
                 *  当调用过 mMapView.getCurrentMap()后,此回调会被触发
                 *  可在此保存截图至存储设备
                 */
            }

@Override
            public void onMapAnimationFinish() {
                /**
                 *  地图完成带动画的操作(如: animationTo())后,此回调被触发
                 */
            }
            /**
             * 在此处理地图载完成事件
             */
            @Override
            public void onMapLoadFinish() {
                Toast.makeText(Activity_showMyLocation.this,
                        "地图加载完成",
                        Toast.LENGTH_SHORT).show();

}
        };
        mMapView.regMapViewListener(TraceMe.getInstance().mBMapManager, mMapListener);

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();
    }
//    /**
//     * 修改位置图标
//     * @param marker
//     */
//    public void modifyLocationOverlayIcon(Drawable marker){
//        //当传入marker为null时,使用默认图标绘制
//        myLocationOverlay.setMarker(marker);
//        //修改图层,需要刷新MapView生效
//        mMapView.refresh();
//    }

@Override
    protected void onPause() {
        /**
         *  MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()
         */
        mMapView.onPause();
        super.onPause();
    }

@Override
    protected void onResume() {
        /**
         *  MapView的生命周期与Activity同步,当activity恢复时需调用MapView.onResume()
         */
        mMapView.onResume();
        super.onResume();
    }

@Override
    protected void onDestroy() {
        /**
         *  MapView的生命周期与Activity同步,当activity销毁时需调用MapView.destroy()
         */
        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);
    }

public class locationOverlay extends MyLocationOverlay{

public locationOverlay(MapView mapView) {
            super(mapView);
            // TODO Auto-generated constructor stub
        }

}
    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的方向信息, 如果定位 SDK 未返回方向信息,用户可以自己实现罗盘功能添加方向信息。
            locData.direction = location.getDerect();
            //更新定位数据
            myLocationOverlay.setData(locData);
            //更新图层数据执行刷新后生效
            mMapView.refresh();
            //是手动触发请求或首次定位时,移动到定位点
            if (isRequest || isFirstLoc){
                //移动地图到定位点
//                Log.d("LocationOverlay", "receive location, animate to it");
                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 ;
            }
        }
    }

}