欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android百度地图开发之在定位图层显示他人位置(代码实现)

程序员文章站 2022-08-21 17:47:58
在这篇博客中主要做了两个工作 ①添加显示他人位置的marker ② 将他人头像作为图片合并到marker中进行显示 主要代码: ① 添加他人位置 这段代码可以添加到构造函数中,或者从服务器获取到他人...

在这篇博客中主要做了两个工作

①添加显示他人位置的marker

② 将他人头像作为图片合并到marker中进行显示

主要代码:

① 添加他人位置

这段代码可以添加到构造函数中,或者从服务器获取到他人位置后的代码中去

//添加他人位置
        resources r = this.getresources();
        bitmap bmp= bitmapfactory.decoderesource(r, r.drawable.touxiang);
        addotherslocation(double(对方的经度),double(对方的纬度),bmp(对方的头像bitmap));

主要函数:

public void addotherslocation(double latitute,double longtitute, bitmap touxiang) {

        resources r = this.getresources();
        bitmap bmp= bitmapfactory.decoderesource(r, r.drawable.icon_geo);//红点

//        //构建marker图标
//        otherscurrentmarker = bitmapdescriptorfactory
//                .fromresource(r.drawable.icon_geo);

        //构建marker图标
        otherscurrentmarker = bitmapdescriptorfactory
                .frombitmap(mergebitmap(bmp,touxiang));//public static bitmapdescriptor frombitmap(bitmap image)  + mergebitmap()

        //定义maker坐标点
        latlng point = new latlng(latitute, longtitute);
        //构建markeroption,用于在地图上添加marker
        overlayoptions option = new markeroptions()
                .position(point)
                .icon(otherscurrentmarker);
        //在地图上添加marker,并显示
        mbaidumap.addoverlay(option);
    }

②合并标志点图片和用户头像图像

//将两张图片合并为一张图片 用作头像
    private bitmap mergebitmap(bitmap firstbitmap, bitmap secondbitmap) {
        int width = firstbitmap.getwidth();
        int height = firstbitmap.getheight();
        secondbitmap = zoomimage(secondbitmap,width,height);
        bitmap bitmap = bitmap.createbitmap(width, height*2,
                firstbitmap.getconfig());
        canvas canvas = new canvas(bitmap);
        canvas.drawbitmap(secondbitmap, new matrix(), null);
        canvas.drawbitmap(firstbitmap, 0, height, null);
        return bitmap;
    }

    //缩放头像图片
    public  bitmap zoomimage(bitmap bgimage, double newwidth,
                             double newheight) {
        // 获取这个图片的宽和高
        float width = bgimage.getwidth();
        float height = bgimage.getheight();
        // 创建操作图片用的matrix对象
        matrix matrix = new matrix();
        // 计算宽高缩放率
        float scalewidth = ((float) newwidth) / width;
        float scaleheight = ((float) newheight) / height;
        // 缩放图片动作
        matrix.postscale(scalewidth, scaleheight);
        bitmap bitmap = bitmap.createbitmap(bgimage, 0, 0, (int) width,
                (int) height, matrix, true);
        return bitmap;
    }

完整代码:

import android.manifest;
import android.app.activity;
import android.content.context;
import android.content.pm.packagemanager;
import android.content.res.resources;
import android.graphics.bitmap;
import android.graphics.bitmapfactory;
import android.graphics.canvas;
import android.graphics.matrix;
import android.graphics.drawable.bitmapdrawable;
import android.graphics.drawable.drawable;
import android.hardware.sensor;
import android.hardware.sensorevent;
import android.hardware.sensoreventlistener;
import android.hardware.sensormanager;
import android.os.build;
import android.os.bundle;
import android.support.v4.app.activitycompat;
import android.support.v4.content.contextcompat;
import android.util.log;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;
import android.widget.compoundbutton;
import android.widget.imageview;
import android.widget.radiogroup.oncheckedchangelistener;
import android.widget.toast;
import android.widget.togglebutton;
import android.widget.zoomcontrols;

