安卓-LBS地图显示

一、实验目的

写一个使用LBS的APP,能显示你目前所在地址(经纬度,国家 省市 街道),并能实时显示你位置的移动。

二、实验内容

开发一个LBS的APP,具备以下功能:
1、基于百度开发LBS的APP
2、显示你目前所在地址
3、实时显示你位置的移动

三、实验要求

(1)每位同学独立设计软件功能、完成软件的开发与测试。
(2)每位同学独立完成实验报告(根据模板),并提交至网络课堂。

四、数据代码及运行结果截图

前期准备
申请API
安卓-LBS地图显示_第1张图片

生成jks文件,获取密钥
安卓-LBS地图显示_第2张图片

主要代码
显示部分的代码即mainactivity部分:

package com.example.lbstest;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = new Intent(MainActivity.this,PositionAcitivity.class);
        startActivity(intent);
    }
}
用于定位的模块代码:
package com.example.lbstest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.TextView;
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.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import java.util.ArrayList;
import java.util.List;
public class PositionAcitivity extends AppCompatActivity {
    public LocationClient locationClient;
    private TextView position;
    private MapView mapView;
    private BaiduMap baiduMap;//百度地图的控制器
    private boolean isFirstLocation = true;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SDKInitializer.initialize(getApplicationContext());//很重要的一段代码
        setContentView(R.layout.activity_position_acitivity);
        //baiduMap的客户端
        locationClient = new LocationClient(getApplicationContext());
        locationClient.registerLocationListener(new MyLocationListener());
        position = findViewById(R.id.textView_position);
        mapView = findViewById(R.id.baiduMap);
        mapView.onCreate(getApplicationContext(),savedInstanceState);
        //获取百度地图的控制器
        baiduMap = mapView.getMap();
        baiduMap.setMyLocationEnabled(true);//可以显示当前位置
        //权限验证
        List<String> permissionList = new ArrayList<>();
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.READ_PHONE_STATE);
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
        if (!permissionList.isEmpty()) {
            String [] permissions = permissionList.toArray(new String[permissionList.size()]);
            ActivityCompat.requestPermissions(this, permissions, 1);
        } else {
            requestLocation();
        }
    }
    private void requestLocation() {
        initLocation();
        locationClient.start();
    }
    //这个是满足移动的时候更新location
    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        option.setScanSpan(5000);
        option.setIsNeedAddress(true);//具体的地址
        locationClient.setLocOption(option);
    }
    //onResume
    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }
    //pause
    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }
    //关闭
    @Override
    protected void onDestroy() {
        super.onDestroy();
        locationClient.stop();
        mapView.onDestroy();
        baiduMap.setMyLocationEnabled(false);
    }
    //监听器
    public class MyLocationListener implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            //定位到我自己
            if(location.getLocType() == BDLocation.TypeGpsLocation ||
                    location.getLocType() == BDLocation.TypeNetWorkLocation){
                navigateTo(location);
            }
            if (location.getCity() == null)
                return;
            //text View的展示地址
            StringBuilder currentPosition = new StringBuilder();
            currentPosition.append("纬度:").append(location.getLatitude()).append(" ");
            currentPosition.append("经线:").append(location.getLongitude()).append("\n");
            currentPosition.append("国家:").append(location.getCountry()).append(" ");
            currentPosition.append("省:").append(location.getProvince()).append("\n");
            currentPosition.append("市:").append(location.getCity()).append(" ");
            currentPosition.append("区:").append(location.getDistrict()).append(" ");
            currentPosition.append("街道:").append(location.getStreet()).append(" ");
            currentPosition.append("定位方式:");
            if (location.getLocType() == BDLocation.TypeGpsLocation) {
                currentPosition.append("GPS");
            } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
                currentPosition.append("网络");
            }
            position.setText(currentPosition);
        }
    }
    //实现定位效果
    private void navigateTo(BDLocation location) {
        if(isFirstLocation){
            Toast.makeText(this, "当前位置: " + location.getAddrStr(), Toast.LENGTH_SHORT).show();
            LatLng ll= new LatLng(location.getLatitude(),location.getLongitude());
            MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
            baiduMap.animateMapStatus(update);
            update = MapStatusUpdateFactory.zoomTo(16f);//地图放大
            baiduMap.animateMapStatus(update);
            isFirstLocation = false;
        }
        //实现光标显示我的位置
        MyLocationData.Builder builder = new MyLocationData.Builder();
        builder.latitude(location.getLatitude());
        builder.longitude(location.getLongitude());
        MyLocationData data = builder.build();
        baiduMap.setMyLocationData(data);
    }
}

