在设置“位置”为Android

时间:2019-07-04 05:27:43

标签: android kotlin nmea

目前,我正在开发需要一定方向的GPS应用程序。当我添加nmea侦听器时,它仅被调用一次。我正在使用thisthis链接。但是问题在于,nmea侦听器似乎只能运行一次。

class MainActivity : AppCompatActivity() {

private lateinit var locationManager: LocationManager

private var mOnNmeaMessageListener: OnNmeaMessageListener? = null

private var mLegacyNmeaListener: NmeaListener? = null

companion object {
    private const val PERMISSION_REQUEST_CODE = 1
    var counter  = 0
}


private fun nmeaProgress(rawNmea: String) {

    println("it is $rawNmea")
    //Here is the sample protocol example of   //$GPRMC,061244.00,A,4120.913656,N,06914.245043,E,1.0,118.8,040719,4.6,E,A*3F


    val rawNmeaSplit = rawNmea.split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()

    if (rawNmeaSplit[0].equals("\$GPRMC", ignoreCase = true)) {
        counter++
        val myString = rawNmeaSplit[0] + " , " + rawNmeaSplit[1] + " , " + rawNmeaSplit[2] + " , " +
                        rawNmeaSplit[3] + " , " + rawNmeaSplit[4] + " , " + rawNmeaSplit[5] + " , " +
                        rawNmeaSplit[6] + " , " + rawNmeaSplit[7] + " , " + rawNmeaSplit[8] + " , " +
                        rawNmeaSplit[9] + " , " + rawNmeaSplit[10] + " , " + rawNmeaSplit[11] + " , " + rawNmeaSplit[12] + ", $counter"
        message.text = myString

        val latitude = "Latitude: ${rawNmeaSplit[3]}"
        val longitude = "Longitude: ${rawNmeaSplit[5]}"
        val velocity = "Speed : ${rawNmeaSplit[7]}"
        val deg = "Degree : ${rawNmeaSplit[8]}"


        lat.text = longitude
        lng.text = latitude
        speed.text = velocity
        degree.text = deg

    }

}



override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    init()
}

private fun init() {
    val msg = "Data not received yet"
    lat.text = msg
    locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
}


@SuppressLint("MissingPermission")
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (grantResults.size != permissions.size) {
        Toast.makeText(this, "Please grant all permission", Toast.LENGTH_SHORT).show()
        finish()
    } else {
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0.0f, locationListener)
        addNmeaListener()
    }

}

private val locationListener: LocationListener = object : LocationListener {
    override fun onLocationChanged(location: Location?) {


        //Will be implemented later

    }

    override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {
        //
    }

    override fun onProviderEnabled(provider: String?) {
        //
    }

    override fun onProviderDisabled(provider: String?) {
        //
    }

}



override fun onResume() {
    super.onResume()
    requestUpdate()
}

private fun requestUpdate() {
    val list = arrayListOf<String>()

    if (ContextCompat.checkSelfPermission(
            applicationContext,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        list.add(Manifest.permission.ACCESS_FINE_LOCATION)
    } else if (ContextCompat.checkSelfPermission(
            applicationContext,
            Manifest.permission.ACCESS_COARSE_LOCATION
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        list.add(Manifest.permission.ACCESS_COARSE_LOCATION)
    }

    val array = arrayOfNulls<String>(list.size)
    list.toArray(array)
    if (list.isEmpty()) {
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 0.0f, locationListener)
        //setNmeaListener()
        addNmeaListener()

    } else {
        ActivityCompat.requestPermissions(
            this,
            array,
            PERMISSION_REQUEST_CODE
        )
    }
}
private fun addNmeaListener() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        addNmeaListenerAndroidN()
    } else {
        addLegacyNmeaListener()
    }
}


@SuppressLint("MissingPermission")
@RequiresApi(api = Build.VERSION_CODES.N)
private fun addNmeaListenerAndroidN() {
    if (mOnNmeaMessageListener == null) {
        mOnNmeaMessageListener = OnNmeaMessageListener { message, timestamp ->
            nmeaProgress(message)
        }
    }
    locationManager.addNmeaListener(mOnNmeaMessageListener)
}


@SuppressLint("MissingPermission")
private fun addLegacyNmeaListener() {
    if (mLegacyNmeaListener == null) {
        mLegacyNmeaListener = NmeaListener { timestamp, nmea ->
            nmeaProgress(nmea)
        }
    }
    locationManager.addNmeaListener(mLegacyNmeaListener)
}

override fun onPause() {
    super.onPause()

    locationManager.removeUpdates(locationListener)

    removeNmeaListener()
}

private fun removeNmeaListener() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        if (mOnNmeaMessageListener != null) {
            locationManager.removeNmeaListener(mOnNmeaMessageListener)
        }
    } else {
        if (mLegacyNmeaListener != null) {
            locationManager.removeNmeaListener(mLegacyNmeaListener)
        }
    }
}

}

请注意,轴承不是解决方案

更新

我现在已经测试过,问题更加明确。它正在工作,并且可以完美地获取数据。更新UI(将数据设置为相应的TextView)时会出现问题。如果GPS没有正确设置位置,则将解析输入的数据并将其放入TextView中。但是,当通过GPS设置位置时,UI不会更新。如果GPS再次搜索位置,则UI更新正常。我通过添加静态计数器和日志进行检查

运行正常

欢迎任何帮助或建议。预先谢谢你

1 个答案:

答案 0 :(得分:0)

现在我开始知道解决方案了。问题在于nmea协议。 GPRMC在位置不固定时使用。位置固定后,GPRMC不再使用,可以参考GNRMC协议。但是,人们应该关心哪个位置服务正在设置其位置(GPSGLONASSGALILEO?)。在这种情况下,我可以自由使用GNRMC,因为它广泛可用。