使用高德地图MapView

本文详细介绍了如何在Android应用中使用高德地图MapView,包括在Activity和Fragment中的集成,以及路径规划的实现。重点讨论了初始化地图时的常见问题,如定位、精度圈和缩放按钮的隐藏,自定义定位按钮的实现,以及在PopupWindow中防止地图穿透的问题。此外,还讲解了如何绘制路径、更新marker位置,以及模拟司机沿规划路线移动的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

跳过导入高德地图,导入包,直接到使用

一、在Activity中使用

1、在布局中使用mapview

<com.amap.api.maps.MapView
        android:id="@+id/amapView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="#fff"
        android:clickable="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/estimate_payment" />

2、在Actvity中初始化地图
遇到过的问题:
(1)没有在onCreate中调用MapView.onCreate,导致地图是空白
(2)onPause里使用了MapView.OnPause,onResume里没有使用MapView.OnResume,导致mapview卡住一动不动(移动地图,缩放手势都不起作用)
(3)隐藏精度圈、缩放按钮、自定义定位蓝点(https://lbs.amap.com/api/android-sdk/guide/interaction-with-map/control-interaction)
(4)自定义定位button:因为高德地图没有提供替换定位button的方法,所以需要将原本地图的定位button隐藏,添加自定义的button,点击之后执行定位。(http://lbsbbs.amap.com/forum.php?mod=viewthread&tid=14167)
(5)弹出popupwindow时设置背景变暗,mapView上面重叠部分的view被穿透。低版本上mapView整个就没有变暗。这个问题只要将mapView换成TextureMapView就可以了。官网上有个解释mapView与TextureMapView区别的:mapView是GLSurfaceView,与其他GLSurfaceView叠加会出现穿透现象,不知道我这边的问题是不是同一个原因。虽然TextureMapView效率比MapView低,但是我暂时没有找到更好的解决方法。(https://lbs.amap.com/api/android-sdk/guide/create-map/show-map)
问题图:
在这里插入图片描述
最终效果:
在这里插入图片描述

    @InjectView(R.id.amapView)
    MapView mBmapView;
    //声明AMapLocationClient类对象
    private AMapLocationClient mLocationClient = null;
    //声明AMapLocationClientOption对象
    private AMapLocationClientOption mLocationOption = null;
    private AMap mAmap;
    private static final int MAP_ZOOM_SIZE = 18;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
        mBmapView.onCreate(savedInstanceState);
    }
    
    @Override
    protected void onPause() {
        if (mBmapView != null) {
        //在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
            mBmapView.onPause();
        }
        if (mLocationClient != null) {
            mLocationClient.stopLocation();
        }
        super.onPause();
    }
    
    @Override
    protected void onResume() {
    //在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
        mBmapView.onResume();
        if (mLocationClient != null) {
            mLocationClient.startLocation();
        }
        super.onResume();
    }
    
    @Override
    protected void onDestroy() {
        LogUtils.i("onDestroy");
        clearRouteLines();
        if (mLocationClient != null) {
            mLocationClient.stopLocation();
        }
        if (mBmapView != null) {
        //在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
            mBmapView.onDestroy();
        }
        super.onDestroy();
    }
    
    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
        mBmapView.onSaveInstanceState(outState);
    }

     private void initMap() {
        if (mAmap == null) {
            mAmap = mBmapView.getMap();
        }
        //设置希望展示的地图缩放级别
        CameraUpdate mCameraUpdate = CameraUpdateFactory.zoomTo(MAP_ZOOM_SIZE);
        mAmap.moveCamera(mCameraUpdate);

        //自定义定位蓝点:
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.location_indicator));
        //连续定位、且将视角移动到地图中心点,定位蓝点跟随设备移动。(1秒1次定位)
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
        //设置精度圆圈(隐藏精度圈)
        myLocationStyle.strokeColor(Color.argb(0, 0, 0, 0));
        myLocationStyle.radiusFillColor(Color.argb(0, 0, 0, 0));
        //隐藏高德logo
        mAmap.getUiSettings().setLogoBottomMargin(-60);
        //设置定位蓝点的Style
        mAmap.setMyLocationStyle(myLocationStyle);
        
        //初始化定位
        mLocationClient = new AMapLocationClient(getApplicationContext());
        //设置定位回调监听
        mLocationClient.setLocationListener(this);
        //初始化AMapLocationClientOption对象
        mLocationOption = new AMapLocationClientOption();
        //设置定位模式为AMapLocationMode.Hight_Accuracy,高精度模式。
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //获取最近3s内精度最高的一次定位结果:
        //设置setOnceLocationLatest(boolean b)接口为true,启动定位时SDK会返回最近3s内精度最高的一次定位结果。
        //如果设置其为true,setOnceLocation(boolean b)接口也会被设置为true,反之不会,默认为false。
        mLocationOption.setOnceLocationLatest(true);
        //设置是否返回地址信息(默认返回地址信息)
        mLocationOption.setNeedAddress(true);
        //设置是否允许模拟位置,默认为true,允许模拟位置
        mLocationOption.setMockEnable(false);
        //关闭缓存机制
        mLocationOption.setLocationCacheEnable(false);
        mLocationClient.setLocationOption(mLocationOption);

        // 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false
        mAmap.setMyLocationEnabled(true);
        //隐藏右下角的缩放按钮
        mAmap.getUiSettings().setZoomControlsEnabled(false);
        //设置默认定位按钮不显示,显示自定义定位按钮并设置click事件。
        mAmap.getUiSettings().setMyLocationButtonEnabled(false);
        
        //启动定位
        mLocationClient.startLocation();
    }

