
android.jpg
概述
1、現(xiàn)在的Android手機(jī)都會有加速度傳感器和磁場傳感器,指南針實(shí)際上就是利用這兩個傳感器計算出現(xiàn)在所指向的方位。(當(dāng)然實(shí)際上還能實(shí)現(xiàn)水平儀)
2、然后一般會使用GPS定位得到現(xiàn)在的經(jīng)緯度,就能實(shí)現(xiàn)一個指南針應(yīng)有的所有功能。(本Demo為了顯示實(shí)際地址使用了騰訊定位)
預(yù)覽

1.jpg

2.jpg
實(shí)現(xiàn)
1、獲取sensor實(shí)例
fun initServices() {
mSensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
mOrientationSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) //加速度傳感器
mMagneticSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) //地磁場傳感器
}
2、設(shè)置和取消監(jiān)聽
override fun onResume() {
super.onResume()
mOrientationListener = MySensorEventListener()
mMagneticListener = MySensorEventListener()
mSensorManager.registerListener(mOrientationListener, mOrientationSensor, Sensor.TYPE_ACCELEROMETER)
mSensorManager.registerListener(mMagneticListener, mMagneticSensor, Sensor.TYPE_MAGNETIC_FIELD)
mStopDrawing = false
mHandler.postDelayed(this, 20)
}
override fun onPause() {
super.onPause()
mStopDrawing = true
mSensorManager.unregisterListener(mOrientationListener)
mSensorManager.unregisterListener(mMagneticListener)
}
3、獲取角度相關(guān)參數(shù)
inner class MySensorEventListener : SensorEventListener2 {
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
}
override fun onFlushCompleted(sensor: Sensor?) {
}
override fun onSensorChanged(event: SensorEvent) {
if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
accelerometerValues = event.values
}
if (event.sensor.type == Sensor.TYPE_MAGNETIC_FIELD) {
magneticFieldValues = event.values
}
}
}
4、計算方向和角度
if (direction >= 22.5f && direction < 157.5f) {
//east
} else if (direction > -157.5f && direction < -22.5f) {
//west
}
if (direction > 122.5f || direction < -122.5f) {
// south
} else if (direction < 67.5f && direction > -67.5f) {
// north
}
5、羅盤繪制和旋轉(zhuǎn);網(wǎng)上有很多指南針demo羅盤都是使用的一張圖片實(shí)現(xiàn),本人覺得這樣不是很美觀,于是就簡單繪制了一個。(表盤使用自定義View完成,通過繪制文字表盤刻度等實(shí)現(xiàn)無論如何旋轉(zhuǎn)文字都是正的,大體思路如下;此View是使用最笨的 方式去實(shí)現(xiàn)的,還有很多需要完善的地方,具體代碼實(shí)現(xiàn)可參考源碼CompassDrawView)
canvas.save() //保存畫布,先旋轉(zhuǎn)和方向無關(guān)的東西
canvas.rotate(mDirection, (width / 2).toFloat(), (height / 2).toFloat())
drawBackGroundCircle()
drawScaleLine()
canvas.restore() //重置畫布
canvas.save()
drawDirectionText() //重置畫布后通過傳感器角度來確定文字的位置,以達(dá)到文字問正的情況
drawAngleText()
canvas.rotate(mDirection, (width / 2).toFloat(), (height / 2).toFloat())
canvas.restore()
drawNHand() //最后畫不需要動的指針