Android Studio地图开发(百度地图)

目前以开发出根据经纬度定位、根据地址定位、返回当前位置三个功能,项目不日会发到github供大家参考!!
地图项目实例https://github.com/wangleihitcs/MyMap/tree/master

第一步、配置环境

1.申请百度地图key

  • 首先到百度地图开放平台,登录账号,然后到如下界面Android Studio地图开发(百度地图)_第1张图片
  • 点击“创建应用”,到如下界面,填写应用名称,应用类型选择“Android SDK”Android Studio地图开发(百度地图)_第2张图片
  • 获取发布版SHA1和开发版SHA1,链接如下百度提供的获取SHA1的方法,注意,SHA1是基于文件.jks得到的,开发版SHA1为你调试的时候用到的,是基于debug.jks得到;发布版为你发布app或apk时用到的,是基于你自己创建的xxx.jks得到。如果你只填发布版SHA1得到的key,调试的时候是显示不出百度地图的,切记!!!

2.导入基本的百度地图jar包和so文件

  • 列在libs目录下导入jar包,这里只是最简单的BaiduLBS_Android.jar, 如下图Android Studio地图开发(百度地图)_第3张图片
  • 在main文件夹下创建jniLibs目录,导入so文件,如下图。这里注意armeabi目录和x86目录,里面的so文件是一样的,只是为了不同的CPU(arm,x86)而设置。如果你只有armeabi,那么你在x86虚拟机运行就显示不出百度地图!!!Android Studio地图开发(百度地图)_第4张图片

第二步,基本开发

基本功能是定位,根据经纬度、地址查询等简单操作。

  • 在AndroidManifest.xml文件下添加权限信心、百度key等

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.wanglei.mymap">
    <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_FINE_LOCATION" />
    
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        
        <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="KlXVjLVaGQZUk5z8i13mAPL805aFXE8n" />
        <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">
        service>
    application>

manifest>
  • 在activity_main.xml里添加控件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal"
        android:id="@+id/linearLayout1"
        android:visibility="gone"
        >
        <EditText
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:hint="经度"
            android:id="@+id/editText_lg" />
        <EditText
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:hint="纬度"
            android:id="@+id/editText_la" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:hint="前往"
            android:id="@+id/button_llsearch"/>
    LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal"
        android:id="@+id/linearLayout2"
        android:visibility="gone"
        >
        <EditText
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:hint="地址"
            android:id="@+id/editText_site" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:hint="前往"
            android:id="@+id/button_sitesearch"/>
    LinearLayout>

    <com.baidu.mapapi.map.MapView
        android:id="@+id/baiduMapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true" />
LinearLayout>
  • 在menu目录下添加menu_item.xml
"http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.zhangyi.baidumap_test.MainActivity">

    <item
        android:id="@+id/menu_item_mylocation"
        android:title="我的位置"
        app:showAsAction="never" />
    <item
        android:id="@+id/menu_item_llsearch"
        android:title="经纬度搜索"
        app:showAsAction="never" />
    <item
        android:id="@+id/menu_item_sitesearch"
        android:title="地址搜索"
        app:showAsAction="never" />


  • 在MainActivity.java
