Android教学用例程序LBS 2 - 功能设计与实现

Posted Notebook

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android教学用例程序LBS 2 - 功能设计与实现相关的知识,希望对你有一定的参考价值。

打开后自动定位,并显示相关数据。

点击按钮可以刷新数据,未设置自动刷新,省电。。。

自动根据定位模式,亮起GPS或NET灯。


 Ref:《第一行代码》郭霖,百度地图官方文档


 

准备工作:

获取API_Key(AK)参考《第一行代码》,该书写得比较详细。也可参考百度官方文档。

下载 BaiduLBS_androidSDK V7.1 基础包:http://lbsyun.baidu.com/index.php?title=android-locsdk/geosdk-android-download

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.lbstest">
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <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="5HsZfAwGVeuPQIwvEZWyktP37VwaAodG"/>
        <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"/>
    </application>

</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"    >
    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapView"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:clickable="true" />
    <LinearLayout
        android:orientation = "horizontal"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <RadioButton
            android:id="@+id/radioGPS"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="GPS" />
        <RadioButton
            android:id="@+id/radioNET"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="NET" />
        <Button
            android:id="@+id/btn_refresh"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="Refresh"
            android:layout_weight="1.5"/>
    </LinearLayout>
    <TextView
        android:id="@+id/position_text_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

 MainActivity.java

package com.example.lbstest;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
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.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.Manifest;

public class MainActivity extends AppCompatActivity {
    public BDLocationListener BaiDuListener = new MylocationListener();
    public LocationClient mLocationClient = null;
    private TextView positionText;
    private RadioButton rbtnGPS;
    private RadioButton rbtnNet;

    private Button btnRefresh;
    private MapView mapView;
    private BaiduMap baiduMap;
    private boolean isFirstLocate = true;
    private LocationClientOption option = new LocationClientOption();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mLocationClient = new LocationClient(getApplicationContext());//声明LocationClient类
        mLocationClient.registerLocationListener(BaiDuListener);//注册监听函数
        SDKInitializer.initialize(getApplicationContext());//SDKInitializer调用initialize方法,传入全局的上下文进行初始化操作,地图就会显示出来
        setContentView(R.layout.activity_main);

        mapView = (MapView)findViewById(R.id.bmapView);
        positionText  =(TextView)findViewById(R.id.position_text_view);
        rbtnGPS = (RadioButton)findViewById(R.id.radioGPS);
        rbtnNet = (RadioButton)findViewById(R.id.radioNET);

        btnRefresh = (Button)findViewById(R.id.btn_refresh);
        rbtnNet.setClickable(false);//Forbidden radiobutton can be clicked
        rbtnGPS.setClickable(false);

