当前位置: 首页 > news >正文

Android 的定位分层架构

Android GPS定位服务的系统架构共分为六层
应用层,系统框架层,JNI层、HAL层、linux内核层、GPS硬件设备层
从上至下它们是逐层依赖的关系,每层依赖下面一层完成其所需提供的服务。
【概要定位流程】:由应用层APP发起定位请求,调用Framework层提供的API接口,此时会去启动一个定位服务的线程,通过LocationManagerService定位服务,会调用到对应的Location provider,然后通过native方法调用到JNI中,JNI获得GpsInterface并传递给接口一个回调函数的实现。GpsInterface是HAL层最主要的实现。

最上面是应用层,可安装基于定位服务的应用,这些应用可以发起定位请求,比如百度地图等。

第二层是框架层(framework层),这一层包含了被APP调用的API以及系统服务的实现,主要由 Java 语言来实现。
a. Java语言实现的API,即android.location包中的内容,主要用来被APP调用
目录:frameworks/base/location/java/android/location
b.系统服务实现
目录1:frameworks/base/location/java/com/android/internal/location
这个目录是Framework对Location服务的内部实现
目录2:framework\base\services\core\java\com\android\server
这个目录中的LocationManagerService.java是Location服务对内部实现的一种封装

JNI层只有一个文件,起到承上启下的作用。上层承接Framework,下层调用HAL层具体硬件抽象实现。
目录:
frameworks/base/services/core/jni/com_android_server_location_GpsLocationProvider.cpp

第四层是共享库层(HAL层),本层由 C 以及 C++ 语言实现, 框架层与共享库层使用 JNI进行衔接。HAL层相当于一个linux应用程序接口,通过open,close等操作,操作硬件设备。
目录:
hardware/qcom/gps
hardware/libhardware/include/hardware/gps.h

第五层是 Linux内核层,整个Android系统都是以Linux内核为基础的。

最底层是GPS硬件设备层

判断App是否获得定位权限

checkPermissionGranted(Manifest.permission.ACCESS_COARSE_LOCATION)
private boolean checkPermissionGranted(String permission) {
     return this.checkPermission(permission, Process.myPid(), Process.myUid()) == PackageManager.PERMISSION_GRANTED;
}

方法二
在API>=23(6.0)的Android系统中,可以使用

ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)

方法三

PackageManager pkgMgr = getPackageManager();
return pkgMgr.checkPermission(permission, getPackageName()) == PackageManager.PERMISSION_GRANTED;

方法一和三在应用targetSdkVerison<23时,固定返回true,无论应用是否获得授权。如果要在API<23时正常使用,建议使用如下方法四

方法四 系统提供的方法
PermissionChecker.checkPermission(this, permission, Process.myPid(), Process.myUid(), getPackageName()) == PackageManager.PERMISSION_GRANTED;
这个方法在23前后都可以使用,但是最好是做版本判断,大于等于23时使用ActivityCompat.checkSelfPermission(),其他的使用方法四

Android 系统中的定位模式

GPS、WLAN和移动网络WLAN和移动网络仅使用GPS
特点同时使用GPS、WIFI及基站定位,速度快、精度高,室内定位效果好。缺点:耗流量、耗电量只使用WIFI和基站定位,需要WIFI或者基站才行,室内效果好。缺点:依赖WIFI或基站,精度一般不依赖WIFI和基站,室内效果差,户外可靠性好。缺点:室内效果差
条件LocationManager.GPS_PROVIDER = true; LocationManager.NETWORK_PROVIDER = true;LocationManager.GPS_PROVIDER = false; LocationManager.NETWORK_PROVIDER = true;LocationManager.GPS_PROVIDER = true; LocationManager.NETWORK_PROVIDER = false;
是否打开定位服务Settings.Secure.LOCATION_MODE = 3Settings.Secure.LOCATION_MODE = 2Settings.Secure.LOCATION_MODE = 1

注:上面的条件判断指的是

1 Log.e("David", "GPS是否打开 " + locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER));
2 Log.e("David", "网络定位是否打开 " + locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER));

android中判断设备定位状态

