Я полностью новичок в Android / Kotlin из iOS / Swift, поэтому извините, если этот вопрос слишком широкий.
Я создаю приложение, которое взаимодействует с устройством USB через это библиотека.Я также добавил этот сервис в проект.Служба отвечает за обработку соединения с USB-устройством.
В приложении я буду выполнять несколько действий, все из которых будут связаны с USB-устройством через одно и то же соединение.Поэтому я решил, что Сервис должен быть привязан к какому-то Singleton, который доступен по всему мируСогласно « Bind service from singleton » это должен быть действительный способ привязки сервиса.
Но мне непонятно, как на самом деле создать синглтон, способный привязать к нему сервис
Когда я пытаюсь переместить привязку Сервиса изMainActivity (как это сделано в коде библиотеки ) для своего собственного Singleton, методы bindService
и registerReceiver
недоступны в Singleton.Может быть, это связано с «контекстом приложения», о котором упоминается в приведенном выше SO вопросе.
- Как сделать такой синглтон?Должен ли я использовать
object
или class
для его определения? - Где определены
bindService
и registerReceiver
, и почему я не могу использовать их из моего Singleton object
?
Вот моя попытка синглтона.Но кажется, что я не могу создать 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()
}
}
}
}