我对iOS / Swift中的Android / Kotlin完全陌生,所以请问这个问题是否太宽泛。
我正在构建一个通过this库与USB设备交互的应用程序。我还向项目添加了this service。该服务负责处理与USB设备的连接。
在“应用程序”中,我将有多个活动,所有活动都通过同一连接进入USB设备。因此,我认为该服务应该绑定到一些全球可用的Singleton。根据“ Bind service from singleton” 它应该是绑定服务的有效方法。
但是我不清楚如何实际制作能够绑定服务的Singleton
当我尝试将Service的绑定从MainActivity(如在库的example code中完成)移动到它自己的Singleton时,方法bindService
和registerReceiver
却没有在Singleton中可用。也许这与上面提到的SO问题提到的“应用程序上下文”有关。
object
还是class
进行定义?bindService
和registerReceiver
的定义在哪里,为什么我无法从Singleton object
中使用它们?这是我对Singleton的尝试。但是似乎我无法从中创建一个Intent,并且上面提到的两个函数都没有定义...
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import android.content.BroadcastReceiver
import android.content.Context
import android.content.ComponentName
import android.os.IBinder
import android.content.ServiceConnection
import android.os.Handler
import android.os.Message
import java.lang.ref.WeakReference
import android.content.IntentFilter
object BoxManager {
private var usbService: UsbService? = null
private var mHandler: BoxManager.MyHandler? = null
init {
mHandler = MyHandler(this)
setFilters()
startService(UsbService::class.java, usbConnection, null)
}
/*
* Notifications from UsbService will be received here.
*/
private val mUsbReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
UsbService.ACTION_USB_PERMISSION_GRANTED // USB PERMISSION GRANTED
-> Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show()
UsbService.ACTION_USB_PERMISSION_NOT_GRANTED // USB PERMISSION NOT GRANTED
-> Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show()
UsbService.ACTION_NO_USB // NO USB CONNECTED
-> Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show()
UsbService.ACTION_USB_DISCONNECTED // USB DISCONNECTED
-> Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show()
UsbService.ACTION_USB_NOT_SUPPORTED // USB NOT SUPPORTED
-> Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show()
}
}
}
private val usbConnection = object : ServiceConnection {
override fun onServiceConnected(arg0: ComponentName, arg1: IBinder) {
(arg1 as UsbService.UsbBinder).service.let {
usbService = it
it.setHandler(mHandler)
}
}
override fun onServiceDisconnected(arg0: ComponentName) {
usbService = null
}
}
private fun startService(service: Class<*>, serviceConnection: ServiceConnection, extras: Bundle?) {
if (!UsbService.SERVICE_CONNECTED) {
val startService = Intent(this, service)
if (extras != null && !extras.isEmpty) {
val keys = extras.keySet()
for (key in keys) {
val extra = extras.getString(key)
startService.putExtra(key, extra)
}
}
startService(startService)
}
val bindingIntent = Intent(this, service)
bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE)
}
private fun setFilters() {
val filter = IntentFilter()
filter.addAction(UsbService.ACTION_USB_PERMISSION_GRANTED)
filter.addAction(UsbService.ACTION_NO_USB)
filter.addAction(UsbService.ACTION_USB_DISCONNECTED)
filter.addAction(UsbService.ACTION_USB_NOT_SUPPORTED)
filter.addAction(UsbService.ACTION_USB_PERMISSION_NOT_GRANTED)
registerReceiver(mUsbReceiver, filter)
}
/*
* This handler will be passed to UsbService. Data received from serial port is displayed through this handler
*/
private class MyHandler(activity: MainActivity) : Handler() {
private val mActivity: WeakReference<MainActivity>
init {
mActivity = WeakReference(activity)
}
override fun handleMessage(msg: Message) {
when (msg.what) {
UsbService.MESSAGE_FROM_SERIAL_PORT -> {
val data = msg.obj as String
Toast.makeText(mActivity.get(), "DATA: ${data}", Toast.LENGTH_LONG).show()
}
UsbService.CTS_CHANGE -> Toast.makeText(mActivity.get(), "CTS_CHANGE", Toast.LENGTH_LONG).show()
UsbService.DSR_CHANGE -> Toast.makeText(mActivity.get(), "DSR_CHANGE", Toast.LENGTH_LONG).show()
}
}
}
}