隐藏高德地图的定位图标:

//设置默认定位按钮不显示,显示自定义定位按钮并设置click事件。
mAmap.getUiSettings().setMyLocationButtonEnabled(false);

设置图标带阴影的属性elevation(有background才会生效)

    <ImageView
        android:id="@+id/im_location"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_gravity="right"
        android:layout_margin="10dp"
        android:background="@drawable/roadrescue_location_btn_selector"
        android:clickable="true"
        android:elevation="2dp"
        android:scaleType="center"
        android:src="@drawable/location_btn"
        app:layout_constraintRight_toRightOf="parent" />

设置自定义定位图标的点击事件

    @OnClick({R.id.im_location })
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.im_location:
                //自定义定位控件,可以移动到定位点,使用animateCamera就有动画效果,设置希望展示的地图缩放级别
                CameraUpdate mCameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, MAP_ZOOM_SIZE);
                mAmap.moveCamera(mCameraUpdate);
                break;
        }
    }

二、Fragment里的使用

在onCreateView里创建地图,其他和Activity一样

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        mBmapView.onCreate(savedInstanceState);
        return mRootView;
    }

三、路径规划

已知起点(可以通过onLocationChanged获得)和终点(比如滴滴司机的起始位置),首先画出路径,显示用户marker和司机marker。然后通过handler每隔1分钟从服务器获取司机位置的经纬度,创建一个ArrayList 保存司机要smooth的两点,每次获取新的坐标时就remove掉0,add新坐标,通过SmoothMoveMarker让小车从0滑到1,这样就移动了。
1、画路径,画起点和终点marker

    //路线规划
    private RouteSearch mRouteSearch;
    //这个数组的作用是把规划路线的所有坐标点放进去,便于绘制
    private ArrayList<LatLng> latLonArray = new ArrayList<>();
        //小车smooth的路线,存放两个点
    private ArrayList<LatLng> runArray = new ArrayList<>();
    //平滑移动的标记,即小车
    private SmoothMoveMarker smoothMarker;
    
/**
     * 已知司机地址,获取司机起始位置经纬度(用于不知道司机经纬度,知道司机起始地址)和行车时间,先画出一
     * 个路线图,起点终点出来
     * @param cityName
     */
    private void getStoreLatlon(String cityName) {
        LogUtils.i("StoreyName;" + cityName);
        GeocodeSearch geocodeSearch = new GeocodeSearch(this);
        geocodeSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
            @Override
            public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
                
            }
            
            @Override
            public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
                
                if (i == 1000) {
                    if (geocodeResult != null && geocodeResult.getGeocodeAddressList() != null
                            && geocodeResult.getGeocodeAddressList().size() > 0) {
                        
                        GeocodeAddress geocodeAddress = geocodeResult.getGeocodeAddressList().get(0);
                        double latitude = geocodeAddress.getLatLonPoint().getLatitude();//纬度
                        double longititude = geocodeAddress.getLatLonPoint().getLongitude();//经度
                        mStoreLatlng = new LatLng(latitude, longititude);
                        getStoreDriveTime();
                        LogUtils.i("lgq地理编码:" + geocodeAddress.getAdcode() + "");
                        LogUtils.i("lgq纬度latitude:" + latitude + "");
                        LogUtils.i("lgq经度longititude:" + longititude + "");
                    }
                    else {
                        ToastUtil.showMessage(RoadRescueApplyAct.this, "地名出错");
                    }
                }
            }
        });
        
        GeocodeQuery geocodeQuery = new GeocodeQuery(cityName.trim(), "29");
        geocodeSearch.getFromLocationNameAsyn(geocodeQuery);
    }
    
    /**
     *查询司机到用户的路径
     */
    private void getStoreDriveTime() {
        mRouteSearch = new RouteSearch(this);
        mRouteSearch.setRouteSearchListener(this);
        LatLng rescueLatlng = new LatLng(mCurrentRescueOrder.getLat(), mCurrentRescueOrder.getLng());
        RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(convertToLatLonPoint(rescueLatlng),
                convertToLatLonPoint(mStoreLatlng));
        RouteSearch.DriveRouteQuery routeQuery = new RouteSearch.DriveRouteQuery(fromAndTo,
                RouteSearch.DRIVING_SINGLE_AVOID_CONGESTION, null, null, "");
        mRouteSearch.calculateDriveRouteAsyn(routeQuery);
    }