package com.example.wanglei.mymap;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;

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 ActionBarActivity {
    private MapView myMapView = null;//地图控件
    private BaiduMap myBaiduMap;//百度地图对象
    private LocationClient mylocationClient;//定位服务客户对象
    private MylocationListener mylistener;//重写的监听类
    private Context context;

    private double myLatitude;//纬度,用于存储自己所在位置的纬度
    private double myLongitude;//经度,用于存储自己所在位置的经度
    private float myCurrentX;

    private BitmapDescriptor myIconLocation1;//图标1,当前位置的箭头图标
//    private BitmapDescriptor myIconLocation2;//图表2,前往位置的中心图标

    private MyOrientationListener myOrientationListener;//方向感应器类对象

    private MyLocationConfiguration.LocationMode locationMode;//定位图层显示方式
//    private MyLocationConfiguration.LocationMode locationMode2;//定位图层显示方式

    private LinearLayout myLinearLayout1; //经纬度搜索区域1
    private LinearLayout myLinearLayout2; //地址搜索区域2

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // requestWindowFeature(Window.FEATURE_NO_TITLE);
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_main);
        this.context = this;
        initView();
        initLocation();
    }
    private void initView() {
        myMapView = (MapView) findViewById(R.id.baiduMapView);

        myBaiduMap = myMapView.getMap();
        //根据给定增量缩放地图级别
        MapStatusUpdate msu= MapStatusUpdateFactory.zoomTo(18.0f);
        myBaiduMap.setMapStatus(msu);
    }

    private void initLocation() {
        locationMode = MyLocationConfiguration.LocationMode.NORMAL;

        //定位服务的客户端。宿主程序在客户端声明此类,并调用,目前只支持在主线程中启动
        mylocationClient = new LocationClient(this);
        mylistener = new MylocationListener();

        //注册监听器
        mylocationClient.registerLocationListener(mylistener);
        //配置定位SDK各配置参数,比如定位模式、定位时间间隔、坐标系类型等
        LocationClientOption mOption = new LocationClientOption();
        //设置坐标类型
        mOption.setCoorType("bd09ll");
        //设置是否需要地址信息,默认为无地址
        mOption.setIsNeedAddress(true);
        //设置是否打开gps进行定位
        mOption.setOpenGps(true);
        //设置扫描间隔,单位是毫秒 当<1000(1s)时,定时定位无效
        int span = 1000;
        mOption.setScanSpan(span);
        //设置 LocationClientOption
        mylocationClient.setLocOption(mOption);

        //初始化图标,BitmapDescriptorFactory是bitmap 描述信息工厂类.
        myIconLocation1 = BitmapDescriptorFactory.fromResource(R.drawable.location_marker);
//        myIconLocation2 = BitmapDescriptorFactory.fromResource(R.drawable.icon_target);

        //配置定位图层显示方式,三个参数的构造器
        MyLocationConfiguration configuration
                = new MyLocationConfiguration(locationMode, true, myIconLocation1);
        //设置定位图层配置信息,只有先允许定位图层后设置定位图层配置信息才会生效,参见 setMyLocationEnabled(boolean)
        myBaiduMap.setMyLocationConfigeration(configuration);

        myOrientationListener = new MyOrientationListener(context);
        //通过接口回调来实现实时方向的改变
        myOrientationListener.setOnOrientationListener(new MyOrientationListener.OnOrientationListener() {
            @Override
            public void onOrientationChanged(float x) {
                myCurrentX = x;
            }
        });

    }

    /*
     *创建菜单操作
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId())
        {
            /*
             *第一个功能,返回自己所在的位置,箭头表示
             */
            case R.id.menu_item_mylocation://返回当前位置
                getLocationByLL(myLatitude, myLongitude);
                break;

            /*
             *第二个功能,根据经度和纬度前往位置
             */
            case R.id.menu_item_llsearch://根据经纬度搜索地点
                myLinearLayout1 = (LinearLayout) findViewById(R.id.linearLayout1);
                //经纬度输入区域1可见
                myLinearLayout1.setVisibility(View.VISIBLE);
                final EditText myEditText_lg = (EditText) findViewById(R.id.editText_lg);
                final EditText myEditText_la = (EditText) findViewById(R.id.editText_la);
                Button button_ll = (Button) findViewById(R.id.button_llsearch);

                button_ll.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        final double mylg = Double.parseDouble(myEditText_lg.getText().toString());
                        final double myla = Double.parseDouble(myEditText_la.getText().toString());
                        getLocationByLL(myla, mylg);
                        //隐藏前面经纬度输入区域
                        myLinearLayout1.setVisibility(View.GONE);
