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函数中主要由几部分构成:

  1. 权限申请:因为我们这次申请的权限较多,所以我们将要申请的权限放在一个List集合中集体进行授权。授权通过后,调用requestLocation()方法进行位置获取
  2. 位置获取:包括requestLocation和initLocation两个主要方法,initLocation方法对定位的刷新时间,定位方式、显示模式等进行设置。
  3. 回调监听:在监听回调中,创建一个字符串,对其进行组装,并在textview中显示。
  4. 销毁函数:在活动的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特色——基于位置的服务

Android 使用两个不同的代码片段获取当前位置 NULL

android - 离开应用程序时保持谷歌地图片段在位置上放大

如何在不在 android 的 Activity 上添加地图片段的情况下获取我的位置?

停止位置侦听器服务 Android

Android 逆向Android 进程注入工具开发 ( Visual Studio 开发 Android NDK 应用 | Visual Studio 中 SDK 和 NDK 安装位置 )(代码片段