/
UsbPermissionGrant.kt
76 lines (70 loc) · 3.29 KB
/
UsbPermissionGrant.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.ak1211.smartmeter_route_b
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Context.USB_SERVICE
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.os.Build
import androidx.annotation.RequiresApi
import com.hoho.android.usbserial.BuildConfig
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.first
class UsbPermissionGrant {
enum class UsbPermission(var extraDevice: UsbDevice? = null) { Denied, Granted }
companion object {
const val INTENT_ACTION_USB_PERMISSION =
BuildConfig.LIBRARY_PACKAGE_NAME + ".USB_PERMISSION"
// callbackをFlowにする
private fun getPermissionFlow(context: Context, usbDevice: UsbDevice): Flow<UsbPermission> =
callbackFlow {
val receiver = object : BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == INTENT_ACTION_USB_PERMISSION) {
synchronized(this) {
val granted = intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED,
false
)
val permission: UsbPermission =
if (granted) {
UsbPermission.Granted
} else {
UsbPermission.Denied
}
permission.extraDevice =
intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)
trySend(permission)
close()
}
} else {
trySend(UsbPermission.Denied)
close()
}
}
}
//登録
context.registerReceiver(receiver, IntentFilter(INTENT_ACTION_USB_PERMISSION))
// USB接続の許可ダイアログを表示してもらう
val usbManager: UsbManager = context.getSystemService(USB_SERVICE) as UsbManager
val permissionIntent =
PendingIntent.getBroadcast(context, 0, Intent(INTENT_ACTION_USB_PERMISSION), PendingIntent.FLAG_MUTABLE)
usbManager.requestPermission(usbDevice, permissionIntent)
//解除
awaitClose { context.unregisterReceiver(receiver) }
}
// USB接続の許可を得る
suspend fun getPermission(context: Context, usbDevice: UsbDevice): Deferred<UsbPermission> =
coroutineScope {
async { getPermissionFlow(context, usbDevice).first() }
}
}
}