import com.baidu.location.bdlocation;
import com.baidu.location.bdlocationlistener;
import com.baidu.location.locationclient;
import com.baidu.location.locationclientoption;
import com.baidu.mapapi.sdkinitializer;
import com.baidu.mapapi.map.baidumap;
import com.baidu.mapapi.map.bitmapdescriptor;
import com.baidu.mapapi.map.bitmapdescriptorfactory;
import com.baidu.mapapi.map.mapstatusupdate;
import com.baidu.mapapi.map.mapstatusupdatefactory;
import com.baidu.mapapi.map.mapview;
import com.baidu.mapapi.map.markeroptions;
import com.baidu.mapapi.map.mylocationconfiguration;
import com.baidu.mapapi.map.mylocationconfiguration.locationmode;
import com.baidu.mapapi.map.mylocationdata;
import com.baidu.mapapi.map.overlayoptions;
import com.baidu.mapapi.model.latlng;

/**
 * 此demo用来展示如何结合定位sdk实现定位,并使用mylocationoverlay绘制定位位置 同时展示如何使用自定义图标绘制并点击时弹出泡泡 
 *
 */
public class locationdemo extends activity {

    // 定位相关  
    locationclient mlocclient;
    public mylocationlistenner mylistener = new mylocationlistenner();
    private locationmode mcurrentmode;
    bitmapdescriptor mcurrentmarker,otherscurrentmarker;

    mapview mmapview;
    baidumap mbaidumap;

    private sensormanager msensormanager;
    double degree = 0;
    // ui相关  
    oncheckedchangelistener radiobuttonlistener;
    button requestlocbutton;
    togglebutton togglebtn = null;
    boolean isfirstloc = true;// 是否首次定位  

    @override
    public void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        sdkinitializer.initialize(getapplicationcontext());
        setcontentview(r.layout.activity_location);
        judgepermission();
        requestlocbutton = (button) findviewbyid(r.id.button1);
        mcurrentmode = locationmode.normal;
        requestlocbutton.settext("普通");
        onclicklistener btnclicklistener = new onclicklistener() {
            public void onclick(view v) {
                switch (mcurrentmode) {
                    case normal:
                        requestlocbutton.settext("跟随");
                        mcurrentmode = locationmode.following;
                        mbaidumap
                                .setmylocationconfigeration(new mylocationconfiguration(
                                        mcurrentmode, true, mcurrentmarker));
                        break;
                    case compass:
                        requestlocbutton.settext("普通");
                        mcurrentmode = locationmode.normal;
                        mbaidumap
                                .setmylocationconfigeration(new mylocationconfiguration(
                                        mcurrentmode, true, mcurrentmarker));
                        break;
                    case following:
                        requestlocbutton.settext("罗盘");
                        mcurrentmode = locationmode.compass;
                        mbaidumap
                                .setmylocationconfigeration(new mylocationconfiguration(
                                        mcurrentmode, true, mcurrentmarker));
                        break;
                }
            }
        };
        requestlocbutton.setonclicklistener(btnclicklistener);

        togglebtn = (togglebutton) findviewbyid(r.id.togglebutton);
        togglebtn
                .setoncheckedchangelistener(new android.widget.compoundbutton.oncheckedchangelistener() {

                    @override
                    public void oncheckedchanged(compoundbutton buttonview,
                                                 boolean ischecked) {
                        if (ischecked) {
                            // 普通地图  
                            mbaidumap.setmaptype(baidumap.map_type_satellite);
                        } else {
                            // 卫星地图  
                            mbaidumap.setmaptype(baidumap.map_type_normal);
                        }

                    }
                });

        // 地图初始化  
        mmapview = (mapview) findviewbyid(r.id.bmapview);
        mbaidumap = mmapview.getmap();
        // 开启定位图层  
        mbaidumap.setmylocationenabled(true);
        // 定位初始化  
        mlocclient = new locationclient(this);
        mlocclient.registerlocationlistener(mylistener);
        locationclientoption option = new locationclientoption();
        option.setopengps(true);// 打开gps  
        option.setcoortype("bd09ll"); // 设置坐标类型  
        option.setscanspan(1000);// 设置发起定位请求的间隔时间为1000ms  
        option.setisneedaddress(true);
        mlocclient.setlocoption(option);
        mlocclient.start();
        // 隐藏logo
        view child = mmapview.getchildat(1);
        if (child != null && (child instanceof imageview || child instanceof zoomcontrols)){
            child.setvisibility(view.invisible);
        }