//                        Toast.makeText(context, "", Toast.LENGTH_SHORT).show();
                        //隐藏输入法键盘
                        InputMethodManager imm =(InputMethodManager)getSystemService(
                                Context.INPUT_METHOD_SERVICE);
                        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                    }
                });
                break;

            /*
             *第三个功能,根据地址名前往所在的位置
             */
            case R.id.menu_item_sitesearch://根据地址搜索
                myLinearLayout2 = (LinearLayout) findViewById(R.id.linearLayout2);
                //显示地址搜索区域2
                myLinearLayout2.setVisibility(View.VISIBLE);
                final EditText myEditText_site = (EditText) findViewById(R.id.editText_site);
                Button button_site = (Button) findViewById(R.id.button_sitesearch);

                button_site.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        final String site_str = myEditText_site.getText().toString();
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                AddressToLatitudeLongitude at = new AddressToLatitudeLongitude(site_str);
                                at.getLatAndLngByAddress();
                                getLocationByLL(at.getLatitude(), at.getLongitude());
                            }
                        }).start();
                        //隐藏前面地址输入区域
                        myLinearLayout2.setVisibility(View.GONE);
                        //隐藏输入法键盘
                        InputMethodManager imm = (InputMethodManager) getSystemService(
                                Context.INPUT_METHOD_SERVICE);
                        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                    }
                });
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    /*
     *根据经纬度前往
     */
    public void getLocationByLL(double la, double lg)
    {
        //地理坐标的数据结构
        LatLng latLng = new LatLng(la, lg);
        //描述地图状态将要发生的变化,通过当前经纬度来使地图显示到该位置
        MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
        myBaiduMap.setMapStatus(msu);
    }

    /*
     *定位请求回调接口
     */
    public class MylocationListener implements BDLocationListener
    {
        //定位请求回调接口
        private boolean isFirstIn=true;
        //定位请求回调函数,这里面会得到定位信息
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            //BDLocation 回调的百度坐标类,内部封装了如经纬度、半径等属性信息
            //MyLocationData 定位数据,定位数据建造器
            /*
            * 可以通过BDLocation配置如下参数
            * 1.accuracy 定位精度
            * 2.latitude 百度纬度坐标
            * 3.longitude 百度经度坐标
            * 4.satellitesNum GPS定位时卫星数目 getSatelliteNumber() gps定位结果时,获取gps锁定用的卫星数
            * 5.speed GPS定位时速度 getSpeed()获取速度,仅gps定位结果时有速度信息,单位公里/小时,默认值0.0f
            * 6.direction GPS定位时方向角度
            * */
            myLatitude = bdLocation.getLatitude();
            myLongitude = bdLocation.getLongitude();
            MyLocationData data = new MyLocationData.Builder()
                    .direction(myCurrentX)//设定图标方向
                    .accuracy(bdLocation.getRadius())//getRadius 获取定位精度,默认值0.0f
                    .latitude(myLatitude)//百度纬度坐标
                    .longitude(myLongitude)//百度经度坐标
                    .build();
            //设置定位数据, 只有先允许定位图层后设置数据才会生效,参见 setMyLocationEnabled(boolean)
            myBaiduMap.setMyLocationData(data);

            //判断是否为第一次定位,是的话需要定位到用户当前位置
            if (isFirstIn) {
                //根据当前所在位置经纬度前往
                getLocationByLL(myLatitude, myLongitude);
                isFirstIn = false;
                //提示当前所在地址信息
//                Toast.makeText(context, bdLocation.getAddrStr(), Toast.LENGTH_SHORT).show();
            }

        }
    }

    /*
    *定位服务的生命周期,达到节省
    */
    @Override
    protected void onStart() {
        super.onStart();
        //开启定位,显示位置图标
        myBaiduMap.setMyLocationEnabled(true);
        if(!mylocationClient.isStarted())
        {
            mylocationClient.start();
        }
        myOrientationListener.start();
    }
    @Override
    protected void onStop() {
        super.onStop();
        //停止定位
        myBaiduMap.setMyLocationEnabled(false);
        mylocationClient.stop();
        myOrientationListener.stop();
    }
    @Override
    protected void onResume() {
        super.onResume();
        myMapView.onResume();
    }
    @Override
    protected void onPause() {
        super.onPause();
        myMapView.onPause();
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        myMapView.onDestroy();
    }
}
  • MainActivity.java同一目录,AddressToLatitudeLongitude.java
package com.example.wanglei.mymap;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

/**
 * Created by wanglei on 2017/6/20.
 * 根据百度地图API,根据地址得到经纬度
 */