//会走到回调方法,选择onDriveRouteSearched进行处理,driverRouteResult里存放了路径所有经纬度点
@Override
    public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) {
        LogUtils.i("i:" + i);
        if (i == 1000) {
            if (driveRouteResult == null) {
                LogUtils.e("driveResult is null");
            }
            if (!latLonArray.isEmpty()) {
                latLonArray.clear();
            }
            //设置预计等待时间
            LogUtils.i("time:" + driveRouteResult.getPaths().get(0).getDuration());
            mDriveDuration = driveRouteResult.getPaths().get(0).getDuration();
            mDistance = driveRouteResult.getPaths().get(0).getDistance();
            Spanned durationText = Html
                    .fromHtml(getString(R.string.roadrescue_duration, secondsToMinute(mDriveDuration)));
            mTvWaitTime.setText(durationText);
            //设置距离
            Spanned distanceText = Html.fromHtml(getString(R.string.roadrescue_distance, meterToKilometer(mDistance)));
            mTvRescueDistance.setText(distanceText);
            //如果为出工就不画路径图
            if (mCurrentRescueOrder.getStatus() == 1 || mCurrentRescueOrder.getStatus() == 2) {
                return;
            }
            for (DrivePath path : driveRouteResult.getPaths()) {
                for (DriveStep step : path.getSteps()) {
                    for (LatLonPoint point : step.getPolyline()) {
                        latLonArray.add(convertToLatLng(point));
                    }
                }
            }
            //规划路线,画出起点,小车,路线图
            drawingRouteOverlay(latLonArray);
            //将改点作为未来小车要smooth的起点
            if (runArray.size() == 0) {
                runArray.add(mStoreLatlng);
            }
            showCarMarker(mStoreLatlng);
        }
        else {
            LogUtils.e("no route to find");
        }
    }
    
    /**
     * 绘制路线
     * @param drivePath
     */
    private void drawingRouteOverlay(List<LatLng> drivePath) {
        this.startLatLng = drivePath.get(0);
        this.endLatLng = drivePath.get(drivePath.size() - 1);
        polyLineOptions = new PolylineOptions();
        polyLineOptions.width(width);
        polyLineOptions.setCustomTexture(BitmapDescriptorFactory.fromResource(R.drawable.custtexture));
        endBitmap = BitmapDescriptorFactory.fromResource(R.drawable.location_savecar);
        //将客户位置作为起点标记在map上
        addMarkerToMap(drivePath);
        //画路线
        drawLine(drivePath);
    }
    
    /**
     * 将起点终点的marker添加到地图上
     */
    public void addMarkerToMap(List<LatLng> drivePath) {
        try {
            //清除原来的marker
            mAmap.clear();
            //将用户的位置marker添加到地图上
            LatLng rescueLatLng = new LatLng(mCurrentRescueOrder.getLat(), mCurrentRescueOrder.getLng());
            endMarker = mAmap.addMarker(new MarkerOptions().position(rescueLatLng).icon(endBitmap));
        }
        catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
    
    /**
     * 画线
     */
    private void drawLine(List<LatLng> drivePath) {
        try {
            polyLineOptions.addAll(drivePath);
            allPolyLines.add(mAmap.addPolyline(polyLineOptions));
        }
        catch (Throwable e) {
            e.printStackTrace();
        }
    }

    //显示司机所在位置
    private void showCarMarker(LatLng location) {
        zoomToSpan();
        if (rescueCarMarker == null) {
            //如果是空的添加一个新的icon方法就是设置定位图标,可以自定义
            rescueCarMarker = mAmap.addMarker(new MarkerOptions().position(location)
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.savecar)));
        }
        else {
            rescueCarMarker.setPosition(location);
        }
    }
    
    /**
     * 将点始终保持在能看到的位置
     */
    private void zoomToSpan() {
        try {
            LatLngBounds.Builder b = LatLngBounds.builder();
            b.include(new LatLng(startLatLng.latitude, startLatLng.longitude));
            b.include(new LatLng(endLatLng.latitude, endLatLng.longitude));
            LatLngBounds bounds = b.build();
            //就是这个方法把视觉一直控制在大概中间的位置,具体的可以看高德地图API
            mAmap.animateCamera(CameraUpdateFactory.newLatLngBoundsRect(bounds, 100, 100, 100, 450));
        }
        catch (Throwable e) {
            e.printStackTrace();
        }
    }

2、更新司机marker位置

//每隔1分钟从服务器获取司机经纬度
mHandler.sendEmptyMessageDelayed(MSG_UPDATE_RESCUE_CAR_LOCATION,
                                        UPDATE_RESCUE_CAR_LOCATION_INTERNAL);
 private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (runArray == null) {
                return;
            }if (msg.what == MSG_UPDATE_RESCUE_CAR_LOCATION) {
                //获取司机位置
                getRescueCarDistance(mCurrentRescueOrder.getOrderId());
                sendEmptyMessageDelayed(MSG_UPDATE_RESCUE_CAR_LOCATION, UPDATE_RESCUE_CAR_LOCATION_INTERNAL);
            }
        }
    };
    
    /**
     * 获取司机位置并计算距离(已出动)
     * @param orderId
     */
    private void getRescueCarDistance(long orderId) {
        RequestManager2.getServiceInstance()
                .getRescuevehicleLocation(orderId)
                .compose(RequestManager2.<LatLng> setSchedulers())
                .subscribe(new BackgroundSubscriber<LatLng>(RoadRescueApplyAct.this) {
                    @Override
                    public void onSuccess(LatLng latLng) {
                        super.onSuccess(latLng);
                        LogUtils.e("rescuecar,latLng:" + latLng);
                        //获取销售店与用户的距离,时间由地图map来算
                        LatLng rescueLatlng = new LatLng(mCurrentRescueOrder.getLat(), mCurrentRescueOrder.getLng());
                        mDistance = AMapUtils.calculateLineDistance(rescueLatlng, latLng);
                        Spanned distanceText = Html
                                .fromHtml(getString(R.string.roadrescue_distance, meterToKilometer(mDistance)));
                        mTvRescueDistance.setText(distanceText);
                        //添加Marker显示小车位置
                        if (latLng.longitude == 0 || latLng.latitude == 0) {
                            return;
                        }
                        //更新小车位置
                       if (runArray.size() == 1) {
                            //如果runArray里只有一个点,获取小车最新位置后再加一个点
                            runArray.add(latLng);
                        }
                        else if (runArray.size() == 2) {
                        	//如果runArray里已经有两个点,移除第一个点,加入最新的点
                            runArray.remove(0);
                            runArray.add(latLng);
                        }
                        if (smoothMarker != null) {
                            smoothMarker.destroy();
                        }
                        //让小车从runArray 0滑动到1
                        showCarMarkerSmooth();
                    }
                });
    }

	//滑动小车
    private void showCarMarkerSmooth() {
        
        // 获取轨迹坐标点
        zoomToSpan();
        if(rescueCarMarker!=null){
            //移除一开始设置的小车marker
            rescueCarMarker.remove();
        }
        smoothMarker = new SmoothMoveMarker(mAmap);
        // 设置滑动的图标
        smoothMarker.setDescriptor(BitmapDescriptorFactory.fromResource(R.drawable.savecar));
        
        LatLng drivePoint = runArray.get(0);
        Pair<Integer, LatLng> pair = SpatialRelationUtil.calShortestDistancePoint(runArray, drivePoint);
        runArray.set(pair.first, drivePoint);
        List<LatLng> subList = runArray.subList(pair.first, runArray.size());
        
        // 设置滑动的轨迹坐标点
        smoothMarker.setPoints(subList);
        // 设置滑动的总时间60s
        smoothMarker.setTotalDuration(60);
        // 开始滑动
        smoothMarker.startSmoothMove();
    }

但是实际司机的位置数据可能没有,所以我们可以模拟司机运动,数据就从获取的路径的所有经纬度点里面选取,模拟司机一直沿着规划的路线走。定义两个ArrayList,一个是latLonArray存放规划路径的所有点,一个是runArray存放两个点,不断从latLonArray里面取点,模拟更新司机前进。(比如latLongArray里的点是0,1,2,3,4…,runArray更新数据(0,1)(1,2)(2,3)…然后小车marker根据runArray里面的两个点不断往前滑动)

    /**
     * 根据起点和终点的经纬度查询路线
     */
    private void startRouteSearch() {
        LogUtils.e("startRouteSearch");
        mRouteSearch = new RouteSearch(this);
        mRouteSearch.setRouteSearchListener(this);
        RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(mStarPoint, mEndPoint);
        RouteSearch.DriveRouteQuery routeQuery = new RouteSearch.DriveRouteQuery(fromAndTo,
                RouteSearch.DRIVING_SINGLE_AVOID_CONGESTION, null, null, "");
        mRouteSearch.calculateDriveRouteAsyn(routeQuery);
    }
    
    @Override
    public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) {
        LogUtils.i("i:" + i);
        if (i == 1000) {
            if (driveRouteResult == null) {
                LogUtils.e("driveResult is null");
            }
            if (!latLonArray.isEmpty()) {
                latLonArray.clear();
            }
            for (DrivePath path : driveRouteResult.getPaths()) {
                for (DriveStep step : path.getSteps()) {
                    for (LatLonPoint point : step.getPolyline()) {
                        latLonArray.add(convertToLatLng(point));
                    }
                }
            }
            //规划路线,画出起点,小车,路线图
            drawingRouteOverlay(latLonArray);
            runArray.add(latLonArray.get(0));
            runArray.add(latLonArray.get(1));
            showCarMarkerSmooth();
            mHandler.sendEmptyMessage(MSG_UPDATE_CAR);
        }
        else {
            LogUtils.e("no route to find");
        }
    }
    
    private void showCarMarkerSmooth() {
        zoomToSpan();
        smoothMarker = new SmoothMoveMarker(mAmap);
        // 设置滑动的图标
        smoothMarker.setDescriptor(BitmapDescriptorFactory.fromResource(R.drawable.car));
        
        LatLng drivePoint = runArray.get(0);
        Pair<Integer, LatLng> pair = SpatialRelationUtil.calShortestDistancePoint(runArray, drivePoint);
        runArray.set(pair.first, drivePoint);
        List<LatLng> subList = runArray.subList(pair.first, runArray.size());
        
        // 设置滑动的轨迹坐标点
        smoothMarker.setPoints(subList);
        // 设置滑动的总时间
        smoothMarker.setTotalDuration(1);
        // 开始滑动
        smoothMarker.startSmoothMove();
    }
        private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (runArray == null) {
                return;
            }
            if (msg.what == MSG_UPDATE_CAR) {
                if (latLonArray.size() > 2) {
                    if (runArray.size() > 0) {
                        runArray.remove(0);
                        runArray.add(latLonArray.remove(0));
                    }
                    else {
                        runArray.add(latLonArray.remove(0));
                        runArray.add(latLonArray.remove(0));
                    }
                    if (smoothMarker != null) {
                        smoothMarker.destroy();
                    }
                    showCarMarkerSmooth();
                    sendEmptyMessageDelayed(MSG_UPDATE_CAR, UPDATE_CAR_INTERNAL);
                }
                else {
                    LogUtils.e("stop");
                    smoothMarker.stopMove();
                    clearRouteLines();
                    smoothMarker.destroy();
                    removeMessages(MSG_UPDATE_CAR);
                }
        }
    };
