Android百度地圖(二)結合方向傳感器我們自己定位哪裏走
阿新 • • 發佈:2018-04-05
troy 真機 pretty 刪除文件 RR tap 大神 素材 near
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;
/**
* 定位的client
*/
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
* [email protected]
*/
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百度地圖(二)結合方向傳感器我們自己定位哪裏走