public class AddressToLatitudeLongitude {
    private String address = "哈尔滨";//地址
    private double Latitude = 45.7732246332393;//纬度
    private double Longitude = 126.65771685544611;//经度

    public AddressToLatitudeLongitude(String addr_str) {
            this.address = addr_str;
    }
    /*
     *根据地址得到地理坐标
     */
    public void getLatAndLngByAddress(){
        String addr = "";
        String lat = "";
        String lng = "";
        try {
            addr = java.net.URLEncoder.encode(address,"UTF-8");//编码
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String url = String.format("http://api.map.baidu.com/geocoder/v2/?"
                +"address=%s&ak=4rcKAZKG9OIl0wDkICSLx8BA&output=json",addr);
        URL myURL = null;
        URLConnection httpsConn = null;
        //进行转码
        try {
            myURL = new URL(url);
        } catch (MalformedURLException e) {
                e.printStackTrace();
        }
        try {
            httpsConn = (URLConnection) myURL.openConnection();//建立连接
            if (httpsConn != null) {
                InputStreamReader insr = new InputStreamReader(//传输数据
                        httpsConn.getInputStream(), "UTF-8");
                BufferedReader br = new BufferedReader(insr);
                String data = null;
                if ((data = br.readLine()) != null) {
                        System.out.println(data);
                        //这里的data为以下的json格式字符串,因为简单,所以就不使用json解析了,直接字符串处理
                        //{"status":0,"result":{"location":{"lng":118.77807440802562,"lat":32.05723550180587},"precise":0,"confidence":12,"level":"城市"}}
                    lat = data.substring(data.indexOf("\"lat\":")+("\"lat\":").length(), data.indexOf("},\"precise\""));
                    lng = data.substring(data.indexOf("\"lng\":")+("\"lng\":").length(), data.indexOf(",\"lat\""));
                }
                insr.close();
                br.close();
            }
        } catch (IOException e) {
                e.printStackTrace();
        }
        this.Latitude = Double.parseDouble(lat);
        this.Longitude = Double.parseDouble(lng);
    }
    public Double getLatitude() {
            return this.Latitude;
    }
    public Double getLongitude() {
            return this.Longitude;
    }

    public static void main(String[] args) {
            AddressToLatitudeLongitude at = new AddressToLatitudeLongitude("安徽省亳州市亳州一中");
            at.getLatAndLngByAddress();
            System.out.println(at.getLatitude() + " " + at.getLongitude());
    }
}
  • 如上,MyOrientationListener.java
package com.example.wanglei.mymap;

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 SensorManager mSensorManager;
    private Sensor mSensor;
    private Context mContext;
    private float lastX;
    private OnOrientationListener mOnOrientationListener;

    public MyOrientationListener(Context context)
    {
        this.mContext=context;
    }
    public void start()
    {
        mSensorManager= (SensorManager) mContext
                .getSystemService(Context.SENSOR_SERVICE);
        if(mSensorManager!= null)
        {
            //获得方向传感器
            mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        }
        //判断是否有方向传感器
        if(mSensor!=null)
        {
            //注册监听器
            mSensorManager.registerListener(this,mSensor,SensorManager.SENSOR_DELAY_UI);

        }


    }
    public void stop()
    {
        mSensorManager.unregisterListener(this);

    }
    //方向改变
    @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)
            {
                if(mOnOrientationListener!=null)
                {
                    mOnOrientationListener.onOrientationChanged(x);
                }
            }
            lastX=x;

        }

    }
    public void setOnOrientationListener(OnOrientationListener listener)
    {
        mOnOrientationListener=listener;
    }

    public interface OnOrientationListener
    {
        void onOrientationChanged(float x);

    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }
}
  • 文件组织截图
    Android Studio地图开发(百度地图)_第5张图片

  • app运行截图
    Android Studio地图开发(百度地图)_第6张图片
    Android Studio地图开发(百度地图)_第7张图片

    Android Studio地图开发(百度地图)_第8张图片

    参考如下链接

    根据百度API地址返回经纬度
    最详细的Android Studio百度地图(BaiduMap)开发教程,可以用作官方文档的教程!

你可能感兴趣的:(Android,Studio)