android - Flutter Kotlin从广播接收器获取数据

标签 android flutter kotlin

我正在尝试使用自己的蓝牙kotlin实现,但是遇到了问题。

我将按照kotlin教程here启动用于扫描蓝牙设备的广播接收器。

问题是,当我尝试将每个发现的设备从广播接收器添加到主要 Activity 范围的可变列表中,以便将列表发送到颤振侧时,我总是会得到一个空值。

由于我是kotlin和android的新手,所以我无法真正理解我到底在哪里出错,以及我需要了解哪些概念才能做我需要做的事情。

Kotlin MainActivity.kt


class MainActivity : FlutterActivity() {

    private val CHANNEL = "bluetooth.channel"
     var deviceList: MutableList<BluetoothDevice>?=null;

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {

        GeneratedPluginRegistrant.registerWith(flutterEngine);
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->

            when (call.method) {
                "getBlue" -> bluetoothWrapper(result)
                "discoverBlue" -> discoverDevices(deviceList,result)
            }
        }
    }

    private fun bluetoothWrapper(result: MethodChannel.Result) {
        val defaultAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()
        checkAdapter(result, defaultAdapter);
        enableAdapter(defaultAdapter!!);
    }


    private fun checkAdapter(result: MethodChannel.Result, defaultAdapter: BluetoothAdapter?) {   // check if adapter exists
        if (defaultAdapter == null) {
            result.error("Bluetooth adapter doesn't exist on this device", null, null)
        } else {
            result.success("bluetooth adapter exists on device")
        }


    }

    // check if adapter is enabled if it exists, enable it if it isnt

    @SuppressLint("MissingPermission")
    private fun enableAdapter(bluetoothAdapter: BluetoothAdapter) {
        val requestEnableBt = 1;
        if (!bluetoothAdapter.isEnabled) {
            val enableIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            startActivityForResult(enableIntent, requestEnableBt)
        }
    }

    // register broadcast receiver in order to discover available devices

    private fun discoverDevices(deviceList: MutableList<BluetoothDevice>?, result: MethodChannel.Result) {
        val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)

        registerReceiver(receiver, filter);

        result.success(deviceList)
    }
    private val receiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            when (intent.action) {
                BluetoothDevice.ACTION_FOUND -> {
                    val device: BluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
                    deviceList?.add(device)

                    println("device found has selected parameters inside the broadcast receivver function $device")
                }
                "" -> println("broadcast receiver intent.action has no attribute")
                null -> println("broadcast receiver intent.action was null")
            }
        }
    }
}



Flutter Main.Dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MaterialApp(home: HomePage()));

class HomePage extends StatelessWidget {
  static const platform = const MethodChannel('bluetooth.channel');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Bluetooth Native'),
        centerTitle: true,
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              RaisedButton(
                color: Colors.blue[500],
                onPressed: () {
                  printMethod();
                },
                child: Text('connect to Devices'),
              )
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              RaisedButton(
                color: Colors.blue[500],
                onPressed: () {
                  discoverBlue();
                },
                child: Text('Discover devices'),
              )
            ],
          )
        ],
      ),
    );
  }

  void printMethod() async {
    String value;
    try {
      value = await platform.invokeMethod("getBlue");
    } catch (e) {
      print(e);
    }
    print('printing from dart: $value');
  }

  void discoverBlue() async {
    Future<List> list;
    list = platform.invokeListMethod("discoverBlue", list);
    list.then((val) {
      print("got values from kotlin $val");
    });
  }
}

最佳答案

我看到您尚未触发开始发现过程。
你需要做

        val myAdapter = BluetoothAdapter.getDefaultAdapter();
        myAdapter.startDiscovery();

也因为它是Kotlin中的异步任务。
返回结果
BluetoothAdapter.ACTION_DISCOVERY_FINISHED


因此,您的MainActivity.kt将是
package com.example.testapp

import android.annotation.SuppressLint
import android.app.Activity
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant


class MainActivity : FlutterActivity() {