        //指南针
        msensormanager= (sensormanager) getsystemservice(context.sensor_service);
        sensor magenticsensor=msensormanager.getdefaultsensor(sensor.type_magnetic_field);
        sensor accelerometersensor=msensormanager.getdefaultsensor(sensor.type_accelerometer);
        msensormanager.registerlistener(listener,magenticsensor,sensormanager.sensor_delay_game);
        msensormanager.registerlistener(listener,accelerometersensor,sensormanager.sensor_delay_game);

        //添加他人位置
        resources r = this.getresources();
        bitmap bmp= bitmapfactory.decoderesource(r, r.drawable.touxiang);
        addotherslocation(经度(double),纬度(double),头像bmp);
    }

    //指南针 获取degree值
    private sensoreventlistener listener=new sensoreventlistener() {
        float[] accelerometervalues=new float[3];
        float[] magenticvalues=new float[3];
        @override
        public void onsensorchanged(sensorevent sensorevent) {
            //判断当前是加速度传感器还是地磁传感器
            if(sensorevent.sensor.gettype()==sensor.type_accelerometer){
                accelerometervalues=sensorevent.values.clone();
            }else if(sensorevent.sensor.gettype()== sensor.type_magnetic_field){
                magenticvalues=sensorevent.values.clone();
            }
            float[] r=new float[9];
            float[] values=new float[3];
            sensormanager.getrotationmatrix(r, null, accelerometervalues, magenticvalues);
            sensormanager.getorientation(r,values);
            log.d("mainactivity","value[0] is"+math.todegrees(values[0]));
            degree = math.todegrees(values[0]);

        }
        @override
        public void onaccuracychanged(sensor sensor, int i) {
        }
    };

    public void addotherslocation(double latitute,double longtitute, bitmap touxiang) {

        resources r = this.getresources();
        bitmap bmp= bitmapfactory.decoderesource(r, r.drawable.icon_geo);//标识红点

//        //构建marker图标
//        otherscurrentmarker = bitmapdescriptorfactory
//                .fromresource(r.drawable.icon_geo);

        //构建marker图标
        otherscurrentmarker = bitmapdescriptorfactory
                .frombitmap(mergebitmap(bmp,touxiang));//public static bitmapdescriptor frombitmap(bitmap image)  + mergebitmap()

        //定义maker坐标点
        latlng point = new latlng(latitute, longtitute);
        //构建markeroption,用于在地图上添加marker
        overlayoptions option = new markeroptions()
                .position(point)
                .icon(otherscurrentmarker);
        //在地图上添加marker,并显示
        mbaidumap.addoverlay(option);
    }

    //将两张图片合并为一张图片 用作头像
    private bitmap mergebitmap(bitmap firstbitmap, bitmap secondbitmap) {
        int width = firstbitmap.getwidth();
        int height = firstbitmap.getheight();
        secondbitmap = zoomimage(secondbitmap,width,height);
        bitmap bitmap = bitmap.createbitmap(width, height*2,
                firstbitmap.getconfig());
        canvas canvas = new canvas(bitmap);
        canvas.drawbitmap(secondbitmap, new matrix(), null);
        canvas.drawbitmap(firstbitmap, 0, height, null);
        return bitmap;
    }

    //缩放头像图片
    public  bitmap zoomimage(bitmap bgimage, double newwidth,
                             double newheight) {
        // 获取这个图片的宽和高
        float width = bgimage.getwidth();
        float height = bgimage.getheight();
        // 创建操作图片用的matrix对象
        matrix matrix = new matrix();
        // 计算宽高缩放率
        float scalewidth = ((float) newwidth) / width;
        float scaleheight = ((float) newheight) / height;
        // 缩放图片动作
        matrix.postscale(scalewidth, scaleheight);
        bitmap bitmap = bitmap.createbitmap(bgimage, 0, 0, (int) width,
                (int) height, matrix, true);
        return bitmap;
    }

    /**
     * 定位sdk监听函数 
     */
    public class mylocationlistenner implements bdlocationlistener {

        @override
        public void onreceivelocation(bdlocation location) {
            // map view 销毁后不在处理新接收的位置  
            if (location == null || mmapview == null)
                return;
            mylocationdata locdata = new mylocationdata.builder()
                    .accuracy(location.getradius())
                    // 此处设置开发者获取到的方向信息,顺时针0-360  
                    .direction((float)degree).latitude(location.getlatitude())
                    .longitude(location.getlongitude()).build();
            mbaidumap.setmylocationdata(locdata);
            if (isfirstloc) {
                isfirstloc = false;
                //定义maker坐标点  https://blog.csdn.net/u012382791/article/details/53856203
                latlng ll = new latlng(location.getlatitude(),
                        location.getlongitude());
                // mapstatusupdate u = mapstatusupdatefactory.newlatlng(ll);  
                // 设置缩放比例,更新地图状态  
                float f = mbaidumap.getmaxzoomlevel();// 19.0
                mapstatusupdate u = mapstatusupdatefactory.newlatlngzoom(ll,
                        f - 2);
                mbaidumap.animatemapstatus(u);
                //地图位置显示  
                toast.maketext(locationdemo.this, location.getaddrstr(),
                        toast.length_short).show();
            }

        }

        public void onreceivepoi(bdlocation poilocation) {
        }
    }

    @override
    protected void onpause() {
        mmapview.onpause();
        super.onpause();
    }

    @override
    protected void onresume() {
        mmapview.onresume();
        super.onresume();
    }

    @override
    protected void ondestroy() {
        // 退出时销毁定位  
        mlocclient.stop();
        // 关闭定位图层  
        mbaidumap.setmylocationenabled(false);
        mmapview.ondestroy();
        mmapview = null;

        if(msensormanager!=null){
            msensormanager.unregisterlistener(listener);
        }
        super.ondestroy();
    }


    //6.0之后要动态获取权限,重要!!!
    protected void judgepermission() {

        if (build.version.sdk_int >= build.version_codes.m) {
            // 检查该权限是否已经获取
            // 权限是否已经 授权 granted---授权  dinied---拒绝

            // sd卡权限
            string[] sdcardpermission = {manifest.permission.write_external_storage};
            if (contextcompat.checkselfpermission(this, sdcardpermission[0]) != packagemanager.permission_granted) {
                // 如果没有授予该权限,就去提示用户请求
                activitycompat.requestpermissions(this, sdcardpermission, 100);
            }

            //手机状态权限
            string[] readphonestatepermission = {manifest.permission.read_phone_state};
            if (contextcompat.checkselfpermission(this, readphonestatepermission[0]) != packagemanager.permission_granted) {
                // 如果没有授予该权限,就去提示用户请求
                activitycompat.requestpermissions(this, readphonestatepermission, 200);
            }

            //定位权限
            string[] locationpermission = {manifest.permission.access_fine_location};
            if (contextcompat.checkselfpermission(this, locationpermission[0]) != packagemanager.permission_granted) {
                // 如果没有授予该权限,就去提示用户请求
                activitycompat.requestpermissions(this, locationpermission, 300);
            }

            string[] access_coarse_location = {manifest.permission.access_coarse_location};
            if (contextcompat.checkselfpermission(this, access_coarse_location[0]) != packagemanager.permission_granted) {
                // 如果没有授予该权限,就去提示用户请求
                activitycompat.requestpermissions(this, access_coarse_location, 400);
            }


            string[] read_external_storage = {manifest.permission.read_external_storage};
            if (contextcompat.checkselfpermission(this, read_external_storage[0]) != packagemanager.permission_granted) {
                // 如果没有授予该权限,就去提示用户请求
                activitycompat.requestpermissions(this, read_external_storage, 500);
            }

            string[] write_external_storage = {manifest.permission.write_external_storage};
            if (contextcompat.checkselfpermission(this, write_external_storage[0]) != packagemanager.permission_granted) {
                // 如果没有授予该权限,就去提示用户请求
                activitycompat.requestpermissions(this, write_external_storage, 600);
            }

        }else{
            //dosdcardresult();
        }
        //locationclient.restart();
    }
}  

效果截图:

Android百度地图开发之在定位图层显示他人位置(代码实现)

左上角红点带头像的就是别人的位置显示