Android特色——基于位置的服务
Posted Mask_D
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android特色——基于位置的服务相关的知识,希望对你有一定的参考价值。
一 使用百度地图
1.申请api key
在申请百度地图api key时,需要两个SHA1,一个是发布版的SHA1,一个是开发版SHA1。我们目前可以两个都填写开发版SHA1。
在as中右侧的属性栏中:
其中在run中就会显示出SHA1开发版指纹,如下:
2.配置相关文件
在下载文件解压后,主要分为两部分,一部分是文件夹中包含的.so文件,一部分是java的jar包。
配置中,将所有的jar包复制到目录中app/libs中。将所有的so文件直接复制到app/src/main中新建的一个jniLibs文件夹中。整体如下:
此外,在app/build.gradle中:
dependencies { implementation fileTree(dir: \'libs\', include: [\'*.jar\']) }
表示使用所有的jar包,但是我们的jar包是复制的,所以还需要点击sync进行配置。
在androidManifest.xml中修改文件较多,首先添加了很多权限,都是百度sdk需要用到的。
然后添加了一个meta-data标签,这个标签的android:name是固定的,必须是com.baidu.lbsapi.API_KEY,而value则是刚才申请到的api key。
在之后还注册一个lbs sdk中的服务。如下:
1 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 2 package="com.example.lbstest"> 3 4 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 5 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 6 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> 7 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 8 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> 9 <uses-permission android:name="android.permission.READ_PHONE_STATE"/> 10 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 11 <uses-permission android:name="android.permission.INTERNET"/> 12 <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> 13 <uses-permission android:name="android.permission.WAKE_LOCK"/> 14 15 <application 16 android:allowBackup="true" 17 android:icon="@mipmap/ic_launcher" 18 android:label="@string/app_name" 19 android:roundIcon="@mipmap/ic_launcher_round" 20 android:supportsRtl="true" 21 android:theme="@style/AppTheme"> 22 <meta-data 23 android:name="com.baidu.lbsapi.API_KEY" 24 android:value="EDbklpKPGOwY9odAqS1syZ7GNjZp1X3c"/> 25 26 <activity android:name=".MainActivity"> 27 <intent-filter> 28 <action android:name="android.intent.action.MAIN" /> 29 30 <category android:name="android.intent.category.LAUNCHER" /> 31 </intent-filter> 32 </activity> 33 34 <service android:name="com.baidu.location.f" 35 android:enabled="true" 36 android:process=":remote"> 37 </service> 38 39 </application> 40 41 </manifest>
二 定位实例
1.布局
在布局中只是放一个Textview,用来显示我们获取到的定位信息。
2.MainActivity
1 public class MainActivity extends AppCompatActivity { 2 3 public LocationClient mLocationClient; 4 private TextView positionText; 5 6 @Override 7 protected void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.activity_main); 10 positionText = (TextView) findViewById(R.id.position_text_view); 11 12 mLocationClient = new LocationClient(getApplicationContext());//创建实例,传入全局context参数 13 /*注册一个定位监听器,当获取到位置信息后回调这定位监听器*/ 14 mLocationClient.registerLocationListener(new MyLocationListener()); 15 16 /*因为申请的权限中有三个权限需要对用户进行询问,在这里进行一次性授权 17 * 1.新建一个List集合,依次判断3个权限有没有授权,如果没有加入到list中 18 * 2.将list转化为数组,调用ActivityCompat.requestPermissions()方法一次性申请*/ 19 List<String> permissionList = new ArrayList<>(); 20 if (ContextCompat.checkSelfPermission(MainActivity.this, 21 Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 22 permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION); 23 } 24 if (ContextCompat.checkSelfPermission(MainActivity.this, 25 Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { 26 permissionList.add(Manifest.permission.READ_PHONE_STATE); 27 } 28 if (ContextCompat.checkSelfPermission(MainActivity.this, 29 Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { 30 permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); 31 } 32 /*如果申请权限列表不为空,则申请权限列表中的权限,否则直接进行返回位置信息方法requestLocation()*/ 33 if (!permissionList.isEmpty()) { 34 String[] permissions = permissionList.toArray(new String[permissionList.size()]); 35 ActivityCompat.requestPermissions(MainActivity.this, permissions, 1); 36 } else { 37 requestLocation(); 38 } 39 } 40 41 /*定位的具体方法,具体的定位结果会回调到监听器中。*/ 42 private void requestLocation() { 43 initLocation(); 44 mLocationClient.start(); 45 } 46 47 private void initLocation() { 48 LocationClientOption option = new LocationClientOption(); 49 option.setScanSpan(5000); //设置更新的间隔--5s 50 option.setIsNeedAddress(true);//需要获取详细的地址信息 51 mLocationClient.setLocOption(option); 52 } 53 54 /*在活动被销毁的时候要关闭定位,不然会在后台一直定位,耗费电量。*/ 55 @Override 56 protected void onDestroy(){ 57 super.onDestroy(); 58 mLocationClient.stop(); 59 } 60 61 /*申请权限的回调函数*/ 62 @Override 63 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResult) { 64 switch (requestCode) { 65 case 1: 66 if (grantResult.length > 0) { 67 /*采用一个循环将每个申请的权限进行判断*/ 68 for (int result:grantResult){ 69 if(result!=PackageManager.PERMISSION_GRANTED){ 70 Toast.makeText(this,"必须同意所有权限才能使用", 71 Toast.LENGTH_LONG).show(); 72 finish(); 73 return; 74 } 75 } 76 requestLocation(); 77 }else { 78 Toast.makeText(MainActivity.this,"发送未知错误", 79 Toast.LENGTH_LONG).show(); 80 } 81 break; 82 default: 83 break; 84 } 85 } 86 87 public class MyLocationListener implements BDLocationListener { 88 89 @Override 90 public void onReceiveLocation(final BDLocation bdLocation) { 91 runOnUiThread(new Runnable() { 92 @Override 93 public void run() { 94 /*组装一个字符串,加入获取经度和纬度,加入定位方式,在textview中显示*/ 95 StringBuilder currentPosition = new StringBuilder(); 96 /*获取经度和纬度*/ 97 currentPosition.append("纬度:").append(bdLocation.getLatitude()).append("\\n"); 98 currentPosition.append("经度:").append(bdLocation.getLongitude()).append("\\n"); 99 currentPosition.append("国家:").append(bdLocation.getCountry()).append("\\n"); 100 currentPosition.append("省:").append(bdLocation.getProvince()).append("\\n"); 101 currentPosition.append("市:").append(bdLocation.getCity()).append("\\n"); 102 currentPosition.append("区:").append(bdLocation.getDistrict()).append("\\n"); 103 currentPosition.append("街道:").append(bdLocation.getStreet()).append("\\n"); 104 currentPosition.append("定位方式:"); 105 if(bdLocation.getLocType()==BDLocation.TypeGpsLocation){ 106 currentPosition.append("GPS"); 107 }else if(bdLocation.getLocType()==BDLocation.TypeNetWorkLocation){ 108 currentPosition.append("网络"); 109 } 110 positionText.setText(currentPosition); 111 } 112 }); 113 } 114 /*@Override 115 public void onConnectHopSpotMessage(String s,int i){ 116 117 }*/ 118 } 119 }
MainActivity函数中主要由几部分构成:
- 权限申请:因为我们这次申请的权限较多,所以我们将要申请的权限放在一个List集合中集体进行授权。授权通过后,调用requestLocation()方法进行位置获取
- 位置获取:包括requestLocation和initLocation两个主要方法,initLocation方法对定位的刷新时间,定位方式、显示模式等进行设置。
- 回调监听:在监听回调中,创建一个字符串,对其进行组装,并在textview中显示。
- 销毁函数:在活动的onDestroy()方法中,要将定位进行销毁,否则会造成电量损耗。
3.显示出地图
布局代码如下:将textview先屏蔽,先建立一个Mapview
1 <TextView 2 android:id="@+id/position_text_view" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content" 5 android:text="nothing" 6 android:visibility="gone"/> 7 8 <com.baidu.mapapi.map.MapView 9 android:id="@+id/bmapView" 10 android:layout_width="match_parent" 11 android:layout_height="match_parent" 12 android:clickable="true"/>
然后修改MainActivity如下:
1 @Override 2 protected void onCreate(Bundle savedInstanceState) { 3 4 ··· 5 /*设置一个初始化方式,传入一个全局的context参数*/ 6 SDKInitializer.initialize(getApplicationContext()); 7 mapView = (MapView) findViewById(R.id.bmapView); 8 ··· 9 } 10 11 @Override 12 protected void onResume(){ 13 super.onResume(); 14 mapView.onResume(); 15 } 16 @Override 17 protected void onPause(){ 18 super.onPause(); 19 mapView.onPause(); 20 } 21 22 /*在活动被销毁的时候要关闭定位,不然会在后台一直定位,耗费电量。*/ 23 @Override 24 protected void onDestroy(){ 25 super.onDestroy(); 26 mLocationClient.stop(); 27 mapView.onDestroy(); 28 }
在初始化中加入一些地图初始化,传入全局context。还需要重写onDestroy,onPause,onResume三个方法,对MapView进行管理,保证资源能及时的得到释放。
以上是关于Android特色——基于位置的服务的主要内容,如果未能解决你的问题,请参考以下文章
Android 使用两个不同的代码片段获取当前位置 NULL
android - 离开应用程序时保持谷歌地图片段在位置上放大
如何在不在 android 的 Activity 上添加地图片段的情况下获取我的位置?
Android 逆向Android 进程注入工具开发 ( Visual Studio 开发 Android NDK 应用 | Visual Studio 中 SDK 和 NDK 安装位置 )(代码片段