码迷,mamicode.com
首页 > 移动开发 > 详细

Android百度地图结合方向传感器我们自己定位哪里走

时间:2016-07-19 13:49:53      阅读:703      评论:0      收藏:0      [点我收藏+]

标签:

Android百度地图结合方向传感器我们自己定位哪里走

本文代码在http://blog.csdn.net/xyzz609/article/details/51943556的基础上进一步修改,有兴趣的同学可以研究下怎么修改的

本篇我们准备为地图添加:第一,定位功能;第二,与方向传感器结合,通过旋转手机进行道路的方向确认。有了这两个功能,地图已经可以为我服务了

@一启动就自动定位了

a,MainActivity 中添加定位代码,定位的监听器MyLocationListener

b,封装的方向传感器的类MyOrientationListener

c,记得在AndroidManifest.xml配一个service

本文参考的是http://blog.csdn.net/lmj623565791/article/details/37730469

我刚开始看的时候差点蒙了,因为笔者思路很清晰,可是我不懂啊,最后我总结了下,其实就是改了上面的三个文件,下载他的代码看了,有些还没用到,就放进来了,我整理了好大一会才明白,

还有就是鸿洋大神有好大一个bug,害我浪费一个小时,

import com.baidu.mapapi.map.MyLocationConfigeration;

看者没问题吧,但是报错,开始我以为百度包有问题,是不是我没把百度demo上的包导入正确啊,然后各种查询,网上各种解决。。cannot resovle。。。

最后我发现是MyLocationConfiguration

一个字母一个字母对去吧。。。

好了,不说了,下面给大家附上我的代码。。

有兴趣的话可以compare一下上篇的代码

记住还是真机测试

实现功能有 普通地图,卫星地图,实时交通

技术分享
技术分享

布局文件或者素材

技术分享

下面是我实现的代码

布局文件:activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
    <com.baidu.mapapi.map.MapView
        android:id="@+id/id_bmapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true" />

    <RelativeLayout
        android:id="@+id/id_marker_info"
        android:visibility="gone"
        android:layout_width="fill_parent"
        android:layout_height="220dp"
        android:layout_alignParentBottom="true"
        android:background="#CC4e5a6b"
        android:clickable="true" >

        <ImageView
            android:layout_width="fill_parent"
            android:layout_height="150dp"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="12dp"
            android:layout_marginRight="12dp"
            android:layout_marginTop="10dp"
            android:alpha="1.0"
            android:background="@drawable/map_image_border_white"
            android:clickable="true"
            android:scaleType="fitXY"
            android:src="@drawable/map_iv" />

        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="50dp"
            android:layout_alignParentBottom="true"
            android:background="@drawable/bg_map_bottom" >

            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="20dp"
                android:orientation="vertical" >

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="老米家泡馍小炒"
                    android:textColor="#FFF5EB" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="距离200米"
                    android:textColor="#FFF5EB" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="20dp"
                android:orientation="horizontal" >

                <ImageView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:onClick="zan"
                    android:src="@drawable/map_zan" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:text="652"
                    android:textColor="#FFF5EB" />
            </LinearLayout>
        </RelativeLayout>
    </RelativeLayout>

</RelativeLayout>

展示视图控制文件:MainActivity

package com.yang.baidumapceshi;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;

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.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.yang.baidumapceshi.MyOrientationListener.OnOrientationListener;

import java.lang.reflect.Method;

public class MainActivity extends Activity
{
    /**
     * 地图控件
     */
    private MapView mMapView = null;
    /**
     * 地图实例
     */
    private BaiduMap mBaiduMap;
    /**
     * 定位的客户端
     */
    private LocationClient mLocationClient;
    /**
     * 定位的监听器
     */
    public MyLocationListener mMyLocationListener;
    /**
     * 当前定位的模式
     */
    private LocationMode mCurrentMode = LocationMode.NORMAL;
    /***
     * 是否是第一次定位
     */
    private volatile boolean isFristLocation = true;

