【Anroid学习笔记】 基于位置的安卓开发

定位方式

GPS定位:基于手机内置的GPS硬件直接和卫星交互来获取当前的经纬度信息,精确度高

网络定位:根据手机当前网络附近的三个基站进行测速,以此计算出手机和每个基站的距离,再通过三角定位确定出一个大概的位置,精确度一般

 

申请百度API Key

1 登录百度账号,打开http://developer.baidu.com/user/reg填写注册信息,只需要填写带有“*”号的那部分内容,然后提交。

 

2 打开自己的邮箱,点击百度发送给我们的验证邮件中的链接,完成注册。

 

3 访问http://lbsyun.baidu.com/apiconsole/key这个地址,同意百度开发者协议。

 

4 点击创建应用就可以去申请API Key了,应用名称可以随便填,应用类型选择Android SDK,启动服务保持默认即可。开发版SHA1和发布版SHA1指的是打包程序时所有的签名文件的SHA1指纹,可以通过Android Studio查看到。选中项目,点击右侧工具栏的Gradle——>项目名——>app——>Tasks——>android,其中singingReport这个Task就可以用来查看签名文件信息。

其中的SHA1码是Android自动生成的一个用于测试的签名文件,当你的应用程序发布时还需要创建一个正式的签名文件,如果要得到它的指纹,可以在cmd中输入如下命令:keytool -list -v -keystore <签名文件路径>

 

5 将SHA1码和项目包名(如:com.example.lbstest)填入,点击提交,应用就创建成功了。其中的长串字符串就是申请到的API Key。

 

使用百度定位

准备LBS SDK

1 先将百度平台提供的SDK准备好,下载地址是:http://lbsyun.baidu.com/sdk/download。后续会用到基础地图和定位功能这两个SDK,将它们勾选上,然后点击"开发包"下载按钮即可。

 

2 下载后对该压缩包解压,其中会有一个libs目录,libs目录下的内容又分为两部分,BaiduLBS_Android.jar这个文件是Java层要使用到的,其他目录下的so文件是Native层要用到的。

 

3 我们需要将libs目录下的每个文件都放置到正确的位置上。将BaiduLBS_Android.jar文件复制到app目录下的libs目录中;接下来展开src/main目录,右键新建一个名为jniLibs的目录,专门用来存放so文件,然后将压缩包里的其他所有目录直接复制到这里。

 

4 手动点击Android Studio顶部工具栏的Sync按钮,之后libs目录下的jar文件就会多出一个向右的箭头,这就表示项目已经能引用到这些包了。

 

确定自己位置的经纬度

修改AndroidManifest.xml文件代码如下:

 
     
     
     
     
     
     
     
     
     
     
    
     
         
        ... 
         
         
     

先申请权限,每一个权限都是LBS SDK内部要用到的。在标签的内部添加了一个标签,这个标签的android:name部分是固定的,必须填com. baidu.lbsapi.API_KEY,android:value部分填写从百度申请到的API KEY。最后,再注册一个LBS SDK中的服务。

 

修改MainActivity中的代码如下:

class MainActivity extends AppCompatActivity{ 
    public LocationClient mLocationClient; 
    private TextView positionText; 

