【问题标题】:Flutter Kotlin Get Data from Broadcast receiverFlutter Kotlin 从广播接收器获取数据
【发布时间】:2020-04-16 23:20:48
【问题描述】:

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

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

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

由于我是 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");
    });
  }
}

【问题讨论】:

  • 您找到问题所在了吗?你能分享一个答案吗?

标签: android flutter kotlin


【解决方案1】:

我看到您尚未触发启动发现过程。 你需要做的

        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);
  }
}

【讨论】:

  • 这不会将 onReceive 方法中捕获的设备传递到颤振端。知道可能出了什么问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-04
  • 2020-05-07
  • 2022-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多