能否通过Android Fused Location Provider Client获取NMEA语句?
Great question! The short answer is: No, you can't directly get raw NMEA sentences via the Fused Location Provider (FLP) Client.
Let me break down why, and what you can do instead:
Why FLP Doesn't Support NMEA
The Fused Location Provider is built as a high-level, simplified API. It takes data from multiple sources (GPS, Wi-Fi, cell towers, sensors), processes it to deliver optimized, reliable location updates, and intentionally hides low-level details like raw NMEA strings. Its core goal is to make location access easy for developers, not to expose raw GNSS hardware data.
The Alternative: Use LocationManager
If you need raw NMEA sentences, you’ll have to use the lower-level LocationManager API, which gives direct access to GNSS receiver data. Here’s a step-by-step guide to implement this:
1. Add Required Permissions to Manifest
First, update your AndroidManifest.xml with permissions and a GNSS feature declaration:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- For Android 12+, add this if you need background NMEA access --> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-feature android:name="android.hardware.location.gnss" android:required="true" />
2. Implement the NMEA Listener
Here’s a Kotlin example (Java follows similar logic) of setting up the listener in an Activity:
import android.location.LocationManager import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import android.Manifest import android.content.pm.PackageManager class NmeaReaderActivity : AppCompatActivity() { private lateinit var locationManager: LocationManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_nmea_reader) locationManager = getSystemService(LOCATION_SERVICE) as LocationManager // Check if GPS is enabled on the device if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { Toast.makeText(this, "Enable GPS to receive NMEA data", Toast.LENGTH_SHORT).show() return } // Handle runtime location permissions (required for Android 6.0+) if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 100) return } // Start listening for NMEA sentences setupNmeaListener() } private fun setupNmeaListener() { locationManager.addNmeaListener { nmeaSentence, timestamp -> // This callback receives raw NMEA strings println("Raw NMEA Sentence: $nmeaSentence") // Example: Filter and process specific sentence types when { nmeaSentence.startsWith("\$GPGGA") -> { // Handle GGA (fix quality and location data) } nmeaSentence.startsWith("\$GPRMC") -> { // Handle RMC (recommended minimum navigation data) } } } } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == 100 && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { setupNmeaListener() } else { Toast.makeText(this, "Location permission is required to access NMEA data", Toast.LENGTH_SHORT).show() } } }
Key Notes
- Runtime Permissions: Always check and request
ACCESS_FINE_LOCATIONat runtime. For background NMEA access on Android 10+, you’ll also needACCESS_BACKGROUND_LOCATION(and comply with Google Play policy requirements). - GNSS Availability: The listener only receives data if the device has a working GNSS receiver and GPS is enabled in system settings.
- Battery Impact: Raw GNSS access uses more battery than FLP’s optimized updates, so consider this for your app’s use case.
内容的提问来源于stack exchange,提问作者Daitarn