    onCreate(){ 
        //调用getApplicationContext()传入一个全局的Context对象 
        mLocationClient = new LocationClient(getApplicationContext()); 
        //注册定位监听器,当获取到未知信息时,就会回调这个定位监听器         
        mLocationClient.registerLocationListener(new MyLocationListener()); 
        List permissionList = new ArrayList<>(); 
        //将未授权的权限添加进list     
        if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest. 
        permission.ACCESS_FINE_LOCATION)!=PackageManager.PERMISSION_GRANTED){     
            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION); 
        } 
        if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest. 
        permission.READ_PHONE_STATE)!=PackageManager.PERMISSION_GRANTED){     
            permissionList.add(Manifest.permission.READ_PHONE_STATE); 
        } 
        if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest. 
        permission.WRITE_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){ 
            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); 
        } 
        if(!permissionList.isEmpty()){ 
            //将未授权的权限数组传入ActivityCompat.requestPermissions() 
            //方法中,批量请求授权 
            String[] permissions = permissionList.toArray(new String
            [permissionList.size()]);     
            ActivityCompat.requestPermissions(MainActivity.this,permissions,1); 
        }else{ 
            requestLocation(); 
        } 
    } 

    //请求定位,定位的结果会回调到刚才注册的监听器中 
    requestLocation(){ 
        mLocationClient.start(); 
    } 

    onRequestPermissionResult(){ 
        switch(requestCode){ 
            case 1: 
                if(grantResults.length > 0){ 
                    for(int result : grantResults){         
                        if(result!=PackageManager.PERMISSION_GRANTED){             
                            Toast.makeText(this,"必须同意所有权限才能使用本程序",     
                            Toast.LENGTH_SHORT).show(); 
                            finish(); 
                            return; 
                        } 
                    } 
                    requestLocation(); 
                }else{ 
                    Toast.makeText(this,"发生未知错误",Toast.LENGTH_SHORT).show();             
                    finish(); 
                } 
                break; 
            default: 
        } 
    } 

    class MyLocationListener implements BDLocationListener{ 
        //每次收到定位信息时执行 
        void onReceiveLocation(BDLocation location){ 
            runOnUiThread(new Runnable(){ 
                run(){ 
                    StringBuilder currentPosition = new StringBuilder();         
                    currentPosition.append("纬度:").append(location. 
                    getLatitude()).append("\n"); 
                    currentPosition.append("经度:").append(location. 
                    getLongitude()).append("\n"); 
                    currentPosition.append("定位方式:");         
                    if(location.getLocType()==BDLocation.TypeGpsLocation){         
                         currentPosition.append("GPS"); 
                    }else if(location.getLocType()==BDLocation. TypeNewWorkLocation){ 
                        currentPosition.append("网络"); 
                    } 
                    positionText.setText(currentPosition); 
                } 
            }); 
        } 

        onConnectHotSpotMessage(String s,int i){ 
        } 
    } 
}

 

在默认情况下,调用LocationClient中的start()方法只会定位一次,百度LBS SDK提供了一系列设置方法,来允许我们更改默认的行为,修改MainActivity如下:

requestLocation(){ 
    initLocation(); 
    mLocationClient.start(); 
} 

initLocation(){ 
    LocationClientOption option = new LocationClientOption(); 
    //设置更新位置的时间间隔 
    option.setScanSpan(5000); 
    //为mLocationClient对象设置选项 
    mLocationClient.setLocOption(option); 
} 

onDestroy(){ 
    super.onDestroy(); 
    //活动销毁时记得停止定位,否则程序会在后台不断定位,消耗手机电量 
    mLocationClient.stop(); 
}

 

选择定位模式

开启了GPS定位功能后,我们可以在initLocation()方法中对百度LBS SDK的定位模式进行指定,一共有三种模式可以选择:

 

Hight_accuracy 高精确度模式,会在GPS信号正常的情况下优先使用GPS定位,在无法接收GPS信号的时候使用网络定位。

Battery_Saving 节电模式,只会使用网络定位。

Device_Sensors 传感器模式,只会使用GPS定位。

 

在手机设置里,可以选择使用哪种定位模式。

 

当然,我们也可以强制指定只使用GPS进行定位,修改MainActivity如下:

void initLocation(){ 
    LocationClientOption option = new LocationClientOption(); 
    option.setScanSpan(5000); 
    //指定定位模式为传感器模式     
    option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors);     
    mLocationClient.setLocOption(option); 
}

 

看得懂的位置信息

修改MainActivity如下:

initLocation(){ 
    LocationClientOption option = new LocationClientOption(); 
    option.setScanSpan(5000); 
    //表示需要获取更详细的信息 
    option.setIsNeedAddress(true); 
    mLocationClient.setLocOption(option); 
} 

class MyLocationListener implements BDLocationListener{ 
    onReceiveLocation(BDLocation location){ 
        runOnUiThread(new Runnable(){ 
            run(){ 
                StringBuilder currentPosition = new StringBuilder();     
                currentPosition.append("纬度:").append(location.     
                getLatitude()).append("\n"); 
                currentPosition.append("经度:").append(location. 
                getLongitude()).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"); 
                urrentPosition.append("街道:").append(location. 
                getStreet()).append("\n"); 
                currentPosition.append("定位方式:");             
                if(location.getLocType()==BDLocation.TypeGpsLocation){             
                    currentPosition.append("GPS"); 
                }else if(location.getLocType()==BDLocation. TypeNewWorkLocation){
                    currentPosition.append("网络"); 
                } 
                positionText.setText(currentPosition); 
            } 
        }); 
    }
}

 

