首页 > 其他分享 >【android】Android定位功能开发(1)——获取位置

【android】Android定位功能开发(1)——获取位置

时间:2023-03-07 10:12:30浏览次数:43  
标签:定位 String 位置服务 void 位置 LocationManager provider android Android

基于位置的服务包括三个方面:获取位置、地图服务、地理编码服务。

获取位置有两种方式,一种是通过GPS获得位置,精度高,耗电高,另一种是通过WLAN或通讯基站获得位置,精度低,耗电低。得到的位置信息是三维的,包括经度、纬度、海拔。
地图服务实现的功能是将经纬度点显示在地图上,以及将地图上的点转化为经纬度。通过调用地图服务商(如谷歌、百度、高德等)的API接口,从其服务器上获取地图信息。
地理编码服务实现经纬度点转化为地址,以及地址转化为经纬度。实现方法是通过HTTP协议调用互联网上的地址服务。

 

 

获取位置是所有基于位置的服务的基础,Android获取位置使用LocationManager类。首先获取LocationManager的实例,然后一般要检查位置服务是否开启。如果未开启,就打开设置位置服务界面。如果已开启,再检查应用的定位权限是否允许。都通过了,就可以设置一个位置监听器,有了位置信息就会调用监听器的相应方法。设置监听器时可以设置位置监听的最小时间间隔和最小距离间隔,只有这两个条件都满足时才会有位置信息。流程和关键代码如下图:

 

下面是一个获取位置的例子。例子的界面如下,最上面一行是两项设置,记录位置的最小时间间隔和最小距离,只有这两个条件同时满足,才会产生一个位置数据。第二行是两个按钮,分别启动和停止位置监听。再下面是一个文本,显示监听到的位置信息。

 

 

 

例子中,首先要在onCreate中获取LocationManager实例,并检查设备是否开启了位置服务,代码如下:

manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
if(!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) &&
!manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
askLocationSettings();
}

可以从手机最上面的功能栏中开启/关闭手机的位置服务,如下图:

 

 

 如果位置服务未开启,可以询问用户是否转到位置服务设置界面。位置服务设置界面通过Intent来启动,动作是android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS。代码如下:

void askLocationSettings(){
      AlertDialog.Builder builder = new AlertDialog.Builder(this);
      builder.setTitle("开启位置服务");
      builder.setMessage("本应用需要开启位置服务,是否去设置界面开启位置服务?");
      builder.setPositiveButton("是", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface arg0, int arg1) {
                  Intent intent = new Intent(
     android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                  MainActivity.this.startActivity(intent);
            }
      });
      builder.setNegativeButton("否", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface arg0, int arg1) {
                 Toast.makeText(MainActivity.this, "No location provider to use", 
    Toast.LENGTH_SHORT).show();
            }
      });
      builder.show();
}

位置服务设置界面如下:

 

如果设备开启了位置服务,就可以创建一个位置信息监听器,在监听时需要传给LocationManager。在事件监听方法中将经度、纬度、高度、速度等位置信息输出。代码如下:

listener = new LocationListener(){
      public void onLocationChanged(Location arg0) {
            String txt = "Longitude:" + arg0.getLongitude() 
    + ", Latitude:" +  arg0.getLatitude()
    + ", Altitude" + arg0.getAltitude()
    + ", Speed:" + arg0.getSpeed();    
            // 经度,纬度,高度,速度
            tvResult.append(txt + "\n");
      }
      public void onProviderDisabled(String arg0) {}
      public void onProviderEnabled(String arg0) {}
      public void onStatusChanged(String arg0, int arg1, Bundle arg2) {}
};

启动位置监听需要调用LocationManager的requestLocationUpdates()方法,方法的第一个参数是位置服务提供者。一个设备上可能有多个位置服务提供者,比如gps,wifi,北斗等,所以要先根据定位需求寻找一个最匹配的提供者,使用的方法是LocationManager的getBestProvider()方法。另外,获取当前位置需要一定的时间,而有些应用又已启动就需要一个定位信息,此时可以使用上次使用时的最后已知位置。该位置保存在缓存中,可以通过LocationManager的getLastKnownLocation()方法获得。具体代码如下:

 void startListening(){
        Criteria crt = new Criteria();                        // 位置监听标准
        crt.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);    // 水平精度高
        crt.setAltitudeRequired(true);                        // 需要高度
        String provider = manager.getBestProvider(crt, true);    // 寻找最匹配的provider
        Location l = manager.getLastKnownLocation(provider);    // 取最后已知位置,即缓存中的位置
        if(l!=null)    tvResult.append(provider + "-LastKnown:" + l.toString() + "\n");
        long period = Long.parseLong(etPeriod.getText().toString());        // 最小时间间隔
        int distance = Integer.parseInt(etDistance.getText().toString());    // 最小距离
        manager.requestLocationUpdates(provider, period*1000, distance, listener);    // 开始监听
        tvResult.append(provider + "-Location listener started.\n");
}

Android6.0以上系统需要应用运行时进行动态权限申请,所以在开始监听位置前需要检查权限,如果没有许可就进行询问。主要代码是:

if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 101);
            return;
}

停止位置监听使用LocationManager的removeUpdates()方法,代码如下:

manager.removeUpdates(listener);
tvResult.append("Location listener stoped.\n");

监听位置需要在配置文件里声明权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

例子中用到的相关类包括:

1)android.location.LocationManager类,方法有:

boolean isProviderEnabled(String provider):返回提供位置的provider是否开启,provider的取值一般为LocationManager.GPS_PROVIDER或LocationManager.NETWORK_PROVIDER
String getBestProvider(Criteria criteria, boolean enabledOnly):返回与要求最匹配的provider,criteria为精度等要求,enabledOnly为true时只匹配已开启的provider,返回值一般为LocationManager.GPS_PROVIDER、LocationManager.NETWORK_PROVIDER或LocationManager.PASSIVE_PROVIDER(从其他应用获得位置)
Location getLastKnownLocation(String provider):返回上次已知位置,是上次获取位置时存放在缓存中的,不一定准确反映现在位置。若provider未开启会返回null。
void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener):注册当前Activity来接收provider提供的位置信息。位置信息周期性产生,最小时间间隔为minTime毫秒,最小距离间隔为minDistance米,产生后会调用listener的onLocationChanged方法。minTime越小,位置服务搜索越频繁,耗电越多,最好不要小于60000毫秒。此方法必须在主线程中调用。
void removeUpdates(LocationListener listener):移除位置监听器
void requestLocationUpdates(String provider, long minTime, float minDistance, PendingIntent intent):位置变化后以广播PendingIntent的形式通知,可以在子线程中调用。
void removeUpdates(PendingIntent intent):移除位置通知广播
2)android.location.Criteria类,方法有:

void setHorizontalAccuracy(int accuracy):设置水平精度要求,accuracy取值为Criteria.ACCURACY_HIGH,ACCURACY_MEDIUM,ACCURACY_LOW
void setAltitudeRequired(boolean altitudeRequired):设置是否需要高度数据
3)android.location.Location类,方法有:

double getLongitude():返回经度
double getLatitude():返回纬度
double getAltitude():返回高度
float getSpeed():返回速度,单位米/秒
4)android.location.LocationListener接口,方法有:

void onLocationChanged(Location location):位置变化时调用
void onProviderDisabled(String provider):用户关闭provider时调用
void onProviderEnabled(String provider):用户开启provider时调用
void onStatusChanged(String provider, int status, Bundle extras):provider状态变化时调用,如GPS信号无法获得等
【参考连接】

Android定位功能开发(1)——获取位置

 

标签:定位,String,位置服务,void,位置,LocationManager,provider,android,Android
From: https://www.cnblogs.com/opensmarty/p/17187076.html

相关文章

  • Android systrace命令行工具
    命令行工具systrace(SystemTrace)跟踪的是系统级的内容,如CPU各核心调度,SurfaceFlinger、VSync(垂直同步)、BufferQueue。通过收集系统事件和App逻辑中插入的自定义事件的组合......
  • 关于Android Studio的Activity的页面跳转完成
    第一种方式Intentintent=newIntent();intent.setClass(this,MainActivity3.class);startActivity(intent);第二种方式Intentintent=newIntent();intent.setClas......
  • 解决Android SDK Manager无法更新以及更新缓慢问题
    打开..\Android\sdk\SDKManager.exe按下图进行设置如果更新缓慢,可以更换HTTPProxyServer(详见http://www androiddevtools.cn,目前mirrors.neusoft.edu.cn......
  • 【Android Studio】通过编辑setting.gradle文件,添加阿里仓库
    本人对AndroidStudio的了解非常初级,这篇blog主要是自用备忘性质。因为众所周知的原因,国外仓库访问很不方便,影响项目构建。所以需要添加国内仓库,而阿里云仓库属于比较知名......
  • Android发布aar到Maven仓库
    目录一、配置步骤方式一方式二(推荐)二、引用私有仓库的依赖三、方式一完整配置示例附录一、配置步骤方式一在要发布的子模块的build.gradle文件中做如下配置:添加m......
  • android 访问域名接口报错
    1.移动端访问https域名及接口,显示java.net.UnknownHostException:Unabletoresolvehost"xxx":Noaddressassociatedwithhostname2.使用okhttp访问的接口,......
  • 【Android逆向】反调试绕过(nop 绕过)
    1.这是看雪上的一个题目,要求显示出itissuccesshttps://www.kanxue.com/work-task_read-800648.htm第三题2.apk安装到手机,发现闪退3.apk拖入到jadx中,观察public......
  • android | 静态注册广播接收器的坑
    android|静态注册广播接收器的坑按书上写的并不能正常接收,查了一下是这个原因:反正就是要加上包名类名,有点离谱哦。具体如下: btn.setOnClickListener(newView.OnCli......
  • Android--aar打包
    文章目录一、aar包和jar包二、打aar包1.Module中不含有其它aar2.Module中嵌套第三方aar3.fat-aar-android的简单用法一、aar包和jar包Android中常见的第三方库包括:.so、.ja......
  • 【android】MediaRecorder录音录像
    前言Android除了支持播放多媒体文件之外,还可以从对应的硬件中捕获多媒体,比如从麦克风录音、从摄像头录像等。本篇博客讲解一下Android下如何通过MediaRecorder进行录......