    /**
     * 最新一次的经纬度
     */
    private double mCurrentLantitude;
    private double mCurrentLongitude;
    /**
     * 当前的精度
     */
    private float mCurrentAccracy;
    /**
     * 方向传感器的监听器
     */
    private MyOrientationListener myOrientationListener;
    /**
     * 方向传感器X方向的值
     */
    private int mXDirection;

    /**
     * 地图定位的模式
     */
    private String[] mStyles = new String[] { "地图模式【正常】", "地图模式【跟随】",
            "地图模式【罗盘】" };
    private int mCurrentStyle = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // 注意该方法要再setContentView方法之前实现
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_main);
        // 第一次定位
        isFristLocation = true;
        // 获取地图控件引用
        mMapView = (MapView) findViewById(R.id.id_bmapView);
        // 获得地图的实例
        mBaiduMap = mMapView.getMap();
        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f);
        mBaiduMap.setMapStatus(msu);
        // 初始化定位
        initMyLocation();
        // 初始化传感器
        initOritationListener();

    }

    /**
     * 初始化方向传感器
     */
    private void initOritationListener()
    {
        myOrientationListener = new MyOrientationListener(
                getApplicationContext());
        myOrientationListener
                .setOnOrientationListener(new OnOrientationListener()
                {
                    @Override
                    public void onOrientationChanged(float x)
                    {
                        mXDirection = (int) x;

                        // 构造定位数据
                        MyLocationData locData = new MyLocationData.Builder()
                                .accuracy(mCurrentAccracy)
                                // 此处设置开发者获取到的方向信息,顺时针0-360
                                .direction(mXDirection)
                                .latitude(mCurrentLantitude)
                                .longitude(mCurrentLongitude).build();
                        // 设置定位数据
                        mBaiduMap.setMyLocationData(locData);
                        // 设置自定义图标
                        BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory
                                .fromResource(R.mipmap.navi_map_gps_locked);
                        MyLocationConfiguration config = new MyLocationConfiguration(
                                mCurrentMode, true, mCurrentMarker);
                        mBaiduMap.setMyLocationConfigeration(config);

                    }
                });
    }

    /**
     * 初始化定位相关代码
     */
    private void initMyLocation()
    {
        // 定位初始化
        mLocationClient = new LocationClient(this);
        mMyLocationListener = new MyLocationListener();
        mLocationClient.registerLocationListener(mMyLocationListener);
        // 设置定位的相关配置
        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true);// 打开gps
        option.setCoorType("bd09ll"); // 设置坐标类型
        option.setScanSpan(1000);
        mLocationClient.setLocOption(option);
    }

    /**
     * 实现实位回调监听
     */
    public class MyLocationListener 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(mXDirection).latitude(location.getLatitude())
                    .longitude(location.getLongitude()).build();
            mCurrentAccracy = location.getRadius();
            // 设置定位数据
            mBaiduMap.setMyLocationData(locData);
            mCurrentLantitude = location.getLatitude();
            mCurrentLongitude = location.getLongitude();
            // 设置自定义图标
            BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory
                    .fromResource(R.mipmap.navi_map_gps_locked);
            MyLocationConfiguration config = new MyLocationConfiguration(
                    mCurrentMode, true, mCurrentMarker);
            mBaiduMap.setMyLocationConfigeration(config);
            // 第一次定位时,将地图位置移动到当前位置
            if (isFristLocation)
            {
                isFristLocation = false;
                LatLng ll = new LatLng(location.getLatitude(),
                        location.getLongitude());
                MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
                mBaiduMap.animateMapStatus(u);
            }
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    /**
     * 默认点击menu菜单,菜单项不现实图标,反射强制其显示
     */
    @Override
    public boolean onMenuOpened(int featureId, Menu menu)
    {

        if (featureId == Window.FEATURE_OPTIONS_PANEL && menu != null)
        {
            if (menu.getClass().getSimpleName().equals("MenuBuilder"))
            {
                try
                {
                    Method m = menu.getClass().getDeclaredMethod(
                            "setOptionalIconsVisible", Boolean.TYPE);
                    m.setAccessible(true);
                    m.invoke(menu, true);
                } catch (Exception e)
                {
                }
            }

        }
        return super.onMenuOpened(featureId, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {

        switch (item.getItemId())
        {
            case R.id.id_menu_map_common:
                // 普通地图
                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
                break;
            case R.id.id_menu_map_site:// 卫星地图
                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
                break;
            case R.id.id_menu_map_traffic:
                // 开启交通图

                if (mBaiduMap.isTrafficEnabled())
                {
                    item.setTitle("开启实时交通");
                    mBaiduMap.setTrafficEnabled(false);
                } else
                {
                    item.setTitle("关闭实时交通");
                    mBaiduMap.setTrafficEnabled(true);
                }
                break;
            case R.id.id_menu_map_myLoc:
                center2myLoc();
                break;
            case R.id.id_menu_map_style:
                mCurrentStyle = (++mCurrentStyle) % mStyles.length;
                item.setTitle(mStyles[mCurrentStyle]);
                // 设置自定义图标
                switch (mCurrentStyle)
                {
                    case 0:
                        mCurrentMode = LocationMode.NORMAL;
                        break;
                    case 1:
                        mCurrentMode = LocationMode.FOLLOWING;
                        break;
                    case 2:
                        mCurrentMode = LocationMode.COMPASS;
                        break;
                }
                BitmapDescriptor mCurrentMarker = BitmapDescriptorFactory
                        .fromResource(R.mipmap.navi_map_gps_locked);
                MyLocationConfiguration config = new MyLocationConfiguration(
                        mCurrentMode, true, mCurrentMarker);
                mBaiduMap.setMyLocationConfigeration(config);
                break;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * 地图移动到我的位置,此处可以重新发定位请求,然后定位;
     * 直接拿最近一次经纬度,如果长时间没有定位成功,可能会显示效果不好
     */
    private void center2myLoc()
    {
        LatLng ll = new LatLng(mCurrentLantitude, mCurrentLongitude);
        MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
        mBaiduMap.animateMapStatus(u);
    }

    @Override
    protected void onStart()
    {
        // 开启图层定位
        mBaiduMap.setMyLocationEnabled(true);
        if (!mLocationClient.isStarted())
        {
            mLocationClient.start();
        }
        // 开启方向传感器
        myOrientationListener.start();
        super.onStart();
    }

    @Override
    protected void onStop()
    {
        // 关闭图层定位
        mBaiduMap.setMyLocationEnabled(false);
        mLocationClient.stop();

        // 关闭方向传感器
        myOrientationListener.stop();
        super.onStop();
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        // 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mMapView.onDestroy();
        mMapView = null;
    }

    @Override
    protected void onResume()
    {
        super.onResume();
        // 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        mMapView.onResume();
    }

    @Override
    protected void onPause()
    {
        super.onPause();
        // 在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        mMapView.onPause();
    }

}

写个MyOrientationListener

package com.yang.baidumapceshi;

/**
 * Created by yang_zzheng on 2016/7/18
 * yangzhizheng2012@163.com
 */
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

public class MyOrientationListener implements SensorEventListener
{

    private Context context;
    private SensorManager sensorManager;
    private Sensor sensor;

    private float lastX ;

    private OnOrientationListener onOrientationListener ;

    public MyOrientationListener(Context context)
    {
        this.context = context;
    }

    // 开始
    public void start()
    {
        // 获得传感器管理器
        sensorManager = (SensorManager) context
                .getSystemService(Context.SENSOR_SERVICE);
        if (sensorManager != null)
        {
            // 获得方向传感器
            sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        }
        // 注册
        if (sensor != null)
        {//SensorManager.SENSOR_DELAY_UI
            sensorManager.registerListener(this, sensor,
                    SensorManager.SENSOR_DELAY_UI);
        }

    }

    // 停止检测
    public void stop()
    {
        sensorManager.unregisterListener(this);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy)
    {

    }

    @Override
    public void onSensorChanged(SensorEvent event)
    {
        // 接受方向感应器的类型
        if (event.sensor.getType() == Sensor.TYPE_ORIENTATION)
        {
            // 这里我们可以得到数据,然后根据需要来处理
            float x = event.values[SensorManager.DATA_X];

            if( Math.abs(x- lastX) > 1.0 )
            {
                onOrientationListener.onOrientationChanged(x);
            }
//            Log.e("DATA_X", x+"");
            lastX = x ;

        }
    }

    public void setOnOrientationListener(OnOrientationListener onOrientationListener)
    {
        this.onOrientationListener = onOrientationListener ;
    }


    public interface OnOrientationListener
    {
        void onOrientationChanged(float x);
    }

}

AndroidManifest.xml配置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yang.baidumapceshi">

    <!-- 添加屏幕及版本支持 -->
    <supports-screens android:largeScreens="true"
        android:normalScreens="true"
        android:smallScreens="true"
        android:resizeable="true"
        android:anyDensity="true"/>
    <uses-sdk android:minSdkVersion="7" />

    <!-- 在sdcard中创建/删除文件的权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- 挂载和反挂载的权限 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <!-- 读取手机状态 ,如来了新电话-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <!-- 震动权限 -->
    <uses-permission android:name="android.permission.VIBRATE" />
    <!-- 网络访问权限 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />

    <!-- 百度地图定位功能所需权限 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <permission android:name="android.permission.BAIDU_LOCATION_SERVICE" />
    <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_GPS"/>
    <uses-permission android:name="android.permission.READ_LOGS" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="HOuUcEQSKXNv5gMLSK2ZSy0hK5dhMh59" />
        <!-- 百度定位服务    android:permission="android.permission.BAIDU_LOCATION_SERVICE">-->
        <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote" >
            <intent-filter>
                <action android:name="com.baidu.location.service_v2.2" >
                </action>
            </intent-filter>
        </service>

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

main.xml配置

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/id_menu_map_common"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="never"
        android:title="普通地图"/>
    <item
        android:id="@+id/id_menu_map_site"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="never"
        android:title="卫星地图"/>
    <item
        android:id="@+id/id_menu_map_traffic"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="never"
        android:title="开启实时交通"/>
    <item
        android:id="@+id/id_menu_map_myLoc"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="never"
        android:title="我的位置"/>
    <item
        android:id="@+id/id_menu_map_style"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="never"
        android:title="地图模式【正常】"/>

</menu>

map_image_border_white.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

    <stroke
        android:width="2dp"
        android:color="#AAffffff" />

    <padding
        android:bottom="2dp"
        android:left="2dp"
        android:right="2dp"
        android:top="2dp" />

</shape>

我这个人比较实在,你照着copy很快就能实现,但是之间关系怎么来的,为什么这么写?

参考大神的吧:http://blog.csdn.net/lmj623565791/article/details/37730469

喜欢的就给赞吧,不喜欢的勿喷,有的地方copy多了,哈哈,我写是照着学习,勿怪。

代码下载

本文中的代码已经在文中全部出现过了,为什么还需要一个下载币呢,是因为我的下载币不够用了额,下载其他大神的代码,需要,所以请赞助一下吧。当然你不想赞助的话,你可以在文章中一个一个的copy,绝对的一模一样,绝对的开源,赞助一个下载币吧
http://download.csdn.net/detail/xyzz609/9579815

Android百度地图结合方向传感器我们自己定位哪里走

标签:

原文地址:http://blog.csdn.net/xyzz609/article/details/51947325

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!