使用百度地图

让地图显示出来

修改activity_main.xml中的代码:

 
     

 

修改MainActivity中的代码:

class MainActivity{ 
    private MapView mapView; 

    onCreate(){ 
        ... 
        //初始化,必须在setContentView方法前执行 
        SDKInitializer.initialize(getApplicationContext);         
        setContentView(R.layout.activity_main); 
        mapView = (MapView)findViewById(R.id.bmapView); 
        ... 
    } 

    onResume(){ 
        super.onResume(); 
        mapView.onResume(); 
    } 

    onPause(){ 
        super.onPause(); 
        mapView.onPause(); 
    } 

    onDestroy(){ 
        super.onDestroy(); 
        mLocationClient.stop(); 
        mapView.onDestroy(); 
    } 
}

 

移动到我的位置

百度LBS SDK的API中提供了一个BaiduMap类,它是地图的总控制器:

BaiduMap baiduMap = mapView.getMap();

 

百度地图缩放级别的值在3~19之间,小数点可取,值越大地图越精细:

//设置缩放级别 
MapStatusUpdate update = MapStatusUpdateFactory.zoomTo(12.5f); 
//完成缩放 
baiduMap.animateMapStatus(update);

 

借助LatLng类可以让地图移动到一个经纬度上,它的构造方法一共有两个参数,第一个参数存放纬度值,第二个参数存放经度值。之后调用MapStatusUpdateFactory的newLatLng()方法将LatLng对象传入,再将newLatLng()方法返回的MapStatusUpdate对象传入到BaiduMap的animateMapStatus()方法中,就可以将地图移动到指定的经纬度上了。写法如下:

LatLng ll = new LatLng(39.915,116.404); 
MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll); 
baiduMap.animateMapStatus(update);

 

修改MainActivity中的代码如下:

class mainActivity{ 
    private BaiduMap baiduMap; 
    private boolean isFirstLocate = true; 

    onCreate(){ 
        ... 
        baiduMap = mapView.getMap(); 
    } 
    
    navigateTo(BDLocation location){ 
        //第一次定位的时候移动下地图就够了 
        if(isFirstLocate){ 
            Latlng ll = new LatLng(location.getLatitude(),location.getLongitude());     
            MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);     
            baiduMap.animateMapStatus(update); 
            update = MapStatusUpdateFactory.zoomTo(16f); 
            baiduMap.animateMapStatus(update); 
            isFirstLocate = false; 
        } 
    } 

    class MyLocationListener implements BDLocationListener{ 
        onReceiveLocation(BDLocation location){         
            if(location.getLocType()==BDLocation.TypeGpsLocation     
            ||location.getLocType()==BDLocation.TypeNetworkLocation){ 
                navigateTo(location); 
            } 
        } 
    } 
}

 

将“我”显示在地图上

LBS SDK提供了一个MyLocationData.Builder类,这个类时用来封装设备当前所在位置的,我们只需将经纬度信息传到这个类的相应方法当中就可以了:

MyLocationData.Builder locationBuilder = new MyLocationData.Builder(); 
locationBuilder.latitude(39.915); locationBuilder.longitude(116.404);

将设备当前的位置显示在地图上:

MyLocationData locationData = locationBuilder.build(); 
baiduMap.setMyLocationData(locationData);

修改MainActivity代码如下:

class MainActivity{ 
    onCreate(){ 
        ... 
        //必须开启获取当前设备位置的功能 
        baiduMap.setMyLocationEnabled(true); 
    } 

    navigateTo(BDLocation location){ 
        if(isFirstLocate){ 
            ... 
        } 
        MyLocationData.Builder locationBuilder = new MyLocationData.Builder();     
        locationBuilder.latitude(location.getLatitude()); 
        locationBuilder.longitude(location.getLongitude()); 
        MyLocationData locationData = locationBuilder.build(); 
        baiduMap.setMyLocationData(locationData); 
    } 

    onDestroy(){ 
        ... 
        baiduMap.setMyLocationEnabled(false); 
    } 
}

 

你可能感兴趣的:(Android,LBS,GPS,Android学习笔记)