方法1
使用locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)和locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER),
有任何一个返回true,则可说明系统定位服务是开启的。

boolean flag = false;  
LocationManager locationManager =
        (LocationManager) getSystemService(Context.LOCATION_SERVICE);  
        // 通过GPS卫星定位  
Boolean gps = 
    locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);  
        // GPS辅助定位,AGPS,借助网络  
boolean network = 
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);  
if (gps || network) {  
        flag = true;  
} 

方法2
在API大于等于19时,返回的locationMode与用户的选择息息相关
当定位服务关闭时,Settings.Secure.LOCATION_MODE = 0
当仅使用网络定位时,Settings.Secure.LOCATION_MODE = 1
当仅使用GPS定位时,Settings.Secure.LOCATION_MODE = 2
当使用网络和GPS定位时,Settings.Secure.LOCATION_MODE = 3

public boolean isLocationEnabled() {
    int locationMode = 0;
    String locationProviders;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        try {
            locationMode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
            return false;
        }
        return locationMode != Settings.Secure.LOCATION_MODE_OFF;
    } else {
        locationProviders = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
        return !TextUtils.isEmpty(locationProviders);
    }
}

跳转设置 定位类型页面

跳转设置 定位类型页面

Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);  
startActivity(intent);  

GPS:
定位级别可以精确到街(通过24颗卫星定位,在室外和空旷的地方定位准确、速度快)

AGPS:
通过WLAN或移动网络(3G/2G)确定的位置(也称作AGPS,辅助GPS定位。
主要用于在室内或遮盖物(建筑群或茂密的深林等)密集的地方定位)

相关文章:

  • 基于docker搭建es集群
  • 2.可视化基础(上)
  • 解决Vue项目中ESLint和Prettier冲突问题[Vue.js项目实践: 新冠自检系统]
  • 【misc】buu-面具下的flag——zip伪加密+用NTFS流隐藏文件
  • java毕业设计企业安全与设备管理系统源码+lw文档+mybatis+系统+mysql数据库+调试
  • Message Bus Solace Deeper Dive
  • Android-AGP之手写你的第一款自定义plugin插件
  • 入门力扣自学笔记159 C++ (题目编号788)
  • java毕业设计奇妙店铺电子商务网站源码+lw文档+mybatis+系统+mysql数据库+调试
  • 类与对象(十四)----包package
  • Codeforces Round #820 (Div. 3)A. Two Elevators
  • 实现淘宝购物车RecyclerView或LIstView的嵌套选择的逻辑
  • (pt可视化)利用torch的make_grid进行张量可视化
  • MQTT协议规范总结
  • SAP EWM-拣货队列操作演示实例
  • CSS中外联样式表代表的含义
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • FineReport中如何实现自动滚屏效果
  • github指令
  • KMP算法及优化
  • Mysql数据库的条件查询语句
  • Node项目之评分系统(二)- 数据库设计
  • 产品三维模型在线预览
  • 大整数乘法-表格法
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 回流、重绘及其优化
  • 两列自适应布局方案整理
  • 前端_面试
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 什么是Javascript函数节流?
  • 写给高年级小学生看的《Bash 指南》
  • 大数据全解:定义、价值及挑战
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • #NOIP 2014# day.2 T2 寻找道路
  • #数学建模# 线性规划问题的Matlab求解
  • (1)(1.11) SiK Radio v2(一)
  • (1)Android开发优化---------UI优化
  • (4) PIVOT 和 UPIVOT 的使用
  • (Java)【深基9.例1】选举学生会
  • (javascript)再说document.body.scrollTop的使用问题
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (算法)Game
  • (五)MySQL的备份及恢复
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .NET CF命令行调试器MDbg入门(三) 进程控制
  • .net core使用RPC方式进行高效的HTTP服务访问
  • .NET DataGridView数据绑定说明
  • .NET 反射 Reflect
  • .NET 中让 Task 支持带超时的异步等待
  • .sdf和.msp文件读取
  • @ConditionalOnProperty注解使用说明
  • @DependsOn:解析 Spring 中的依赖关系之艺术