我想做的是在接听电话时从接近传感器读取数据。当状态为摘机时,我可以从传感器读取数据。但是,当我结束电话呼叫(状态 IDLE)时,proximitySensorListener.stopSensors() 代码不会停止传感器。
class CallStateReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
var proximitySensorListener = ProximitySensorListener(context!!)
if (context == null || intent == null) {
return
}
if (intent.action == TelephonyManager.ACTION_PHONE_STATE_CHANGED) {
when (intent.getStringExtra(TelephonyManager.EXTRA_STATE)) {
TelephonyManager.EXTRA_STATE_RINGING -> {
Toast.makeText(context, "Incoming Call", Toast.LENGTH_SHORT).show()
}
TelephonyManager.EXTRA_STATE_OFFHOOK -> {
Toast.makeText(context, "Call in progress", Toast.LENGTH_SHORT).show()
proximitySensorListener.startSensors()
}
TelephonyManager.EXTRA_STATE_IDLE -> {
Toast.makeText(context, "Call ended", Toast.LENGTH_SHORT).show()
proximitySensorListener.stopSensors()
}
}
}
}
}
class ProximitySensorListener(private val context: Context) : SensorEventListener {
private var sensorManager: SensorManager =
context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
val proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)
fun startSensors() {
if (proximitySensor != null) {
sensorManager.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL)
}
}
fun stopSensors() {
sensorManager.unregisterListener(this, proximitySensor)
}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
}
override fun onSensorChanged(event: SensorEvent?) {
if (event?.sensor?.type == Sensor.TYPE_PROXIMITY) {
val distance = event.values[0]
if (distance < 5) {
println("Off")
} else {
println("On")
}
}
}
}
如果我在通话期间启动传感器侦听器并尝试通过延迟通话来停止它,它会起作用。换句话说,传感器会因此代码而停止,但这不是理想的解决方案:
TelephonyManager.EXTRA_STATE_OFFHOOK -> {
Toast.makeText(context, "Call in progress", Toast.LENGTH_SHORT).show()
proximitySensorListener.startSensors()
GlobalScope.launch {
delay(3000L)
proximitySensorListener.stopSensors()
}
}
那么,为什么这不起作用?
我不知道您每次使用新侦听器是否有原因,但如果不重要,您可以始终使用 1 个侦听器并在需要时注册/取消注册它。
class CallStateReceiver : BroadcastReceiver() {
var proximitySensorListener: ProximitySensorListener? = null
override fun onReceive(context: Context?, intent: Intent?) {
if (context == null || intent == null) {
return
} else if(context != null && proximitySensorListener == null) {
/initialize the listener once and use always this instance
proximitySensorListener = ProximitySensorListener(context!!)
}
if (intent.action == TelephonyManager.ACTION_PHONE_STATE_CHANGED) {
when (intent.getStringExtra(TelephonyManager.EXTRA_STATE)) {
TelephonyManager.EXTRA_STATE_RINGING -> {
Toast.makeText(context, "Incoming Call", Toast.LENGTH_SHORT).show()
}
TelephonyManager.EXTRA_STATE_OFFHOOK -> {
Toast.makeText(context, "Call in progress", Toast.LENGTH_SHORT).show()
proximitySensorListener?.startSensors()
}
TelephonyManager.EXTRA_STATE_IDLE -> {
Toast.makeText(context, "Call ended", Toast.LENGTH_SHORT).show()
proximitySensorListener?.stopSensors()
//here if you want you can try to make again the listener null
// to use a new one in the next intent, but again, because I do
//not have all of your code and I cannot debug it, I don know if
//it will work this. test this proximitySensorListener = null
}
}
}
}
}
class ProximitySensorListener(private val context: Context) : SensorEventListener {
private var sensorManager: SensorManager =
context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
val proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)
fun startSensors() {
if (proximitySensor != null) {
sensorManager.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL)
}
}
fun stopSensors() {
sensorManager.unregisterListener(this, proximitySensor)
}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
}
override fun onSensorChanged(event: SensorEvent?) {
if (event?.sensor?.type == Sensor.TYPE_PROXIMITY) {
val distance = event.values[0]
if (distance < 5) {
println("Off")
} else {
println("On")
}
}
}
}
还请记住,如果您将可能产生内存泄漏的活动作为上下文传递,那么在可能的情况下将应用程序上下文传递给这些系统服务总是更好。