在论坛里看到一篇 "MapView和其它控件一起显示 " 的帖子, 那是很老的一篇帖子了, 很多朋友都说无法在android SDK 1.0上运行。既然那么多人关心,我在这里就把它重写一遍,顺便加入了一些新的功能 ,感兴趣的朋友可以看看。 第一步,当然是增加map的支持了。在Android Manifest.xml中增加以下语句: 第二步, 传说中的Layout: 然后, 创建一个MapViewActivity: public class MapViewActivity extends MapActivity { MapView mapView; MapController mapController; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); mapView = (MapView) findViewById(R.id.map); mapController = mapView.getController(); mapController.setZoom(15); updateView(); } @Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } private void updateView(){ Double lat = 31.23717*1E6; Double lng = 121.50811*1E6; GeoPoint point = new GeoPoint(lat.intValue(), lng.intValue()); mapController.setCenter(point); } } 好了,你的MapView上面就多了一个EditText了。 接着,我希望在MapView中增加ZoomIn和ZoomOut的功能(鄙视一下Google ,缺省的MapView居然连这个功能都没有) 1. 在我们的Layout中增加一段: 2. 在onCreate函数中增加: ViewGroup zoom=(ViewGroup)findViewById(R.id.zoom); zoom.addView(mapView.getZoomControls()); 现在在你的地图中点一下,屏幕左下角,是不是出现了一个Zoom Table? 这才是一个最基本的地图功能嘛。 以下技巧是基于SDK 1.0的) 一、申请Apikey,并放在正确的位置http://iceskysl.1sters.com/?action=show&id=441 这个应该都知道,但是是申请得到的key放哪里很多人不知道,可以放在 1、XML布局文件中 申请APIkey的时候,类似命令如下: C:\Documents and Settings\Administrator\Local Settings\Application Data\Android> "C:\Program Files\Java\jdk1.6.0_10\bin\keytool.exe" -list -alias androiddebugkey -keystore debug.keystore -storepass android -keypass android androiddebugkey, 2008-9-23, PrivateKeyEntry, 认证指纹 (MD5): 1D:68:43:7C:14:2E:CC:CA:35:8B:1F:93:A7:91:AD:45 2、java中 mMapView = new MapView(this, "01Yu9W3X3vbpYT3x33chPxxx7U1Z6jy8WYZXNFA"); 二、记得导入uses-library 由于1.0版本的修改,使得map包不再是默认的了,使用的时候需要在manifest中的application节点下加入 否则,你将遇到可恶的“java.lang.NoClassDefFoundError: ”,切记! 三、需要给予一定的权限 因为要使用GoogleMAP的service,所以需要 如果需要GPS等应用,还需要 四、Activity需要继承自MapActivity 类似如下代码; package com.iceskysl.showmap; import com.google.android.maps.MapActivity; import android.os.Bundle; public class ShowMap extends MapActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected boolean isRouteDisplayed() { // TODO Auto-generated method stub return false; } } 在Android中使用其提供的Sensor非常方便,如下是强制Landscape时候的情况: values[0]:方位角(水平旋转角),简单的说就是手机的头现在朝向哪个方位,0=北、90=东、180=南、270=西(可是好像不太准) values[1]:纵向旋转角,0=面朝上平置、-90=垂直向上、-180/180=面朝下平置、90=垂直向下 values[2]:橫向旋转角,0=朝前、90=往右倒、-90=往左倒 在Android中计算GPS两点间的距离/速度 Q:how to get distance between two GeoPoints in sdk 1.0 ? MapPoint.distanceSquared(MapPoint) is gone thaks!! A:you'll need to brush up on your trigonometry, and first compute the Haversine function (this is the standard way of doing it). In order to use the Java trig functions, you'll have to first convert all your angles from degrees to radians. Given two longitude/latitude pairs, and the earth's average radius (assume 6356.78km for your calculations), you can calculate the distance between the 2 points via this Java code: double EarthRad = 6356.78; // in km ! // first convert to radians... double geo1_lat = geo1.getLatitude()*java.lang.Math.PI/360; double geo1_lng = geo1.getLongitude()*java.lang.Math.PI/360; double geo2_lat = geo2.getLatitude()*java.lang.Math.PI/360; double geo2_lng = geo2.getLongitude()*java.lang.Math.PI/360; double deltaLat = java.lang.Math.abs(java.lang.Math.abs(geo2_lat) - java.lang.Math.abs(geo1_lat)); double deltaLng = java.lang.Math.abs(java.lang.Math.abs(geo2_lng) - java.lang.Math.abs(geo1_lng)); double dist = 2*EarthRad*java.lang.Math.asin(java.lang.Math.sqrt(haversine(deltaLat) + java.lang.Math.cos(pair1_lat) *java.lang.Math.cos(pair1_lng)*haversine(deltaLng))); Where "dist" now contains the distance between along the earth's surface. You can find the Haversine function trig equation by Googling it, then construct a method that returns the appropriate value. Computing the speed is straightforward: you know your sampling frequency, and you now know the distance between the most recent two points, so, employee speed = distance / sampling interval 参考:http://www.anddev.org/distance_between_two_geopoints_in_sdk10-t4195.html http://www.anddev.org/calculating_distance_between_two_gps_points-t3708.html 获得maps api的方法:本人的 打开Eclipse--->Windows--->Preferences--->Android--->Build 查看默认的debug keystore位置,我的是C:\Documents and Settings\Administrator\Local Settings\Application Data\Android\debug.keystore 启动命令行 直接 输入如下内容: keytool -list -alias androiddebugkey -keystore "C:\Documents and Settings\Administrator\Local Settings\Application Data\Android\debug.keystore" -storepass android -keypass android 结果如下:Microsoft Windows XP [版本 5.1.2600] (C) 版权所有 1985-2001 Microsoft Corp. C:\Documents and Settings\Administrator>keytool -list -alias androiddebugkey -ke ystore "C:\Documents and Settings\Administrator\Local Settings\Application Data\ Android\debug.keystore" -storepass android -keypass android androiddebugkey, 2009-3-12, keyEntry, 认证指纹 (MD5): 0F:C3:F0:C6:32:49:CE:C6:0E:18:57:CA:48:D7:CD:12 C:\Documents and Settings\Administrator> 屏幕图如下: 打开http://code.google.com/intl/zh-CN/android/maps-api-signup.html 填入你的认证指纹(MD5)即可获得apiKey了 0Ua9BENcUvNLXp8wn_vXXvVf70rLTYixrNxbHNQ http://www.androidcompetencycenter.com/category/android-api/ http://duzike.blogbus.com/logs/35386568.html http://www.helloandroid.com/node/206 http://www.diybl.com/course/6_system/linux/Linuxjs/2008819/136351.html 根据输入城市名动态加载google地图 文章出处:http://www.diybl.com/course/6_system/linux/Linuxjs/2008819/136351.html 1)SendCityName.java: package com.google.android.citygmapview; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; public class SendCityName extends Activity { protected static final int REQUEST_SEND_DATA = 0; /** Called when the activity is first created. */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); getAndSendCityName(); } public void getAndSendCityName() { Button btn = (Button)findViewById(R.id.confirm); btn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { EditText edt=(EditText)SendCityName.this.findViewById(R.id.edt); Intent intent = new Intent(); intent.setClass(SendCityName.this, ShowGmapView.class); if(edt.getText().length()!= 0) { String data = edt.getText().toString(); String name="data"; intent.putExtra(name, data); startSubActivity(intent,REQUEST_SEND_DATA); } } }); } } 说明: if(edt.getText().length()!= 0)用来处理用户输入为空的情况,为空时数据不会传递到另外一个activity中去,节省资源。 (2)ShowGmapView.java: package com.google.android.citygmapview; import java.io.IOException; import java.util.Locale; import com.google.android.location.GmmGeocoder; import com.google.android.maps.MapActivity; import com.google.android.maps.MapController; import com.google.android.maps.MapView; import com.google.android.maps.Point; import android.location.Address; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.Menu; import android.view.Menu.Item; public class ShowGmapView extends MapActivity { private static final int EXIT_ID = 0; private MapView myMapView; private Address[] maddrs; protected void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.gmap_view); Bundle extras = getIntent().getExtras(); String name="data"; if(extras != null) { String data1 = extras.getString(name); GmmGeocoder mgc = new GmmGeocoder(Locale.getDefault()); try { maddrs = mgc.query(data1, GmmGeocoder.QUERY_TYPE_LOCATION, 0, 0, 180.0, 360.0); if (null!=maddrs && maddrs.length > 0) { Log.d("CountryName: ", maddrs[0].getCountryName()); maddrs[0].getLatitude(); } else { setResult(RESULT_OK, null, extras); finish(); } } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } myMapView = new MapView(this); if(null!=maddrs && maddrs.length > 0) { Point p = new Point((int) (maddrs[0].getLatitude() * 1000000), (int) (maddrs[0].getLongitude() * 1000000)); /** 地图控制器 */ MapController mc = myMapView.getController(); mc.animateTo(p); /** 21是最zoom in的一级,一共是1-21级 */ mc.zoomTo(21); setContentView(myMapView); /** 切换到卫星地图 */ myMapView.toggleSatellite(); } setResult(RESULT_OK, null, extras); } } 文章出处:http://www.diybl.com/course/6_system/linux/Linuxjs/2008819/136351.html public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_I) { /** zoom in */ myMapView.getController().zoomTo(myMapView.getZoomLevel() + 1); return true; } else if (keyCode == KeyEvent.KEYCODE_O) { /** zoom out */ myMapView.getController().zoomTo(myMapView.getZoomLevel() - 1); return true; } else if (keyCode == KeyEvent.KEYCODE_S) { /** 卫星地图 */ myMapView.toggleSatellite(); return true; } else if (keyCode == KeyEvent.KEYCODE_T) { /** traffic,路况 */ myMapView.toggleTraffic(); return true; } return false; } 文章出处:http://www.diybl.com/course/6_system/linux/Linuxjs/2008819/136351_2.html @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(0, EXIT_ID, R.string.exit_gmap); return true; } @Override public boolean onMenuItemSelected(int featureId, Item item) { super.onMenuItemSelected(featureId, item); switch(item.getId()) { case EXIT_ID: finish(); break; } return true; } } 说明: 在开始设计时采用了Geocoder这个类,但似乎通过它获取的经纬度为空值,所以最后采取了GmmGeocoder,并能达到目的。 图示: (3)main.xml: (4)gmap_view.xml: (5)strings.xml: city gmap view confirm Exit google map (6)AndroidManifest.xml: 文章出处:http://www.diybl.com/course/6_system/linux/Linuxjs/2008819/136351_3.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值