运行截图如下
安卓-LBS地图显示_第3张图片

五、错误总结

如图显示NULL 百度定位API只给了几秒的时间记录信息,不能随时更新定位,因此当检测到NULL时直接返回即可
安卓-LBS地图显示_第4张图片

public class MyLocationListener implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            //定位到我自己
            if(location.getLocType() == BDLocation.TypeGpsLocation ||
                    location.getLocType() == BDLocation.TypeNetWorkLocation){
                navigateTo(location);
            }
            if (location.getCity() == null)
                return;
            //text View的展示地址
            StringBuilder currentPosition = new StringBuilder();
            currentPosition.append("纬度:").append(location.getLatitude()).append(" ");
            currentPosition.append("经线:").append(location.getLongitude()).append("\n");
            currentPosition.append("国家:").append(location.getCountry()).append(" ");
            if (location.getLocType() == BDLocation.TypeGpsLocation) {
                currentPosition.append("GPS");
            } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {
                currentPosition.append("网络");
            }
            position.setText(currentPosition);
        }
    }

六、个人心得体会

Hello BaiduMap
百度地图SDK为开发者提供了便捷的使用百度地图能力的接口,通过以下几步操作,即可在应用中使用百度地图:
1第一步 配置AndroidManifest.xml文件
1.在中加入如下代码配置开发密钥(AK):

<application>  
    <meta-data  
        android:name="com.baidu.lbsapi.API_KEY"  
        android:value="开发者 key" />  
</application>

若您还不曾申请开发密钥,点此申请
2. 在外部添加如下权限声明:

<!-- 访问网络,进行地图相关业务数据请求,包括地图数据,路线规划,POI检索等 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 获取网络状态,根据网络状态切换进行数据请求网络转换 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
<!-- 读取外置存储。如果开发者使用了so动态加载功能并且把so文件放在了外置存储区域,则需要申请该权限,否则不需要 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 写外置存储。如果开发者使用了离线地图,并且数据写在外置存储区域,则需要申请该权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

注:自Android6.0起部分权限的使用需要开发者在代码中动态申请。
2第二步 在布局文件中添加地图容器
MapView是View的一个子类,用于在Android View中放置地图。MapView的使用方法与Android提供的其他View一样。

<com.baidu.mapapi.map.MapView  
    android:id="@+id/bmapView"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:clickable="true" />

3第三步 地图初始化
注意:在SDK各功能组件使用之前都需要调用“SDKInitializer.initialize(getApplicationContext())”,因此建议在应用创建时初始化SDK引用的Context为全局变量。
新建一个自定义的Application,在其onCreate方法中完成SDK的初始化。示例代码如下:

public class DemoApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        //在使用SDK各组件之前初始化context信息,传入ApplicationContext   
        SDKInitializer.initialize(this);
        //4.3.0起,百度地图SDK所有接口均支持百度坐标和国测局坐标,用此方法设置您使用的坐标类型.
        //包括BD09LL和GCJ02两种坐标,默认是BD09LL坐标。
        SDKInitializer.setCoordType(CoordType.BD09LL);
    }
}

在AndroidManifest.xml文件中声明该Application

4创建地图Activity,管理MapView生命周期
注意:在项目中使用地图的时候要特别注意合理地管理地图生命周期,这非常重要。
以下示例代码简述对地图生命周期的管理:

public class MainActivity extends Activity {  
    private MapView mMapView = null;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);    
        setContentView(R.layout.activity_main);  
        //获取地图控件引用  
        mMapView = (MapView) findViewById(R.id.bmapView);  
    }  
    @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  
    protected void onDestroy() {  
      super.onDestroy();  
      //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理  
      mMapView.onDestroy();  
    }  
}

完成以上工作即可在您的应用中显示地图:
安卓-LBS地图显示_第5张图片

