Android PhoneStateListener在后台运行吗?

3

我正在开发一款Android应用程序,以监测手机的来电和去电,并将通话信息记录到文件中。从我所了解的信息来看,PhoneStateListener 可以满足我的需求。

问题在于,我需要该应用程序在后台运行,而我正考虑使用服务来实现。然而,我找到的每一个使用监听器的示例都是在主活动中声明,因此我不确定是否需要创建服务才能使其在后台运行。

为了更详细地说明情况,我有具体的指令,不能创建一个“替换”默认呼叫应用程序的应用程序,因此创建GUI没有太大用处(我知道应用程序需要一个主活动,但它唯一的功能应该是启动监视器)。

目前我拟定的想法如下:

class CallMonitorService : Service() {
  private lateinit var serviceLooper: Looper
  private lateinit var serviceHandler: ServiceHandler
  private lateinit var monitor: StateMonitor

  private inner class ServiceHandler(looper: Looper) : Handler(looper) {
    override fun handleMessage(msg: Message) {...}
  }

  override fun onCreate() {
    Log.d(serviceName, "Created")
    HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND).apply {
      start()
      // Get the HandlerThread's Looper and use it for our Handler
      serviceLooper = looper
      serviceHandler = ServiceHandler(looper)
      val manager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
      manager.listen(StateMonitor(), PhoneStateListener.LISTEN_CALL_STATE | ...)
    }
  }
  ...
}

class StateMonitor : PhoneStateListener() {
  // Handler methods
}

总而言之,我需要PhoneStateListener在任何时刻都能运行,而不需要应用程序在前台运行。 我应该创建一个后台服务来运行监听器,还是监听器自己就能在后台运行?

2个回答

2
您需要将侦听器移入独立运行的 Service 中。该服务已在“后台”运行,因此您无需创建额外的线程。而且,从您发布的内容中,没有阻塞代码,所有事件都将以回调方式发送。

那么在我的服务中使用状态监听器是个好主意吗? - Roäc

0

好的,所以我解决了这个问题。

简短的回答是不行PhoneStateListener不能在后台运行。根据我看到的,默认情况下,侦听器仅在应用程序处于前台时才运行。

也许有一种方法可以在服务中运行它,但我无法使其正常工作。相反,我使用了一个BroadcastReceiver来解决问题。

因此,对于解决方案

CallStateMonitor与之前保持不变,只是我将其移动到了另一个位置。对于服务,如我所说,我用广播接收器替换了它:

class CallBroadcastReceiver : BroadcastReceiver() {

  override fun onReceive(context: Context?, intent: Intent?) {
    val telephonyManager = context?.getSystemService(TELEPHONY_SERVICE) as TelephonyManager
    val monitor = StateMonitor()
    telephonyManager.listen(monitor, LISTEN_CALL_STATE)
  }

  private val tag = "STATE_MONITOR"

  private inner class StateMonitor : PhoneStateListener() {
    override fun onCallStateChanged(state: Int, phoneNumber: String?) {
      when (state) {
        TelephonyManager.CALL_STATE_IDLE -> Log.d(tag, "IDLE")
        TelephonyManager.CALL_STATE_OFFHOOK -> Log.d(tag, "OFF-HOOK")
        TelephonyManager.CALL_STATE_RINGING -> Log.d(tag, "RINGING")
      }
    }
  }
}

其余的就是从主活动启动接收器:

class CallMonitorActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    registerReceiver(CallBroadcastReceiver(), IntentFilter(ACTION_CONFIGURATION_CHANGED))
    Log.d(ACTIVITY_TAG, "Registered call receiver.")
  }
}

就是这样,希望能帮到其他人 ^-^


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接