質問編集履歴

1

コードの追加

2019/12/28 06:27

投稿

ThiHuynh
ThiHuynh

スコア7

test CHANGED
File without changes
test CHANGED
@@ -1,4 +1,556 @@
1
+ ```
2
+
3
+
4
+
5
+ import android.app.Activity
6
+
7
+ import android.bluetooth.BluetoothAdapter
8
+
9
+ import android.bluetooth.BluetoothDevice
10
+
11
+ import android.bluetooth.BluetoothManager
12
+
13
+ import android.bluetooth.le.ScanCallback
14
+
15
+ import android.content.Context
16
+
17
+ import android.os.Bundle
18
+
19
+ import android.os.Handler
20
+
21
+ import android.os.Parcel
22
+
23
+ import android.os.Parcelable
24
+
25
+ import android.widget.*
26
+
27
+ import androidx.appcompat.app.AppCompatActivity
28
+
29
+ import com.hiramine.blecommunicator.R
30
+
31
+ import android.widget.Toast
32
+
33
+ import android.content.Intent
34
+
35
+ import android.view.*
36
+
37
+ import android.widget.AdapterView
38
+
39
+ import android.bluetooth.le.ScanResult as ScanResult1
40
+
41
+
42
+
43
+ abstract class DeviceListActivity() : AppCompatActivity(), Parcelable,
44
+
45
+ AdapterView.OnItemClickListener {
46
+
47
+
48
+
49
+ internal class DeviceListAdapter(activity: Activity) : BaseAdapter() {
50
+
51
+ private val mDeviceList: ArrayList<BluetoothDevice>
52
+
53
+ private val mInflator: LayoutInflater
54
+
55
+
56
+
57
+ init {
58
+
59
+ mDeviceList = ArrayList()
60
+
61
+ mInflator = activity.layoutInflater
62
+
63
+ }
64
+
65
+
66
+
67
+ // リストへの追加
68
+
69
+ fun addDevice(device: BluetoothDevice) {
70
+
71
+ if (!mDeviceList.contains(device)) { // 加えられていなければ加える
72
+
73
+ mDeviceList.add(device)
74
+
75
+ notifyDataSetChanged() // ListViewの更新
76
+
77
+ }
78
+
79
+ }
80
+
81
+
82
+
83
+ // リストのクリア
84
+
85
+ fun clear() {
86
+
87
+ mDeviceList.clear()
88
+
89
+ notifyDataSetChanged() // ListViewの更新
90
+
91
+ }
92
+
93
+
94
+
95
+ override fun getCount(): Int {
96
+
97
+ return mDeviceList.size
98
+
99
+ }
100
+
101
+
102
+
103
+ override fun getItem(position: Int): Any {
104
+
105
+ return mDeviceList[position]
106
+
107
+ }
108
+
109
+
110
+
111
+ override fun getItemId(position: Int): Long {
112
+
113
+ return position.toLong()
114
+
115
+ }
116
+
117
+
118
+
119
+ internal class ViewHolder {
120
+
121
+ var deviceName: TextView? = null
122
+
123
+ var deviceAddress: TextView? = null
124
+
125
+ }
126
+
127
+
128
+
129
+ override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
130
+
131
+ var convertView = convertView
132
+
133
+ val viewHolder: ViewHolder
134
+
135
+ // General ListView optimization code.
136
+
137
+ if (null == convertView) {
138
+
139
+ convertView = mInflator.inflate(R.layout.listitem_device, parent, false)
140
+
141
+ viewHolder = ViewHolder()
142
+
143
+ viewHolder.deviceAddress = convertView!!.findViewById(R.id.textview_deviceaddress)
144
+
145
+ viewHolder.deviceName = convertView.findViewById(R.id.textview_devicename)
146
+
147
+ convertView.setTag(viewHolder)
148
+
149
+ } else {
150
+
151
+ viewHolder = convertView.getTag() as ViewHolder
152
+
153
+ }
154
+
155
+
156
+
157
+ val device = mDeviceList[position]
158
+
159
+ val deviceName = device.name
160
+
161
+ if (null != deviceName && 0 < deviceName.length) {
162
+
163
+ viewHolder.deviceName!!.text = deviceName
164
+
165
+ } else {
166
+
167
+ viewHolder.deviceName!!.setText(R.string.unknown_device)
168
+
169
+ }
170
+
171
+ viewHolder.deviceAddress!!.text = device.address
172
+
173
+
174
+
175
+ return convertView
176
+
177
+ }
178
+
179
+ }
180
+
181
+
182
+
183
+ // 定数
184
+
185
+ private val REQUEST_ENABLEBLUETOOTH = 1 // Bluetooth機能の有効化要求時の識別コード
186
+
187
+ private val SCAN_PERIOD: Long = 10000 // スキャン時間。単位はミリ秒。
188
+
189
+ val EXTRAS_DEVICE_NAME = "DEVICE_NAME"
190
+
191
+ val EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS"
192
+
193
+
194
+
195
+ // メンバー変数
196
+
197
+ private var mBluetoothAdapter: BluetoothAdapter? =
198
+
199
+ null // BluetoothAdapter : Bluetooth処理で必要
200
+
201
+ private var mDeviceListAdapter: DeviceListAdapter? = null // リストビューの内容
202
+
203
+ private var mHandler: Handler? =
204
+
205
+ null // UIスレッド操作ハンドラ : 「一定時間後にスキャンをやめる処理」で必要
206
+
207
+ private var mScanning = false // スキャン中かどうかのフラグ
208
+
209
+
210
+
211
+ // デバイススキャンコールバック
212
+
213
+ private val mLeScanCallback = object : ScanCallback() {
214
+
215
+ // スキャンに成功(アドバタイジングは一定間隔で常に発行されているため、本関数は一定間隔で呼ばれ続ける)
216
+
217
+ override fun onScanResult(callbackType: Int, result: ScanResult1) {
218
+
219
+ super.onScanResult(callbackType, result)
220
+
221
+ runOnUiThread { mDeviceListAdapter!!.addDevice(result.getDevice()) }
222
+
223
+ }
224
+
225
+
226
+
227
+ // スキャンに失敗
228
+
229
+ override fun onScanFailed(errorCode: Int) {
230
+
231
+ super.onScanFailed(errorCode)
232
+
233
+ }
234
+
235
+ }
236
+
237
+
238
+
239
+ constructor(parcel: Parcel) : this() {
240
+
241
+
242
+
243
+ }
244
+
245
+
246
+
247
+
248
+
249
+ override fun onCreate(savedInstanceState: Bundle?) {
250
+
251
+
252
+
253
+ super.onCreate(savedInstanceState)
254
+
255
+ setContentView(com.hiramine.blecommunicator.R.layout.activity_device_list)
256
+
257
+
258
+
259
+ // 戻り値の初期化
260
+
261
+ setResult(Activity.RESULT_CANCELED)
262
+
263
+
264
+
265
+ // リストビューの設定
266
+
267
+ mDeviceListAdapter = DeviceListAdapter(this) // ビューアダプターの初期化
268
+
269
+ val listView = findViewById(R.id.devicelist) as ListView // リストビューの取得
270
+
271
+ listView.adapter = mDeviceListAdapter // リストビューにビューアダプターをセット
272
+
273
+ listView.setOnItemClickListener(this) // クリックリスナーオブジェクトのセット
274
+
275
+
276
+
277
+ // UIスレッド操作ハンドラの作成(「一定時間後にスキャンをやめる処理」で使用する)
278
+
279
+ mHandler = Handler()
280
+
281
+
282
+
283
+ // Bluetoothアダプタの取得
284
+
285
+ val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
286
+
287
+ mBluetoothAdapter = bluetoothManager.adapter
288
+
289
+ if (null == mBluetoothAdapter) { // デバイス(=スマホ)がBluetoothをサポートしていない
290
+
291
+ Toast.makeText(this, R.string.bluetooth_is_not_supported, Toast.LENGTH_SHORT).show()
292
+
293
+ finish() // アプリ終了宣言
294
+
295
+ return
296
+
297
+ }
298
+
299
+ }
300
+
301
+
302
+
303
+ override fun onResume() {
304
+
305
+ super.onResume()
306
+
307
+
308
+
309
+ // デバイスのBluetooth機能の有効化要求
310
+
311
+ requestBluetoothFeature()
312
+
313
+
314
+
315
+ // スキャン開始
316
+
317
+ startScan()
318
+
319
+ }
320
+
321
+
322
+
323
+ // 別のアクティビティ(か別のアプリ)に移行したことで、バックグラウンドに追いやられた時
324
+
325
+ override fun onPause() {
326
+
327
+ super.onPause()
328
+
329
+
330
+
331
+ // スキャンの停止
332
+
333
+ stopScan()
334
+
335
+ }
336
+
337
+
338
+
339
+ // デバイスのBluetooth機能の有効化要求
340
+
341
+ private fun requestBluetoothFeature() {
342
+
343
+ if (mBluetoothAdapter!!.isEnabled()) {
344
+
345
+ return
346
+
347
+ }
348
+
349
+ // デバイスのBluetooth機能が有効になっていないときは、有効化要求(ダイアログ表示)
350
+
351
+ val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
352
+
353
+ startActivityForResult(enableBtIntent, REQUEST_ENABLEBLUETOOTH)
354
+
355
+ }
356
+
357
+
358
+
359
+ // 機能の有効化ダイアログの操作結果
360
+
361
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
362
+
363
+ when (requestCode) {
364
+
365
+ REQUEST_ENABLEBLUETOOTH // Bluetooth有効化要求
366
+
367
+ -> if (Activity.RESULT_CANCELED == resultCode) { // 有効にされなかった
368
+
369
+ Toast.makeText(this, R.string.bluetooth_is_not_working, Toast.LENGTH_SHORT).show()
370
+
371
+ finish() // アプリ終了宣言
372
+
373
+ return
374
+
375
+ }
376
+
377
+ }
378
+
379
+ super.onActivityResult(requestCode, resultCode, data)
380
+
381
+ }
382
+
383
+
384
+
385
+ // スキャンの開始
386
+
387
+ private fun startScan() {
388
+
389
+ // リストビューの内容を空にする。
390
+
391
+ mDeviceListAdapter?.clear()
392
+
393
+
394
+
395
+ // BluetoothLeScannerの取得
396
+
397
+ // ※Runnableオブジェクト内でも使用できるようfinalオブジェクトとする。
398
+
399
+ val scanner = mBluetoothAdapter!!.getBluetoothLeScanner() ?: return
400
+
401
+
402
+
403
+
404
+
405
+ // スキャン開始(一定時間後にスキャン停止する)
406
+
407
+ mHandler?.postDelayed(Runnable {
408
+
409
+ mScanning = false
410
+
411
+ scanner.stopScan(mLeScanCallback)
412
+
413
+
414
+
415
+ // メニューの更新
416
+
417
+ invalidateOptionsMenu()
418
+
419
+ }, SCAN_PERIOD)
420
+
421
+
422
+
423
+ mScanning = true
424
+
425
+ scanner.startScan(mLeScanCallback)
426
+
427
+
428
+
429
+ // メニューの更新
430
+
431
+ invalidateOptionsMenu()
432
+
433
+ }
434
+
435
+
436
+
437
+ // スキャンの停止
438
+
439
+ private fun stopScan() {
440
+
441
+ // 一定期間後にスキャン停止するためのHandlerのRunnableの削除
442
+
443
+ mHandler?.removeCallbacksAndMessages(null)
444
+
445
+
446
+
447
+ // BluetoothLeScannerの取得
448
+
449
+ val scanner = mBluetoothAdapter?.getBluetoothLeScanner() ?: return
450
+
451
+ mScanning = false
452
+
453
+ scanner.stopScan(mLeScanCallback)
454
+
455
+
456
+
457
+ // メニューの更新
458
+
459
+ invalidateOptionsMenu()
460
+
461
+ }
462
+
463
+
464
+
465
+
466
+
467
+ override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) {
468
+
469
+ // クリックされたアイテムの取得
470
+
471
+ val device = mDeviceListAdapter?.getItem(position) as BluetoothDevice
472
+
473
+ // 戻り値の設定
474
+
475
+ val intent = Intent()
476
+
477
+ intent.putExtra(EXTRAS_DEVICE_NAME, device.name)
478
+
479
+ intent.putExtra(EXTRAS_DEVICE_ADDRESS, device.address)
480
+
481
+ setResult(Activity.RESULT_OK, intent)
482
+
483
+ finish()
484
+
485
+ }
486
+
487
+
488
+
489
+ // オプションメニュー作成時の処理
490
+
491
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
492
+
493
+ menuInflater.inflate(R.menu.activity_device_list, menu)
494
+
495
+ if (mScanning) {
496
+
497
+ menu.findItem(R.id.menuitem_stop).setVisible(false)
498
+
499
+ menu.findItem(R.id.menuitem_scan).setVisible(true)
500
+
501
+ menu.findItem(R.id.menuitem_progress).setActionView(null)
502
+
503
+ } else {
504
+
505
+ menu.findItem(R.id.menuitem_stop).setVisible(true)
506
+
507
+ menu.findItem(R.id.menuitem_scan).setVisible(false)
508
+
509
+ menu.findItem(R.id.menuitem_progress)
510
+
511
+ .setActionView(R.layout.actionbar_indeterminate_progress)
512
+
513
+ }
514
+
515
+ return true
516
+
517
+ }
518
+
519
+
520
+
521
+ // オプションメニューのアイテム選択時の処理
522
+
523
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
524
+
525
+ when (item.getItemId()) {
526
+
527
+ R.id.menuitem_scan -> startScan() // スキャンの開始
528
+
529
+ R.id.menuitem_stop -> stopScan() // スキャンの停止
530
+
531
+ }
532
+
533
+ return true
534
+
535
+ }
536
+
537
+
538
+
539
+ }
540
+
541
+
542
+
543
+
544
+
545
+
546
+
547
+
548
+
549
+
550
+
551
+ コード
552
+
1
- ![イメージ説明](1aaa490cbf8722c93171b0eac7f9541d.png)
553
+ ```[イメージ説明](1aaa490cbf8722c93171b0eac7f9541d.png)
2
554
 
3
555
  MainActivityの分です。deviceListActivity.で引っ張ってきているはずなのに、赤字の部分が直りません。わかるかたお願いします。 
4
556