通过添加View显示地图

百度地图SDK支持不用通过layout文件中添加MapView控件,直接在Java代码中添加MapView的方式来展示地图,示例如下:
1创建MapView对象

MapView mapView = new MapView(this);

2添加MapView对象

setContentView(mapView);

另外,在Java代码中添加MapView的方式支持通过BaiduMapOptions对象根据需求构造包含特定地图状态类型和控件显示状态的MapView对象。示例如下:
1定义BaiduMapOptions对象

BaiduMapOptions options = new BaiduMapOptions()

2设置需要的状态
//设置地图模式为卫星地图

options.mapType(BaiduMap.MAP_TYPE_SATELLITE);

3创建MapView对象

MapView mapView = new MapView(this, options);

4添加MapView对象

setContentView(mapView);

可以通过如下代码设置地图的缩放级别:

MapStatus.Builder builder = new MapStatus.Builder();
builder.zoom(18.0f);
mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));

常用地图容器

地图SDK底层运用两种GLSurfaceView和TextureView两种OpenGL ES组件构建地图。下面简要介绍。GLSurfaceView包括MapView,MapFragment和SupportMapFragment三种容器。MapFragment和SupportMapFragment用于在Android Fragment中放置地图。适合需要使用Fragment的开发场景,方便您实现灵活的布局。MapFragment和SupportMapFragment分别是android.app.Fragment和android.support.v4.app,Fragment的子类,MapFragment需要在android3.0以上的版本中使用。

TextureView
包括TexureMapView,TextureMapFragment和TextureSupportMapFragment三种容器。使用场景:您将MapView与其他的GLSurfaceView(比如相机)叠加展示,或者是在ScrollView中加载地图时,建议使用TextureMapView及SupportTextureMapFragment来展示地图,可以有效解决 GLSurfaceView 叠加时出现的穿透、滚动黑屏等问题。如果使用TextureMapView请确保:Android 4.4以上系统,在AndroidManifest.xml中配置硬件加速选项。
SupportMapFragment
此处示例代码简要介绍SupportMapFragment使用。

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_fragment);
    manager = getSupportFragmentManager();
    //获取到SupportMapFragment实例
    mSupportMapFragment = SupportMapFragment.newInstance(mapOptions);
    //将fragment添加至Activity
    manager.beginTransaction().add(R.id.map_container, mapFragment).commit();
}

另外,您也可以使用replace的方法替换已有的fragment。
manager.beginTransaction().replace(R.id.map_container, mapFragment).commit();
多实例显示地图
开发者可以在一个页面中建立多个地图对象,并且针对这些对象分别操作且不会产生相互干扰。 示例代码:在布局文件中添加多个SupportMapFragment

<fragment
    android:id="@+id/map1"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_margin="5dp"
    android:layout_weight="1"
    class="com.baidu.mapapi.map.SupportMapFragment" />
<fragment
    android:id="@+id/map2"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_margin="5dp"
    android:layout_weight="1"
    class="com.baidu.mapapi.map.SupportMapFragment" />
在Activity中管理地图容器
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_multi_map_demo);

    LatLng GEO_BEIJING = new LatLng(39.945, 116.404);
    LatLng GEO_SHANGHAI = new LatLng(31.227, 121.481);

    //北京为地图中心,logo在左上角
    MapStatusUpdate status1 = MapStatusUpdateFactory.newLatLng(GEO_BEIJING);
    SupportMapFragment map1 = (SupportMapFragment) (getSupportFragmentManager()
            .findFragmentById(R.id.map1));
    map1.getBaiduMap().setMapStatus(status1);
    map1.getMapView().setLogoPosition(LogoPosition.logoPostionleftTop);

    //上海为地图中心
    MapStatusUpdate status2 = MapStatusUpdateFactory.newLatLng(GEO_SHANGHAI);
    SupportMapFragment map2 = (SupportMapFragment) (getSupportFragmentManager()
            .findFragmentById(R.id.map2));
    map2.getBaiduMap().setMapStatus(status2);
}

效果如图:

安卓-LBS地图显示_第6张图片

代码见我发布的资源

你可能感兴趣的:(安卓,Java,android,java,apache)