Android development: Obtain location information, the number of satellite signals and the number of satellites involved in positioning based on native API

overview

Recently, I have been working on a related demo of indoor and outdoor seamless positioning. In outdoor positioning, the GNSS positioning method has the advantages of high precision and low cost, and the Android platform also provides native APIs for positioning, which can be easily implemented. Theoretically, the GNSS positioning method requires at least 4 satellites to obtain position information. Therefore, the indoor positioning method or the GNSS method can be selected based on the number of effective satellites (that is, the seamless switching function is realized based on the number of satellites).
This article records the method of using the Android native API to obtain location information, the method of obtaining the number of satellite signals received, and the method of obtaining the number of satellite signals participating in positioning.

Apply for permission and turn on GPS

First, you need to apply for permission in the AndroidManifest file, the code is as follows:

<!-- rough location permission -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- fine location permission -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Starting from Android 6.0, Google divides permissions into normal permissions and dangerous permissions. Dangerous permissions need to be applied to the user again at runtime. Location information is a dangerous permission. Therefore, you need to apply for the permission again in the Activity. The specific code is as follows:

// 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;
}

After the permission application is completed,
register a LocationManager. LocationManager is a class officially provided by Android for managing location information, which provides access to system location services. These services allow applications to obtain periodic updates of the device's geographic location, or to be notified when the device approaches a given geographic location. See the official documentation for details. code show as below:

LocationManager mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

At the same time, make sure that the mobile device turns on the GPS, the method code is as follows:

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;
}

After that, call the above sub-method in the onCreate() method.

Call the native API for positioning

requestLocationUpdates(provider: String, minTimeMs: Long, minDistanceM: Float, listener: LocationListener) is a method of the LocationManager class, which can obtain location information from a given Provider, and call LocationListener when the location is updated (the first method of the above method four parameters) onLocationChanged() method. LocationListener is used to receive notifications. When the LocationListener has been registered to the LocationManager and the location of the device changes, the relevant methods in the LocationListener will be called.
First write a subclass of LocationListener and rewrite the onLocationChanged() method in it. The specific code is as follows:

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");
    }
};

Then register the custom LocationListener to the LocationManager, the specific code is as follows:

mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000, 0,locationListener);

The location information can be obtained through the above steps.

Get the number of satellite signals received by the device

GnssStatus.Callback is a class used to receive notifications when GNSS events occur, and the registerGnssStatusCallback() method is used to register a custom GnssStatus.Callback class to the LocationManager class.
First, customize an internal class inherited from GnssStatus.Callback, and rewrite the onSatelliteStatusChanged() method in it. The specific code is as follows:

@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 + "个");
    }
};

Then register mGNSSCallback to LocationManager, the specific code is as follows:

mLocationManager.registerGnssStatusCallback(locaCallback);

Through the above steps, the statistics of the number of satellite signals received by the device can be realized.
Note that because the current GNSS system includes GPS, GLONASS, BEIDOU, etc., the official API provided by Android can also determine the GNSS system to which the satellite belongs, by calling the status.getConstellationType(i) method. Taking Beidou satellite statistics as an example, you can add the following code in the onSatelliteStatusChanged() method:

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);
}

Obtain the number of satellite signals used for positioning

Android does not necessarily use all received satellite signals in the positioning algorithm, and will eliminate satellite signals with low reliability based on altitude angle and signal-to-noise ratio.
Android officially provides the encapsulation method status.usedInFix(i), which returns a boolean value, which can be directly used to determine whether the satellite signal is used for positioning, such as adding a judgment statement:

if (status.usedInFix(i)) {
    
    
    BDSInFix++;
}

Results map

Results map

Guess you like

Origin blog.csdn.net/weixin_46269688/article/details/124044784