    private val CHANNEL = "bluetooth.channel"
    var deviceList: MutableList<BluetoothDevice>? = null;

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {

        GeneratedPluginRegistrant.registerWith(flutterEngine);
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->

            when (call.method) {
                "getBlue" -> bluetoothWrapper(result)
                "discoverBlue" -> discoverDevices(deviceList, result)
                "allPaired" -> getConnectedDevices(result)
            }
        }
    }

    private fun getConnectedDevices(result: MethodChannel.Result) {
        val mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
        val pairedDevices = mBluetoothAdapter.bondedDevices

        val s: MutableList<String> = ArrayList()
        for (bt in pairedDevices) s.add(bt.name)
        result.success(s);
    }

    private fun bluetoothWrapper(result: MethodChannel.Result) {
        val defaultAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()
        checkAdapter(result, defaultAdapter);
        enableAdapter(defaultAdapter!!);
    }


    private fun checkAdapter(result: MethodChannel.Result, defaultAdapter: BluetoothAdapter?) {   // check if adapter exists
        if (defaultAdapter == null) {
            result.error("Bluetooth adapter doesn't exist on this device", null, null)
        } else {
            result.success("bluetooth adapter exists on device")
        }


    }

    // check if adapter is enabled if it exists, enable it if it isnt

    @SuppressLint("MissingPermission")
    private fun enableAdapter(bluetoothAdapter: BluetoothAdapter) {
        val requestEnableBt = 1;
        if (!bluetoothAdapter.isEnabled) {
            val enableIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            startActivityForResult(enableIntent, requestEnableBt)
        }
    }

    // register broadcast receiver in order to discover available devices

    private fun discoverDevices(deviceList: MutableList<BluetoothDevice>?, result: MethodChannel.Result) {

        val myAdapter = BluetoothAdapter.getDefaultAdapter();
        myAdapter.startDiscovery();

        val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
        val receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                when (intent.action) {
                    BluetoothDevice.ACTION_FOUND -> {
                        val device: BluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
                        deviceList?.add(device)
                        println("device found has selected parameters inside the broadcast receivver function $device")
                    }
                    BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> {
                        result.success(deviceList)
                    }
                    "" -> println("broadcast receiver intent.action has no attribute")
                    null -> println("broadcast receiver intent.action was null")
                }
            }
        }
        registerReceiver(receiver, filter)
    }


}

并且main.dart将是
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MaterialApp(home: HomePage()));

class HomePage extends StatelessWidget {
  static const platform = const MethodChannel('bluetooth.channel');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Bluetooth Native'),
        centerTitle: true,
      ),
      body: Container(
        width: double.infinity,
        child: Column(
          mainAxisSize: MainAxisSize.max,
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              color: Colors.blue[500],
              onPressed: () {
                printMethod();
              },
              child: Text('connect to Devices'),
            ),
            RaisedButton(
              color: Colors.blue[500],
              onPressed: () {
                discoverBlue();
              },
              child: Text('Discover devices'),
            ),
            RaisedButton(
              color: Colors.blue[500],
              onPressed: () {
                getAllPaired();
              },
              child: Text('All paired devices'),
            )
          ],
        ),
      ),
    );
  }

  void printMethod() async {
    String value;
    try {
      value = await platform.invokeMethod("getBlue");
    } catch (e) {
      print(e);
    }
    print('printing from dart: $value');
  }

  void discoverBlue() async {
    Future<List> list;
    list = platform.invokeListMethod("discoverBlue", list);
    list.then((val) {
      print("got values from kotlin $val");
    });
  }

  void getAllPaired() async {
    var value = await platform.invokeListMethod("allPaired");
    print(value);
  }
}

关于android - Flutter Kotlin从广播接收器获取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61261712/

相关文章:

android - xPath 更多谓词选择节点

flutter - 如何在 flutter 中创建没有应用栏的标签栏?

Android Studio KMM iOS 运行不会在 iPhone 模拟器中启动

android - SQLite 不选择日期

android - 由于SELinux,Socket IO无法正常运行Android 8.0

sqlite - Flutter - 在不删除数据库的情况下修改Sqlite表

android - 如何使用分页库android使用空 View 和分页?

android-studio - 将函数名称作为字符串给出时如何调用 kotlin 函数?

android - 编译 native Android 代码时出现内部编译器错误

flutter - 如何将参数传递给 Mobx Controller (Flutter)