編輯:關於Android編程
本文參考的是http://blog.csdn.net/lmj623565791/article/details/37737213
同樣的我也是廢了半天事,有的問題,不是我們這菜鳥所知道的,
看者沒問題吧,但是報錯,開始我以為百度包有問題,是不是我沒把百度demo上的包導入正確啊,然後各種查詢,網上各種解決。。cannot resovle。。。
多虧了一個網上的朋友告訴我,
好了,不說了,下面給大家附上我的代碼。。
有興趣的話可以compare一下上篇的代碼
記住還是真機測試
實現功能有 添加覆蓋物
展示視圖控制文件:MainActivity
package com.yang.baidumapceshi;
import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
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.BaiduMap.OnMapClickListener;
import com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
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;
import com.yang.baidumapceshi.MyOrientationListener.OnOrientationListener;
import java.lang.reflect.Method;
import java.util.List;
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;
// 初始化全局 bitmap 信息,不用時及時 recycle
private BitmapDescriptor mIconMaker;
/**
* 詳細信息的 布局
*/
private RelativeLayout mMarkerInfoLy;
@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);
mMarkerInfoLy = (RelativeLayout) findViewById(R.id.id_marker_info);
// 獲得地圖的實例
mBaiduMap = mMapView.getMap();
mIconMaker = BitmapDescriptorFactory.fromResource(R.mipmap.maker);
MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f);
mBaiduMap.setMapStatus(msu);
// 初始化定位
initMyLocation();
// 初始化傳感器
initOritationListener();
initMarkerClickEvent();
initMapClickEvent();
}
private void initMapClickEvent()
{
mBaiduMap.setOnMapClickListener(new OnMapClickListener()
{
@Override
public boolean onMapPoiClick(MapPoi arg0)
{
return false;
}
@Override
public void onMapClick(LatLng arg0)
{
mMarkerInfoLy.setVisibility(View.GONE);
mBaiduMap.hideInfoWindow();
}
});
}
private void initMarkerClickEvent()
{
// 對Marker的點擊
mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener()
{
@Override
public boolean onMarkerClick(final Marker marker)
{
// 獲得marker中的數據
Info info = (Info) marker.getExtraInfo().get("info");
InfoWindow mInfoWindow;
// 生成一個TextView用戶在地圖中顯示InfoWindow
TextView location = new TextView(getApplicationContext());
location.setBackgroundResource(R.mipmap.location_tips);
location.setPadding(30, 20, 30, 50);
location.setText(info.getName());
// 將marker所在的經緯度的信息轉化成屏幕上的坐標
final LatLng ll = marker.getPosition();
Point p = mBaiduMap.getProjection().toScreenLocation(ll);
p.y -= 47;
LatLng llInfo = mBaiduMap.getProjection().fromScreenLocation(p);
//定義用於顯示該InfoWindow的坐標點
LatLng pt = new LatLng(39.86923, 116.397428);
//創建InfoWindow , 傳入 view, 地理坐標, y 軸偏移量
mInfoWindow = new InfoWindow(location, llInfo, p.y);
// 顯示InfoWindow
mBaiduMap.showInfoWindow(mInfoWindow);
// 設置詳細信息布局為可見
mMarkerInfoLy.setVisibility(View.VISIBLE);
// 根據商家信息為詳細信息布局設置信息
popupInfo(mMarkerInfoLy, info);
return true;
}
});
}
/**
* 根據info為布局上的控件設置信息
*
*/
protected void popupInfo(RelativeLayout mMarkerLy, Info info)
{
ViewHolder viewHolder = null;
if (mMarkerLy.getTag() == null)
{
viewHolder = new ViewHolder();
viewHolder.infoImg = (ImageView) mMarkerLy
.findViewById(R.id.info_img);
viewHolder.infoName = (TextView) mMarkerLy
.findViewById(R.id.info_name);
viewHolder.infoDistance = (TextView) mMarkerLy
.findViewById(R.id.info_distance);
viewHolder.infoZan = (TextView) mMarkerLy
.findViewById(R.id.info_zan);
mMarkerLy.setTag(viewHolder);
}
viewHolder = (ViewHolder) mMarkerLy.getTag();
viewHolder.infoImg.setImageResource(info.getImgId());
viewHolder.infoDistance.setText(info.getDistance());
viewHolder.infoName.setText(info.getName());
viewHolder.infoZan.setText(info.getZan() + "");
}
/**
* 復用彈出面板mMarkerLy的控件
*
*/
private class ViewHolder
{
ImageView infoImg;
TextView infoName;
TextView infoDistance;
TextView infoZan;
}
/**
* 初始化方向傳感器
*/
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 void addInfosOverlay(List infos)
{
mBaiduMap.clear();
LatLng latLng = null;
OverlayOptions overlayOptions = null;
Marker marker = null;
for (Info info : infos)
{
// 位置
latLng = new LatLng(info.getLatitude(), info.getLongitude());
// 圖標
overlayOptions = new MarkerOptions().position(latLng)
.icon(mIconMaker).zIndex(5);
marker = (Marker) (mBaiduMap.addOverlay(overlayOptions));
Bundle bundle = new Bundle();
bundle.putSerializable("info", info);
marker.setExtraInfo(bundle);
}
// 將地圖移到到最後一個經緯度位置
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latLng);
mBaiduMap.setMapStatus(u);
}
/**
* 實現實位回調監聽
*/
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_addMaker:
addInfosOverlay(Info.infos);
break;
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();
mIconMaker.recycle();
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);
}
}
寫個Info
package com.yang.baidumapceshi;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Created by yang_zzheng on 2016/7/19
* [email protected]
*/
public class Info implements Serializable
{
private static final long serialVersionUID = -758459502806858414L;
/**
* 精度
*/
private double latitude;
/**
* 緯度
*/
private double longitude;
/**
* 圖片ID,真實項目中可能是圖片路徑
*/
private int imgId;
/**
* 商家名稱
*/
private String name;
/**
* 距離
*/
private String distance;
/**
* 贊數量
*/
private int zan;
public static List infos = new ArrayList();
static
{
infos.add(new Info(34.242652, 108.971171, R.mipmap.a01, "英倫貴族小旅館",
"距離209米", 1456));
infos.add(new Info(34.242952, 108.972171, R.mipmap.a02, "沙井國際洗浴會所",
"距離897米", 456));
infos.add(new Info(34.242852, 108.973171, R.mipmap.a03, "五環服裝城",
"距離249米", 1456));
infos.add(new Info(34.242152, 108.971971, R.mipmap.a04, "老米家泡馍小炒",
"距離679米", 1456));
}
public Info()
{
}
public Info(double latitude, double longitude, int imgId, String name,
String distance, int zan)
{
super();
this.latitude = latitude;
this.longitude = longitude;
this.imgId = imgId;
this.name = name;
this.distance = distance;
this.zan = zan;
}
public double getLatitude()
{
return latitude;
}
public void setLatitude(double latitude)
{
this.latitude = latitude;
}
public double getLongitude()
{
return longitude;
}
public void setLongitude(double longitude)
{
this.longitude = longitude;
}
public String getName()
{
return name;
}
public int getImgId()
{
return imgId;
}
public void setImgId(int imgId)
{
this.imgId = imgId;
}
public void setName(String name)
{
this.name = name;
}
public String getDistance()
{
return distance;
}
public void setDistance(String distance)
{
this.distance = distance;
}
public int getZan()
{
return zan;
}
public void setZan(int zan)
{
this.zan = zan;
}
}
AndroidManifest.xml配置
main.xml配置
map_image_border_white.xml
Android 模擬器 3D 加速架構 運行 Android 模擬器的有個 GPU 開關,當打開 GPU 開關 3D 加速功能將轉給 HOST的 GPU, 否則就是用 S
大家知道,自定義View有三個重要的步驟:measure,layout,draw。而measure處於該鏈條的首端,占據著極其重要的地位;然而對於measur
默認AS大包好的apk是app-deubg.apk的,這樣的話版本多了找出一個bug在哪個版本中存在的,就非常的麻煩了,我們追加版本號和版本名稱後就非常好區分了。配置方法
智能手機默認情況下是不會有密碼鎖屏的,但如果你設置了屏幕鎖定,則Flyme系統默認是采用數字鎖定的,數字鎖屏通過輸入正確的數字密碼來解鎖的,輸入數字比較容易