最近研究了很多的第三方sdk,今天稍微简单的研究下百度sdk,打个基础,做个记录,方便以后深入研究,
本文主要实现百度地图基本的类型和定位自己的位置功能
最终效果图如下:
进入界面后,会自动定位到自己的位置,然后有几个基本的类型,都是很基本的功能,如果以后有这方面的需求,在继续深入研究
进入百度开发中心
没有账号的注册一个账号吧
小伙伴可以自行勾选
然后点击下载开发包
把lib文件拷贝到自己的工程里面去
然后在src/main/目录下新建jniLibs目录
放入.so文件
上面这些配置,官网都有记载的,主要是功能的实现和一些bug的出现是个比较烦人的问题
记得在build.gradle(app)里面加上
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
好,接下来去申请key
点这里http://lbsyun.baidu.com/apiconsole/key
点击创建应用
这里主要讲解一下发布版的sha1怎么获取
http://jingyan.baidu.com/article/a681b0de0f860f3b184346bc.html
获得这个应该不难,就不细说了
我们都有默认的debug.keystore的,用这个测试好了,当然你有自己的签名文件的话,直接用自己的签名文件
找到自己的.android文件,然后找到debug.keystore
进入debug.keystore所在的目录
直接敲keytool -list -v -keystore debug.keystore
然后输入密令android
就能得到了
然后输入包名,包名在我们的每个java文件上面都有的
这样提交后,我们就有获得appkey了,
填写到manifest中,如下
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.anlaiye.swt.baidumapdemo">
<application
android:name=".MyApplication"
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="这里输入你的appkey就行了" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<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>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
我们在使用百度地图相关功能的时候,都需要先实例化,但是每一次都实例化就比较麻烦,所以从上面的配置文件中可以看到我创建了一个application,
代码很简单,就是实例化了百度地图SDK
package com.anlaiye.swt.baidumapdemo;
import android.app.Application;
import com.baidu.mapapi.SDKInitializer;
/**
* Created by pc on 2016/12/14.
*/
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
SDKInitializer.initialize(this);
}
}
接下来上布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.baidu.mapapi.map.MapView
android:id="@+id/bmapView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clickable="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/select_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选择类型" />
<Button
android:id="@+id/dingwei"
android:onClick="location"
android:text="定位自己"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
mapview就是百度地图的界面,你需要设置多大就设置多大
我下面加了按钮,实现一些功能
这是type.xml的代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent">
<LinearLayout
android:layout_marginBottom="35dp"
android:background="@android:color/transparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="weixin"
android:text="卫星图" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/white"
android:onClick="nomal"
android:text="正常图" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="none"
android:text="空白图" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/white"
android:onClick="jiaotong"
android:text="交通图" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="hotjiaotong"
android:text="热力交通图" />
</LinearLayout>
</RelativeLayout>
每个按钮都加了onclick事件,直接写在了mainactivity中
package com.anlaiye.swt.baidumapdemo;
import android.app.Dialog;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.PopupWindow;
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.MyLocationData;
import com.baidu.mapapi.model.LatLng;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private MapView mMapView = null;
private BaiduMap mBaiduMap;
private Button type_button;
private Dialog dialog;
private PopupWindow mPopupWindow;
private LocationManager mgr;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//在使用SDK各组件之前初始化context信息,传入ApplicationContext
//注意该方法要再setContentView方法之前实现
SDKInitializer.initialize(this);
setContentView(R.layout.activity_main);
//获取地图控件引用
mMapView = (MapView) findViewById(R.id.bmapView);
mBaiduMap = mMapView.getMap();
type_button = (Button) findViewById(R.id.select_type);
type_button.setOnClickListener(this);
initOritationListener();
initMyLocation();
}
public void weixin(View view) {
//卫星地图
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
// dialog.cancel();
}
public void nomal(View view) {
//正常地图
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
// dialog.cancel();
}
public void none(View view) {
//空白图
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NONE);
// dialog.cancel();
}
public void jiaotong(View view) {
//交通图
mBaiduMap.setTrafficEnabled(true);
// dialog.cancel();
}
public void hotjiaotong(View view) {
//热力交通图
mBaiduMap.setBaiduHeatMapEnabled(true);
// dialog.cancel();
}
/**
* 定位的客户端
*/
private LocationClient mLocationClient;
/**
* 定位的监听器
*/
public MyLocationListener mMyLocationListener;
/**
* 当前定位的模式
*/
private MyLocationConfiguration.LocationMode mCurrentMode = MyLocationConfiguration.LocationMode.NORMAL;
/***
* 是否是第一次定位
*/
private volatile boolean isFristLocation = true;
/**
* 最新一次的经纬度
*/
private double mCurrentLantitude;
private double mCurrentLongitude;
/**
* 当前的精度
*/
private float mCurrentAccracy;
/**
* 方向传感器的监听器
*/
private MyOrientationListener myOrientationListener;
/**
* 方向传感器X方向的值
*/
private int mXDirection;
private void initOritationListener()
{
myOrientationListener = new MyOrientationListener(
getApplicationContext());
myOrientationListener
.setOnOrientationListener(new MyOrientationListener.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 location(View view) {
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();
}
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
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
mMapView.onPause();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.select_type:
//这是对话框展示,都可以实现,稍微调整一下位置
/* View typeview = LayoutInflater.from(this).inflate(R.layout.type, null);
dialog = new Dialog(this, R.style.CustomDialog);
dialog.setContentView(typeview);
Window dialogWindow = dialog.getWindow();
// WindowManager.LayoutParams lp = dialogWindow.getAttributes();
dialogWindow.setGravity(Gravity.BOTTOM | Gravity.LEFT);
dialog.show();*/
//这是popwindows方式展示
View typeview = LayoutInflater.from(this).inflate(R.layout.type, null);
mPopupWindow = new PopupWindow(typeview, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, true);
mPopupWindow.setTouchable(true);
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.getContentView().setFocusableInTouchMode(true);
mPopupWindow.getContentView().setFocusable(true);
mPopupWindow.setBackgroundDrawable(new BitmapDrawable(getResources(), (Bitmap) null));//这句加上之后,点击背景才能去掉popwindows
mPopupWindow.showAtLocation(type_button, Gravity.BOTTOM | Gravity.LEFT, 0, 0);
break;
}
}
}
都注释的很详细,这里参考了鸿洋大神的百度sdk开发,不过鸿洋大神那个时候的sdk比较老了,所以我在看了后,用现在最新的重新实现了一下这些简单的功能,做个记录,
下面是MyOrientationListener的代码,用来监听定位后相关的操作
package com.anlaiye.swt.baidumapdemo;
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);
}
}
好了,简单的功能实现都在这里了
所有的代码在这里https://github.com/swtandyz/BaiDuSdkDemo
有很多人的地图只有网格没有,地图出来,这种情况一般是appkey的问题,也就是你的sha1值可能不对,(包名写错的人还是很少的)
230 uid: -1 appid -1 msg: APP Scode码校验失败
比如这个错误
http://download.youkuaiyun.com/detail/qq_15527709/9715042
可以在这里下载apk安装到手机上面,输入包名,获取sha1值