`
djun100
  • 浏览: 165276 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

百度API获取城市名地名(附源码)

 
阅读更多

在做一个软件时,用到了定位功能。网上有很多关于google 的GPS定位,但网上关于google定位都没有用,

搜索下原因:(这里建议大家在中国就尽量不使用系统自带的定位)

因为Google的服务器不在中国(就算能网上关于定位的代码能用,那也非常的慢,除非你的应用是在国外使用)
由于网络等原因所以定位一般会失败

于是转向使用百度api来定位。

所用到的百度API参考地址。

取得位置的百度官方sdk参考Android定位SDK

由坐标获取地址方法参考Geocoding API的 7.逆地理编码

先讲解怎么使用百度api获取获取地理坐标

准备工作:

(1)第一步,下载定位Android locSDK3.3。
下载地址:http://developer.baidu.com/map/static/doc/locSDK3.3.zip

(2)第二步,解压缩Android locSDK3.3

准备工作至此已经结束。

一、工程配置

1、第一步,在工程里新建libs文件夹,将开发包里的locSDK_3.3.jar拷贝到libs根目录下,将liblocSDK3.so拷贝到libs\armeabi目录下,拷贝完成后的工程目录如下图所示;

2、第二步(第一步导入后可以使用就不用这一步了):在工程属性->Java Build Path->Libraries中选择“Add External JARs”,选定locSDK_3.3.jar,确定后返回。

通过以上两步操作后,您就可以正常使用百度地图定位SDK为您提供的全部功能了。

在AndroidManifest.xml加入如下所示权限及server

<permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >
   </permission>
   <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >
   </uses-permission>
   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >
   </uses-permission>
   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >
   </uses-permission>
   <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
   </uses-permission>
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
   </uses-permission>
   <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" />
   <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >
   </uses-permission>
   <uses-permission android:name="android.permission.READ_LOGS" >
   </uses-permission>

在<application></application>标签中加入baidu server

<service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:permission="android.permission.BAIDU_LOCATION_SERVICE"
            android:process=":remote" >
            <intent-filter>
                <action android:name="com.baidu.location.service_v3.3" />
            </intent-filter>
        </service>

由于Location.java继承自Application,所以需要在配置文件中<application android:name="com.baidulocation.MainActivity" ……>节中需要加android:name,其中com.genwoxue.baidulocation为我们的包名称,Location为继承Application的类名称。

<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote"&gt; </service>这个是来自百度定位中的服务,不可更改其中内容。

我做好的如下所示

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.baidulocation"
    android:versionCode="1"
    android:versionName="1.0" >
     <permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >
    </permission>
    <uses-permission android:name="android.permission.BAIDU_LOCATION_SERVICE" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
    </uses-permission>
    <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" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >
    </uses-permission>
    <uses-permission android:name="android.permission.READ_LOGS" >
    </uses-permission>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.baidulocation.MainActivity"
            android:label="@string/app_name" >
            <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:permission="android.permission.BAIDU_LOCATION_SERVICE"
            android:process=":remote" >
            <intent-filter>
                <action android:name="com.baidu.location.service_v3.3" />
            </intent-filter>
        </service>
    </application>
</manifest>

补充:安列参考

在http://blog.csdn.net/ryantang03/article/details/7951260博客中提到可以通过Android定位SDK 直接获取地址,但是经过实验不行。或许我这地方并不有名的原因。

于是我使用 Android定位SDK 加Geocoding API的模式来获取位置。

为了获取的地理坐标能在函数中被调用,我封装了定位函数

MyBaiduLotion.java

package com.baidulocation;
import android.content.Context;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
public class MyBaiduLotion {
                                                                                                                                                                                                                                                              
    Context myContext;
                                                                                                                                                                                                                                                              
    private LocationClient locationClient = null;
    private static final int UPDATE_TIME = 4000;
    private static int LOCATION_COUTNS = 0;
    private boolean isFinish = false;
    MyBDcoordinate myBDcoordinate = null;
    MyLocation myLocation;
    String strlocation = "";
                                                                                                                                                                                                                                                              
    public MyBaiduLotion(Context context) {
        // TODO Auto-generated constructor stub
        myContext = context;
        myLocation = new MyLocation();
        initLockPst();
                                                                                                                                                                                                                                                                  
    }
                                                                                                                                                                                                                                                              
    class MyBDcoordinate{
        double Latitude;
        double Longitude;
    }
                                                                                                                                                                                                                                                              
     private void initLockPst(){
            locationClient = new LocationClient(this.myContext);
            //设置定位条件
            LocationClientOption option = new LocationClientOption();
            option.setOpenGps(true);        //是否打开GPS
            option.setCoorType("bd09ll");       //设置返回值的坐标类型。
            option.setPriority(LocationClientOption.NetWorkFirst);  //设置定位优先级
            option.setProdName("LocationDemo"); //设置产品线名称。强烈建议您使用自定义的产品线名称,方便我们以后为您提供更高效准确的定位服务。
            option.setScanSpan(UPDATE_TIME);    //设置定时定位的时间间隔。单位毫秒
            locationClient.setLocOption(option);
                                                                                                                                                                                                                                                                      
            //注册位置监听器
            locationClient.registerLocationListener(new BDLocationListener() {
                                                                                                                                                                                                                                                                          
                @Override
                public void onReceiveLocation(BDLocation location) {
                    // TODO Auto-generated method stub
                    if(myBDcoordinate != null){
                        stopOpetateClient();
                        //locationInfoTextView.setText("stop" + LOCATION_COUTNS);
                        return;
                    }
                    if(LOCATION_COUTNS > 5){
                                                                                                                                                                                                                                                                                  
                        stopOpetateClient();
                        return;
                    }
                    if (location == null) {
                        LOCATION_COUTNS ++;
                        return;
                    }
                    //location.getLocType();
                    //location.getLatitude()
                    //location.getLongitude();
                    if(location.getLocType() != 161){
                        LOCATION_COUTNS ++;
                        return;
                    }
                    myBDcoordinate = new MyBDcoordinate();
                    myBDcoordinate.Latitude = location.getLatitude();
                    myBDcoordinate.Longitude = location.getLongitude();
                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                              
                }
                                                                                                                                                                                                                                                                          
                @Override
                public void onReceivePoi(BDLocation location) {
                }
                                                                                                                                                                                                                                                                          
            });
        }
                                                                                                                                                                                                                                                               
     private void stopOpetateClient(){
         locationClient.stop();
         isFinish = true;
     }
                                                                                                                                                                                                                                                               
     private void startOpetateClient(){
         locationClient.start();
            /*
             *当所设的整数值大于等于1000(ms)时,定位SDK内部使用定时定位模式。
             *调用requestLocation( )后,每隔设定的时间,定位SDK就会进行一次定位。
             *如果定位SDK根据定位依据发现位置没有发生变化,就不会发起网络请求,
             *返回上一次定位的结果;如果发现位置改变,就进行网络请求进行定位,得到新的定位结果。
             *定时定位时,调用一次requestLocation,会定时监听到定位结果。
             */
         isFinish = false;
            locationClient.requestLocation();
     }
                                                                                                                                                                                                                                                               
     public boolean getIsFinish(){//获取定位是否完成或终止
         return isFinish;
     }
     public void opetateClient(){//开始或停止。
         if (locationClient == null) {
                return;
            }
            if (locationClient.isStarted()) {
                stopOpetateClient();
            }else {
                startOpetateClient();
                /*
                 *当所设的整数值大于等于1000(ms)时,定位SDK内部使用定时定位模式。
                 *调用requestLocation( )后,每隔设定的时间,定位SDK就会进行一次定位。
                 *如果定位SDK根据定位依据发现位置没有发生变化,就不会发起网络请求,
                 *返回上一次定位的结果;如果发现位置改变,就进行网络请求进行定位,得到新的定位结果。
                 *定时定位时,调用一次requestLocation,会定时监听到定位结果。
                 */
                locationClient.requestLocation();
                                                                                                                                                                                                                                                                          
            }
     }
                                                                                                                                                                                                                                                              
     /*********************************/
    public double getLatValue(){//纬度
        return myBDcoordinate.Latitude;
    }
    public double getLongValue(){//经度
        return myBDcoordinate.Longitude;
    }
                                                                                                                                                                                                                                                              
     public void desClient(){//当处在定位时Activity销毁时调用
         if (locationClient != null && locationClient.isStarted()) {
                locationClient.stop();
                locationClient = null;
            }
     }
                                                                                                                                                                                                                                                               
}

下方Key的申请地址为:http://lbsyun.baidu.com/apiconsole/key

在官方的文档中关于官方说的返回的 json, 需要加个[] 再才能解析。于是直接封装了个直接有坐标获取地址的类。

package com.baidulocation;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class MyLocation {
    String key = "F9da85afead8b6e9c4738e5e5b79eb97";
                                                                                                                                                                                                                 
    public String getAddress(String latValue, String longValue){
        String location = getJsonLocation(latValue, longValue);
        location = getLocation(makeResults(location));
        return location;
    }
                                                                                                                                                                                                                 
    private String getJsonLocation(String latValue, String longValue){
        String urlStr = "http://api.map.baidu.com/geocoder?location=" + latValue + "," + longValue + "&output=json&key=" + key;
        HttpClient httpClient = new DefaultHttpClient();
           String responseData = "";
           try{
               //向指定的URL发送Http请求
               HttpResponse response = httpClient.execute(new HttpGet(urlStr));
               //取得服务器返回的响应
               HttpEntity entity = response.getEntity();
               BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
               String line = "";
               while((line = bufferedReader.readLine()) != null){
                   responseData = responseData + line;
               }
           }
           catch (Exception e) {
               e.printStackTrace();
           }
             return responseData;
    }
                                                                                                                                                                                                                 
    private String makeResults(String result){
        String dealResult = result.substring(0, result.indexOf("result") +8) + "[" + result.substring(result.indexOf("result") +8, result.length()-1) + "]}";
        return dealResult;
    }
                                                                                                                                                                                                                 
    private String getLocation(String str){
          JSONArray jsonObjs;
          String location = "";
        try {
             jsonObjs = new JSONObject(str).getJSONArray("result");
                //取出数组中第一个json对象(本示例数组中实际只包含一个元素)
                JSONObject jsonObj = jsonObjs.getJSONObject(0);
              //解析得formatted_address值
              String address = jsonObj.getString("formatted_address");
              String bussiness = jsonObj.getString("business");
              location = address + ":" + bussiness;
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
          //取出数组中第一个json对象(本示例数组中实际只包含一个元素)
          return location;
    }
}

获取坐标室外会有8秒左右的延迟,所以在获取地理名称时需要等待获取坐标完成后。在主main中,定义一个线程(这里不能再直接建个类来直接获取地名了,需要在Aactivity中实现)

我的工程如下布局,主要看activity中的线程如何实现获取位置的

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"
    tools:context=".MainActivity" >
    <TextView
        android:id="@+id/tv_loc_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_marginBottom="130dp"
        android:layout_marginLeft="30dp"
        android:text="@string/hello_world" />
    <Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/tv_loc_info"
        android:layout_alignLeft="@+id/tv_loc_info"
        android:layout_marginBottom="52dp"
        android:text="Button" />
</RelativeLayout>

MainActivity.java中,主要看线程内的怎么处理获取坐标的延迟。

package com.baidulocation;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
    private TextView locationInfoTextView = null;
    private Button startButton = null;
                                                             
    MyBaiduLotion myLotion;
    MyLocation myLocation;
    String strlocation = "";
    @Override
    public void  onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
                                                                 
        locationInfoTextView = (TextView) this.findViewById(R.id.tv_loc_info);
        startButton = (Button) this.findViewById(R.id.btn_start);
                                                                 
                                                                 
        startButton.setOnClickListener(new OnClickListener() {
                                                                     
            @Override
            public void onClick(View v) {
                myLotion = new MyBaiduLotion(MainActivity.this);
                myLocation = new MyLocation();
                myLotion.opetateClient();
                new LocationTHread().start();
            }
            });
                                                                 
    }
    class LocationTHread extends Thread{
        @Override
        public void run() {
            // TODO Auto-generated method stub
            super.run();
            if(myLotion != null)
            while(!myLotion.getIsFinish()){
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(myLotion.myBDcoordinate != null){
                strlocation =  myLocation.getAddress(myLotion.getLatValue() +"", myLotion.getLongValue() + "");
                myHandler.sendEmptyMessage(1);
            }
                                                                     
        }
                                                                 
    }
                                                             
    Handler myHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
            locationInfoTextView.setText(strlocation);
        }
                                                                 
    };
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //myLotion.desClient();
    }
                                                             
                                                             
}

在手机上运行能获取坐标(室外获取到地理名称8到10秒。室内时间更长或无法定位)(需链接网咯)

源码:http://download.csdn.net/detail/djun100/6199773

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics