umair13adil / simple_beacons_flutter

A flutter plugin project to range & monitor iBeacons.
Apache License 2.0
35 stars 42 forks source link

MissingPluginException for iOS #74

Open RapegnoAndrea opened 1 year ago

RapegnoAndrea commented 1 year ago

Hi, when I try to start the service with "BeaconsPlugin.startMonitoring()" the following exception is thrown: MissingPluginException(No implementation found for method startMonitoring on channel beacons_plugin).

This is blocking for using the plugin on iOS devices.

romulogomesbsi commented 1 year ago

Hello, is there any solution for this error: MissingPluginException(No implementation found for method startMonitoring in channel beacons_plugin). ?

mehdico commented 1 year ago

I have the same problem.

[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method startMonitoring on channel beacons_plugin)
#0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:313:7)
<asynchronous suspension>
#1      BeaconsPlugin.startMonitoring (package:beacons_plugin/beacons_plugin.dart:25:28)
phu-bc commented 1 year ago

I have same problem

phu-bc commented 1 year ago

I have found solution to fix on iOS We should move BeaconsPlugin.listenToBeacons(beaconEventsController) and should addRegion for uuid of beacon

atolve commented 7 months ago

Hi, I have the same problem, can you explain your solution better, I would be very grateful?

phu-bc commented 7 months ago

For this one, you need to use method addRegion to register the beacon first before you want to trigger listening from it.

atolve commented 7 months ago

so you're telling me that just move the statement BeaconsPlugin.listenToBeacons(beaconEventsController); after that of addRegion? Because I already tried but I always get the MissingPluginException error

atolve commented 7 months ago

can you paste your working code?

phu-bc commented 7 months ago

This is my code

await runPlugin();

//-------------------------
Future<void> runPlugin() async {
    if (Platform.isAndroid) {
      BeaconsPlugin.channel.setMethodCallHandler((call) async {
        if (call.method == 'scannerReady') {
          await BeaconsPlugin.startMonitoring();
          setState(() {
            isRunning = true;
          });
        }
      });
      BeaconsPlugin.listenToBeacons(beaconEventsController);
    } else if (Platform.isIOS) {
      BeaconsPlugin.listenToBeacons(beaconEventsController);
      BeaconsPlugin.addRegion(
          'MyBeacon1', 'beacon guid id');
      BeaconsPlugin.addRegion(
          'MyBeacon2', 'beacon guid id');
      await BeaconsPlugin.startMonitoring();
      setState(() {
        isRunning = true;
      });
    }
  }
atolve commented 7 months ago

I modified my initPlatformState code like yours but I still get the same error:

    [VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception:
    MissingPluginException(No implementation found for method addRegion on
    channel beacons_plugin)
    #0 MethodChannel._invokeMethod (package:flutter/src/services/
    platform_channel.dart:308:7)
    <asynchronous suspension>
    #1 BeaconsPlugin.addRegion (package:beacons_plugin/
    beacons_plugin.dart:35:28)
    <asynchronous suspension>
    #2 _ClassicModeState.initPlatformState (package:/vista/
    classic_mode.dart:93:7)
    <asynchronous suspension>

What am I doing wrong? Maybe the way of calling functions in the initPlatformState?

Where do you call your method? Can you paste me the complete code of your class?

phu-bc commented 7 months ago

I call it when press button scan in the view. This is the testing code that I used to test. Currently, I have moved to use flutter_beacon already, not use beacons_plugin anymore.

import 'dart:async';
import 'dart:io';

import 'package:beacons_plugin/beacons_plugin.dart';
import 'package:flutter/material.dart';

class BeaconTesting extends StatefulWidget {
  const BeaconTesting({Key key}) : super(key: key);

  @override
  _BeaconTestingState createState() => _BeaconTestingState();
}

class _BeaconTestingState extends State<BeaconTesting> {
  String _beaconResult = 'Not Scanned Yet.';
  int _nrMessagesReceived = 0;
  bool isRunning = false;
  bool isFirstTime = true;
  List<String> _results = [];

  final ScrollController _scrollController = ScrollController();

  final StreamController<String> beaconEventsController =
  StreamController<String>.broadcast();

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  @override
  void dispose() {
    beaconEventsController.close();
    BeaconsPlugin.clearDisclosureDialogShowFlag(false);
    super.dispose();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    if (Platform.isAndroid) {
      await BeaconsPlugin.setDisclosureDialogMessage(
          title: 'Background Locations',
          message:
          'You have to enable the required permission');
    }

    beaconEventsController.stream.listen(
            (data) {
          if (data.isNotEmpty && isRunning) {
            setState(() {
              _beaconResult = data;
              _results.add(_beaconResult);
              _nrMessagesReceived++;
            });
          }
        },
        onDone: () {},
        onError: (error) {
          print("Error: $error");
        });
  }

  Future<void> runPlugin() async {
    if (isFirstTime) {
      BeaconsPlugin.listenToBeacons(beaconEventsController);
      BeaconsPlugin.addRegion(
          'MyBeacon1', 'beacon guid id');
      BeaconsPlugin.addRegion(
          'MyBeacon2', 'beacon guid id');
      isFirstTime = false;
    } else {
      BeaconsPlugin.listenToBeacons(beaconEventsController);
    }
    setState(() {
      isRunning = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Monitoring Beacons'),
        ),
        body: Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Center(
                  child: Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text('Total Results: $_nrMessagesReceived',
                        style: Theme.of(context).textTheme.headline4?.copyWith(
                          fontSize: 14,
                          color: const Color(0xFF22369C),
                          fontWeight: FontWeight.bold,
                        )),
                  )),
              Padding(
                padding: const EdgeInsets.all(2.0),
                child: ElevatedButton(
                  onPressed: () async {
                    if (isRunning) {
                      await BeaconsPlugin.stopMonitoring();
                      setState(() {
                        isRunning = false;
                      });
                    } else {
                      await runPlugin();
                      await BeaconsPlugin.startMonitoring();
                    }
                  },
                  child: Text(isRunning ? 'Stop Scanning' : 'Start Scanning',
                      style: TextStyle(fontSize: 20)),
                ),
              ),
              Visibility(
                visible: _results.isNotEmpty,
                child: Padding(
                  padding: const EdgeInsets.all(2.0),
                  child: ElevatedButton(
                    onPressed: () async {
                      setState(() {
                        _nrMessagesReceived = 0;
                        _results.clear();
                      });
                    },
                    child:
                    Text("Clear Results", style: TextStyle(fontSize: 20)),
                  ),
                ),
              ),
              SizedBox(
                height: 20.0,
              ),
              Expanded(child: _buildResultsList())
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildResultsList() {
    return Scrollbar(
      isAlwaysShown: true,
      controller: _scrollController,
      child: ListView.separated(
        shrinkWrap: true,
        scrollDirection: Axis.vertical,
        physics: ScrollPhysics(),
        controller: _scrollController,
        itemCount: _results.length,
        separatorBuilder: (BuildContext context, int index) => Divider(
          height: 1,
          color: Colors.black,
        ),
        itemBuilder: (context, index) {
          DateTime now = DateTime.now();
          String formattedDate =
          formatDate(now, format: 'yyyy-MM-dd – kk:mm:ss.SSS');
          final item = ListTile(
              title: Text(
                "Time: $formattedDate\n${_results[index]}",
                textAlign: TextAlign.justify,
                style: Theme.of(context).textTheme.headline4?.copyWith(
                  fontSize: 14,
                  color: const Color(0xFF1A1B26),
                  fontWeight: FontWeight.normal,
                ),
              ),
              onTap: () {});
          return item;
        },
      ),
    );
  }
}