Android之百度定位
如果项目里面有定位功能的话,一般还是觉得蛮高大上的,我们项目用的百度定位,到网上找了很多资料,很多都不全面,很多博客都没有小伙伴期望得到当前的省和城市出来,然后自己动手也有很多错误,不知道错在哪里,也在网上找为什么错了,最终还是一一解决,不废话,先爆结果照片,
我们在Logcat里面可以得到当前的省份,城市,经纬度,还有详细地址字符串。
第一步、我们要到百度地图开放平台去
首先我们打开这个链接, 点击打开链接,来到了百度开放平台,我们选择是哪种开发需要,如图,
第二步、申请我们需要的key
申请好的这个key要记录下来,因为要添加在安卓项目的AndroidManifest.xml文件配置中,至于怎么配置的,等下再为你详细介绍,我们先去key申请的地址去 点击打开链接 然后就点击创建应用,选择我们需要的sdk
然后配置我们的安全码,
Android签名证书的sha1值+“;”+packagename(即:数字签名+分号+包名)怎么获取sha1值,这个 点击打开链接 链接上面写了2种获取方法,第一种方法:使用keytool、第二种方法:在adt 22中直接查看,然后包命是我们项目里面的AndroidManifest.xml配置文件的package,例如
这个时候就要注意了,如果是自己写例子申请key的时候一定要把包名一致,如果你这里申请了key,但是在自己练手的项目例子里面的包名和这个包命不一致的话,我们就得不到我们需要城市,和省份信息,就不能回调onReceiveLocation(BDLocation location){}这个回调函数,至于这个函数是什么,有什么功能,我们下面详细介绍,在输入安全码后,点击“确定”完成应用的配置工作,您将会得到一个创建的Key,我们需要保存好这个key,用Key来完成我们项目需要功能。
第三步 百度地图定位的关键API,然后搞懂思路到底是怎么得到我们的位置
打开这个链接点击打开链接 我们看到
有这几个重要的类,我划了红色长方形内的几个类是我们项目一般需要的类,更具我理解的意思介绍
1 BDLocationListener 可以理解百度定位的监听器,就像我们编程按钮的onClickLister差不多,当我们按钮设置了监听事件之后点击就会触发,BDLocationListener 我们需要重写个类,因为这个类里面有一个最重要的函数就是onReceiverLocation(BDLocation location){}这个函数,当触发监听的时候系统就会自动调用这个方法,这个方法就可以得到我们目前位置的所有信息,location就是当前的位置类,调用locaion.getCity()就得到了我们的城市,location.getAddr()能得到我们当前位置的所有信息,以此类推,可以得到我们当前位置的纬度经度,这里还有很多函数我就不一一举例出来,等下我们的代码一看就知道。
2 locationClient 这个类是本地客服端,类似我们常用的button,button有setOnclick事件,我们locationClient就有registerLocationListener()事件,原理差不多
3 LocationClent
这个类用来设置参数的,比如定位模式、定位时间间隔、坐标系类型等。
第四步 搞懂原理之后我们写例子
1 我们需要导入相关的包和so文件,如图有baidumapapi_v3_2_0.jar和liblocSDK6a.so文件,如果你没有这些官方有这些文件,加了jar文件记得点击鼠标右键 add library, 这个时候包才能点击进去看,说明自己才加到项目里面去了。
2、我们先要配置好AndroidManifest.xml文件里面的key,和service
<!--百度定位的配置-->
<meta-data
android:name="com.baidu.lbsapi.API_KEY"
android:value="zTVZkFgOA9bXgaZYcNtMkEao" />
<service
android:name="com.baidu.location.f"
android:enabled="true"
android:process=":remote" >
</service>
那个value就是配置key,是自己申请的key,不能用我的哈,不然没反应的,然后就是配置<service>,在这里要注意是配置在<application>里面,不要搞到外面去了不然没结果的,不信你试一试。
3、要添加权限,在AndroidManifest.xml里面加上,亲,要加上啊,不然不知道怎么死的
<!-- 这个权限用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<!-- 这个权限用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<!-- 用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<!-- 访问网络,网络定位需要上网-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- SD卡读取权限,用户写入离线定位数据-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
4写我们的程序
首先写个布局文件,里面只有个按钮activity_main.xml文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView android:text="@string/hello_world" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="baidu"
android:id="@+id/button"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="35dp"
android:layout_marginStart="35dp"
android:layout_marginTop="62dp" />
</RelativeLayout>
然后就是写我们的MainActivity.java文件
package com.example.administrator.baidumapdemo;
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
public class MainActivity extends AppCompatActivity {
public LocationClient mLocationClient=null;
public MyLocationListener mMyLocationListener=null;
public Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=(Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent("com.baidu.location.f");
startService(intent);
Log.i("1", "1");
mMyLocationListener=new MyLocationListener();
location(mMyLocationListener);
}
});
}
public class MyLocationListener implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
// Receive Location
// appSession.setBdLocation(location);
Log.i("baidu", "baidu");
StringBuffer sb = new StringBuffer(256);
sb.append("time : ");
sb.append(location.getTime());
sb.append("\nerror code : ");
sb.append(location.getLocType());
sb.append("\nlatitude : ");
sb.append(location.getLatitude());
sb.append("\nlontitude : ");
sb.append(location.getLongitude());
sb.append("\nradius : ");
sb.append(location.getRadius());
if (location.getLocType() == BDLocation.TypeGpsLocation) {
sb.append("\nspeed : ");
sb.append(location.getSpeed());
sb.append("\nsatellite : ");
sb.append(location.getSatelliteNumber());
sb.append("\ndirection : ");
sb.append("\naddr : ");
sb.append(location.getAddrStr());
sb.append(location.getDirection());
} else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
sb.append("\naddr : ");
sb.append(location.getAddrStr());
sb.append("\noperationers:");
sb.append(location.getOperators());
}
double lat= location.getLatitude();
double lon=location.getLongitude();
Log.i("province",location.getProvince()+"");
Log.i("city",location.getCity()+"");
Log.i("lat", "" + lat);
Log.i("lon",""+lon);
Log.i("BaiduLocationApiDem", sb.toString());
}
}
public void location(BDLocationListener listener) {
mLocationClient = new LocationClient(getApplicationContext());
LocationClientOption option = new LocationClientOption();
option.setIsNeedAddress(true);// 中文地址
option.setCoorType("bd09ll");// gcj02 国测局经纬度坐标系 ;bd09 百度墨卡托坐标系;bd09ll
// 百度经纬度坐标系
option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);// 设置定位模式
option.setScanSpan(5*60000);//检查周期 小于1秒的按1秒
mLocationClient.setLocOption(option);
Log.i("2", "2");
mLocationClient.registerLocationListener(listener);
mLocationClient.start();
}
/**
* 用这个方法的时候要注意ct是 调用这个函数类的context,方法的参数应该是this.getApplication传到这个方法里面去,而不是这个类的context,一定要注意。
* @param ct
*/
public void location(Context ct) {
mLocationClient = new LocationClient(ct);
LocationClientOption option = new LocationClientOption();
option.setIsNeedAddress(true);// 中文地址
option.setCoorType("bd09ll");// gcj02 国测局经纬度坐标系 ;bd09 百度墨卡托坐标系;bd09ll
// 百度经纬度坐标系
option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);// 设置定位模式
option.setScanSpan(5 * 60000);//检查周期 小于1秒的按1秒
mLocationClient.setLocOption(option);
Log.i("2", "2");
mLocationClient.registerLocationListener(new MyLocationListener());
mLocationClient.start();
}
}
在这个类中我们重写了BDLocationLister,里面的onReceiveLocation(Location location)通过location我们就可以得到我们的经度和纬度,省份和城市,具体地址全场,具体的API可以自己去看看,
mLocationClient = new LocationClient(getApplicationContext());
这里特别要注意 里面的参数是当前的context,因为是我自己本身调用的所以是getApplication(),如果是其它的类调用呢?我就重载了函数
location(Context ct)
mLocationClient = new LocationClient(ct);
这个ct是调用的类的context,而不是当前这个类的context,如果我在这里就写成mLocationClient=new LocationClient(getApplication())的话就会报空指针异常,要注意,
是设置相关的模式啊,定位时间的
mLocationClient.registerLocationListener(new MyLocationListener());
要记得注册监听啊,不然没反应的
mLocationClient.start();
要记得开始启动啊,不然你等得花儿都谢了。
好了,我们看见我们当前的位置
第五步、总结
有时候为什么不回调onReceiveLocation(BDLocation location){}函数
1、我们申请的key的时候,写的包和自己项目里面的包不一致
2、在AndroidMian.xml文件里面没有配置key 和service,或者配置在Application外面就没反应了
3 、我们没有导入包和so文件
4、 我们
mLocationClient = new LocationClient(getApplicationContext());
里面参数传错了,写的是ct.getApplication(),我们可以这样使用,是哪个类就调用哪个类的context
5 、我们忘记了写,那么你就慢慢等吧,慢慢找错误吧。
mLocationClient.start();
如果你哪里没有搞懂的加我QQ 2657607916 详细为你解答