        baiduMap = mapView.getMap();//获取地图的总控制器BaiduMap类的实例
        // 有了BiaduMap类的实例,就可以对地图进行各种各样的操作,比如设置地图的缩放级别以及将地图移动到某一个经纬度上。
        baiduMap.setMyLocationEnabled(true);//取消百度地图让”我”显示在地图上的限制
        btnRefresh.setOnClickListener(lisenter);
        List<String> permissionList = new ArrayList<>();// Permission array list , request permissions in one array.
        if(ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) !=  PackageManager.PERMISSION_GRANTED){
            permissionList.add(android.Manifest.permission.ACCESS_FINE_LOCATION);
        }
        if(ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED){
            permissionList.add(android.Manifest.permission.READ_PHONE_STATE);
        }
        if(ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
            permissionList.add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
        if(!permissionList.isEmpty()){
            String[] permissions = permissionList.toArray(new String[permissionList.size()]);
            ActivityCompat.requestPermissions(MainActivity.this,permissions,1);//request all permissions
        }else {
            requestLocation();// Request Location information
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mLocationClient.stop();
        mapView.onDestroy();
        baiduMap.setMyLocationEnabled(false);//程序退出的时候,关闭我的位置显示功能
    }

    protected void onRefresh(){
        finish();
        Intent intent = new Intent(MainActivity.this, MainActivity.class);
        startActivity(intent);
    }

    private void initLocation() {
        option.setCoorType("bd09ll");        //可选,默认gcj02,设置返回的定位结果坐标系
        //option.setScanSpan(5000);// 可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
//        option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
//        option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);
        option.setOpenGps(true);        //可选,默认false,设置是否使用gps
        option.setIsNeedAddress(true);//可选,设置是否需要地址信息,默认不需要
        mLocationClient.setLocOption(option);
    }
    private void  requestLocation(){
        initLocation();
        Log.d("map requestLocation:","Run requestLocation ...");
        mLocationClient.start();
    }
    private void navigateTo(BDLocation location) {
        if (isFirstLocate) {
            LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
            MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);//借助LatLng类实现地图移动到某一个经纬度上
            baiduMap.animateMapStatus(update);
            update = MapStatusUpdateFactory.zoomTo(16f);//百度地图可以将缩放级别的取值范围定在3到19之间,值越大,地图越精细。
            baiduMap.animateMapStatus(update);
            isFirstLocate = false;
        }
        MyLocationData.Builder locationBuilder = new MyLocationData.Builder();//借助MyLocationData.Builder类封装经纬度信息
        locationBuilder.latitude(location.getLatitude());
        locationBuilder.longitude(location.getLongitude());
        MyLocationData locationdata = locationBuilder.build();
        baiduMap.setMyLocationData(locationdata);//借助MyLocationData.Builder类的build方法,让设备的位置显示在地图上
    }
    @Override
    public  void  onRequestPermissionsResult(int requestCode, String[] permissions,int[] grantResults){
        switch (requestCode){
            case 1:
                if(grantResults.length >0 ){
                    for (int result : grantResults){
                        if(result != PackageManager.PERMISSION_GRANTED){
                            Toast.makeText(this,"all  permission  !!!",Toast.LENGTH_SHORT).show();
                            finish();
                            return;
                        }
                    }
                    requestLocation();
                }else {
                    Toast.makeText(this,"Unkonw error.",Toast.LENGTH_SHORT).show();
                    finish();
                }
                break;
            default:
        }
    }

    public class MylocationListener implements BDLocationListener{
        @Override
        public  void onReceiveLocation(BDLocation location){
            final StringBuilder currentPosition = new StringBuilder();
            Log.d("map Listener",location.getLocType()+"");
            if(location.getLocType() == BDLocation.TypeGpsLocation){   // GPS定位结果
                Log.d("map test","GPS");
                rbtnGPS.setChecked(true);
                rbtnNet.setChecked(false);
                currentPosition.append("[卫星数量]");
                currentPosition.append(location.getSatelliteNumber());    //获取卫星数
                currentPosition.append("\\n[速度]");
                currentPosition.append(location.getSpeed());        // 单位:公里每小时
                currentPosition.append("\\n[海拔]");
                currentPosition.append(location.getAltitude());    //获取海拔高度信息,单位米
                currentPosition.append("\\n[方向]");
                currentPosition.append(location.getDirection());    //获取方向信息,单位度
                currentPosition.append("\\n[地址]");
                currentPosition.append(location.getAddrStr());    //获取地址信息
                currentPosition.append("\\nGPS定位成功");
                currentPosition.append("\\n");
                navigateTo(location);
            }else if (location.getLocType() == BDLocation.TypeNetWorkLocation){  // Net定位结果
                Log.d("map test","net");
                rbtnNet.setChecked(true);
                rbtnGPS.setChecked(false);
                currentPosition.append("[地址]");
                currentPosition.append(location.getAddrStr());    //获取地址信息
                currentPosition.append("\\n[运营商]");
                currentPosition.append(location.getOperators());    //获取运营商信息
                currentPosition.append("\\n网络定位成功!");
                currentPosition.append("\\n");
                navigateTo(location);
            }else if (location.getLocType() == BDLocation.TypeOffLineLocation) {                // 离线定位结果
                Log.d("map test","Offline");
                currentPosition.append("\\ndescribe : ");
                currentPosition.append("离线定位成功,离线定位结果也是有效的");
                navigateTo(location);
            } else if (location.getLocType() == BDLocation.TypeServerError) {
                currentPosition.append("\\ndescribe : ");
                currentPosition.append("服务端网络定位失败,可以反馈IMEI号和大体定位时间到loc-bugs@baidu.com,会有人追查原因");
            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
                currentPosition.append("\\ndescribe : ");
                currentPosition.append("网络不同导致定位失败,请检查网络是否通畅");
            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
                currentPosition.append("\\ndescribe : ");
                currentPosition.append("无法获取有效定位依据导致定位失败,一般是由于手机的原因,处于飞行模式下一般会造成这种结果,可以试着重启手机");
            }else {
                currentPosition.append("定位失败。错误码:");
                currentPosition.append(location.getLocType()).append("\\n");
            }
            currentPosition.append("[经度]").append(location.getLongitude()+"").append("\\n");
            currentPosition.append("[维度]").append(location.getLatitude()+"").append("\\n");
            currentPosition.append("[国家]").append(location.getCountry()).append("\\n");
            currentPosition.append("[省份]").append(location.getProvince()).append("\\n");
            currentPosition.append("[城市]").append(location.getCity()).append("\\n");
            currentPosition.append("[区县]").append(location.getDistrict()).append("\\n");
            currentPosition.append("[街道]").append(location.getStreet());

            runOnUiThread(new Runnable() {
//                利用Activity.runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,
//                然后在需要更新ui时,把这个Runnable对象传给Activity.runOnUiThread(Runnable)。
//                Runnable对像就能在ui程序中被调用。如果当前线程是UI线程,那么行动是立即执行。
//                如果当前线程不是UI线程,操作是发布到事件队列的UI线程。
                @Override
                public void run() {
                    positionText.setText(currentPosition);
                }
            });
        }
        @Override
        public void onConnectHotSpotMessage(String s, int i) {        }
    }

    private View.OnClickListener lisenter = new View.OnClickListener() {//侦听器
        @Override
        public void onClick(View view) {
            Button button = (Button) view;//把点击获得的参数传递给button
            try{
                switch (button.getId()) {//根据按钮id,判断点击了那个按钮,进一步执行相关代码
                    case R.id.btn_refresh:{                        //
                        Toast toast = Toast.makeText(MainActivity.this,"刷新定位数据", Toast.LENGTH_SHORT);
                        toast.setGravity(Gravity.TOP , 0, 250);
                        toast.show();
                        onRefresh();
                        break;
                    }
                    default:
                        break;
                }
            }
            catch(Exception e)
            {
            }
        }
    };
}

 

以上是关于Android教学用例程序LBS 2 - 功能设计与实现的主要内容,如果未能解决你的问题,请参考以下文章

Android LBS 学习总结

ssm基于微信小程序的高校课堂教学管理系统--(ssm+uinapp+Mysql)

用例图——远程网络教学系统

如何实现LBS轨迹回放功能?含多平台实现代码

python+requests+pytest+yaml/json+Allure+jenkins+docker接口自动化框架保姆级教学

测试设计-划分用例优先级的依据