获取手机定位经纬度js Android开发:基于原生API获得位置信息、卫星信号个数及参与定位的卫星个数
目录
概述
最近在做室内外无缝定位的相关demo,室外定位中,GNSS定位方式具备效率高、成本低等特点,而且Android系统也提供了原生API用于定位,可以很便利地进行功能实现。GNSS定位方式理论上最少必须4颗卫星能够获得位置信息,因此,可以基于有效卫星数判定选择使用室内定位方式而是GNSS方法(即基于卫星数推动无缝切换功能)。
本文记录了使用Android原生API获得位置信息的方式、获取接收到的卫星讯号个数的方式或者获得参与定位的卫星信号个数的方式。
权限申请及开启GPS
首先必须在AndroidManifest文件上面进行权限申请,代码如下:
<!-- rough location permission -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- fine location permission -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
从Android6.0开始获取手机定位经纬度js,Google将权限分为正常权限与危险权限,危险权限应该在运行时再度向用户申请。位置信息属于危险权限,因此,需要在Activity里面对权限再次进行申请,具体代码如下:
// get location permission again
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 0);
return;
}
权限申请完成后,
注册一个LocationManager。LocationManager是Android官方提供的用于管理位置信息的一个类,该类提供对平台位置服务的访问。这些服务允许应用程序取得设施的物理位置的周期性升级,或者当设备接近一个给定的地理位置时受到通知。具体可以看官网文档。代码如下:
LocationManager mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
同时,确保移动设施进入GPS,方法代码如下:
void insureGPSisOpen(LocationManager locationManager) {
// judge whether the GPS is open
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Toast.makeText(getApplicationContext(), "请开启GPS导航...", Toast.LENGTH_SHORT).show();
// trun to the GPS setting page
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivityForResult(intent, 0);
return;
}
Log.d(TAG, "insureGPSisOpen");
return;
}
之后获取手机定位经纬度js,在onCreate()方式里调用上述子步骤。
调用原生API进行定位
requestLocationUpdates(provider:String,minTimeMs:Long,minDistanceM:Float,listener:LocationListener)是LocationManager类的一个方式,该办法无法从给定的Provider中获得位置信息,并在位置更新时调用LocationListener(上述方式的第四个参数)的onLocationChanged()方式。LocationListener用于接收通知,当LocationListener已经注册到LocationManager且设备位置出现变化时,将调用LocationListener里的相关手段。
首先编写一个LocationListener的类库并重写其中的onLocationChanged()方式,具体代码如下:
LocationListener locationListener = new LocationListener() {
@Override
// callback func when the location changed
public void onLocationChanged(@NonNull Location location) {
mTvLatitude.setText("纬度:" + location.getLatitude());
mTvLongitude.setText("经度:" + location.getLongitude());
// change the flag, to record cur status
Log.d(TAG, "onLocationChanged");
}
};
之后将自定义的LocationListener注册到LocationManager中,具体代码如下:
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000, 0,locationListener);
通过上述方法能够获得位置信息。
获得设备收到的卫星信号个数
GnssStatus.Callback是用于接收GNSS事件出现时的通知的类,而registerGnssStatusCallback()方式用于将自定义的GnssStatus.Callback类注册到LocationManager类中。
首先自定义一个外部类继承自GnssStatus.Callback,并重写其中的onSatelliteStatusChanged()方式,具体代码如下:
@RequiresApi(api = Build.VERSION_CODES.N)
GnssStatus.Callback mGNSSCallback = new GnssStatus.Callback() {
@Override
public void onSatelliteStatusChanged(@NonNull GnssStatus status) {
super.onSatelliteStatusChanged(status);
// get satellite count
satelliteCount = status.getSatelliteCount();
mTvSatelliteCount.setText("共收到卫星信号:" + satelliteCount + "个");
}
};
之后将mGNSSCallback注册到LocationManager中,具体代码如下:
mLocationManager.registerGnssStatusCallback(locaCallback);
通过上述方法能够推动设备收到的卫星信号个数的统计。
注意,因为这次的GNSS系统包含GPS、GLONASS、BEIDOU等,Android官方提供的API也可以判定卫星所属的GNSS系统,通过读取status.getConstellationType(i)方式推动。以谋求北斗卫星统计为例,可以在onSatelliteStatusChanged()方式里添加如下代码:
if(satelliteCount > 0) {
for (int i = 0; i < satelliteCount; i++) {
// get satellite type
int type = status.getConstellationType(i);
if(GnssStatus.CONSTELLATION_BEIDOU == type) {
// increase if type == BEIDOU
BDSatelliteCount++;
}
}
Log.d(TAG, "BDS count:" + BDSatelliteCount);
}
获取用于定位的卫星信号个数
Android不一定将所有收到的卫星信号都用于定位算法中,会基于高度角、信噪比等剔除可信度不高的卫星信号。
Android官方提供封装方式status.usedInFix(i),该方式返回boolean值,可以直接用于判定该卫星信号能否用于定位,如降低判断语句:
if (status.usedInFix(i)) {
BDSInFix++;
}
成果图