medyas / flutter_qiblah

Flutter Qiblah is a plugin that allows you to display Qiblah direction in you app with support for both Android and iOS.
https://pub.dev/packages/flutter_qiblah
MIT License
127 stars 91 forks source link

static Stream<QiblahDirection> _merge<A, B>(Stream<A> streamA, Stream<B> streamB) Not recalled in ios #16

Closed HamadBangash353 closed 3 years ago

HamadBangash353 commented 3 years ago

static Stream _merge<A, B>(Stream streamA, Stream streamB) this method is not called again when we off location in ios and again turn it on from settings. Means after turn off location when turn it on again and we come to application then compass qiblah not working. when i checked the method above is no calling again in IOS. in android it is working good, though i have done changes to your plugin code. The state of connection in stream builder in compass qiblah screen remains in waiting state when we make qiblahstream to null.

medyas commented 3 years ago

can you share your code

HamadBangash353 commented 3 years ago
StreamBuilder(
        stream: FlutterQiblah.qiblahStream,
        builder: (_, AsyncSnapshot<QiblahDirection> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting)
            return LoadingIndicator();

          final qiblahDirection = snapshot.data;
          if (!refreshMainScreenFlag) {
            SharePrefUtils.setOffset(qiblahDirection.offset != null
                ? qiblahDirection.offset.toStringAsFixed(3)
                : "");
            widget.refreshMainScreen.refresh();
            refreshMainScreenFlag = true;
          }

          return Scaffold(
              body: Container(
            height: MediaQuery.of(context).size.height,
            width: MediaQuery.of(context).size.width,
            decoration: BoxDecoration(
              image: DecorationImage(
                image: AssetImage(mainBackground != null
                    ? mainBackground
                    : "assets/different_compass_utils/bg_1.jpg"),
                fit: BoxFit.cover,
              ),
            ),
            child: snapshot.hasData
                ? Stack(
                    children: [
                      Align(
                        alignment: Alignment.topCenter,
                        child: GestureDetector(
                          onTap: () {
                            showDialog(
                                context: context,
                                builder: (BuildContext context) {
                                  return CustomDialog(
                                      widget.refreshMainScreen, this);
                                });
                          },
                          child: Container(
                            height: 60,
                            margin:
                                EdgeInsets.only(top: 20, right: 10, left: 10),
                            child: new Card(
                              child: new Row(
                                crossAxisAlignment: CrossAxisAlignment.center,
                                children: [
                                  new SizedBox(
                                    width: 5,
                                  ),
                                  new Icon(
                                    Icons.location_on_sharp,
                                    color: Colors.orange,
                                    size: 35,
                                  ),
                                  new SizedBox(
                                    width: 5,
                                  ),
                                  Container(
                                    width: 10,
                                    child: VerticalDivider(
                                      width: 15,
                                      color: mainGreyColor(),
                                    ),
                                  ),
                                  new SizedBox(
                                    width: 5,
                                  ),
                                  Expanded(
                                      child: new Text(
                                    cityName != "none"
                                        ? cityName
                                        : qiblahDirection.currentLocation != ""
                                            ? qiblahDirection.currentLocation
                                            : "CurrentLocation",
                                    style: new TextStyle(
                                        fontSize: 16, fontFamily: "Poppins"),
                                  ))
                                ],
                              ),
                            ),
                          ),
                        ),
                      ),
                      Align(
                        alignment: Alignment.center,
                        child: Container(
                            width: 250,
                            height: 250,
                            child: Stack(
                              children: <Widget>[
                                Transform.rotate(
                                  angle: (qiblahDirection.direction *
                                      (pi / 180) *
                                      -1),
                                  child: Image.asset(emptyCompassPath != null
                                      ? emptyCompassPath
                                      : "assets/different_compass_utils/compass_1.png"),
                                ),
                                Transform.rotate(
                                  angle: (qiblahDirection.qiblah *
                                      (pi / 180) *
                                      -1),
                                  alignment: Alignment.center,
                                  child: Image.asset(
                                    compassNeedle != null
                                        ? compassNeedle
                                        : "assets/different_compass_utils/needle_1.png",
                                    fit: BoxFit.contain,
                                    height: 350,
                                    alignment: Alignment.center,
                                  ),
                                ),
                              ],
                            )),
                      ),
                    ],
                  )
                : TextErrorWidget(),
          ));
        },
      )

And i am making stream null here to refresh my screen for another location

 @override
  void refresh(checkManualLocFlag) async {
    FlutterQiblah().dispose();
    gettingSharedPrefData();

    if (!checkManualLocFlag) {
      askingPermission();
    } else {
      permissionState = true;
    }

    setState(() {});
  }

This is flutter qiblah concerned code

 static Future<String> getAddressesFromCoordinates(double lat, double lng) async {
    final coordinates = new Coordinates(lat, lng);
    var address;
    try {
      address = await Geocoder.local.findAddressesFromCoordinates(coordinates);

    } catch (_) {}
    if (address == null) {
      return "Current Location";
    }
    return address.first.locality;
  }

  /// Merge the compass stream with location updates, and calculate the Qiblah direction
  /// return a Stream<Map<String, dynamic>> containing compass and Qiblah direction
  /// Direction varies from 0-360, 0 being north.
  /// Qiblah varies from 0-360, offset from direction(North)
  static Stream<QiblahDirection> _merge<A, B>(Stream<A> streamA, Stream<B> streamB) {
    return streamA.combineLatest<B, QiblahDirection>(streamB, (dir, pos) async {

      final position = pos as Position;
      final direction = dir as double;
      var offSet;
      var currentLocation;

      var cityName = await SharePrefUtils.getQiblahCityName();

      var manualLat = await SharePrefUtils.getQiblahLat();
      var manualLng = await SharePrefUtils.getQiblahLng();

      // Calculate the Qiblah offset to North
      if (cityName != "none") {
        offSet = Utils.getOffsetFromNorth(manualLat, manualLng);
        currentLocation ="";

      } else {

        offSet = Utils.getOffsetFromNorth(position.latitude, position.longitude);
        currentLocation=await SharePrefUtils.getCurrentLocationName();
     if(currentLocation=="none")
       {
         currentLocation = await getAddressesFromCoordinates(position.latitude, position.longitude);
         SharePrefUtils.setCurrentLocationName(currentLocation);
       }
      }

      // Adjust Qiblah direction based on North direction
      final qiblah = direction + (360 - offSet);

      return QiblahDirection(qiblah, direction, offSet,currentLocation);
    });
  }

  /// Close compass stream, and set Qiblah stream to null
  Future<void> dispose() async {
    if(_qiblahStream!=null)
      {
        _qiblahStream.drain();
        _qiblahStream = null;
      }
    // FlutterCompass().dispose();
  }
}
medyas commented 3 years ago

well this is a custom implementation and cannot reproduce this. I have you tried not calling dispose ? (FlutterQiblah().dispose();) maybe notclosing the stream will allow it to dispatch data again

HamadBangash353 commented 3 years ago

Dear Sir i have tried with FlutterCompass().dispose(); with this it also doest not work for IOS and for android it is working.

HamadBangash353 commented 3 years ago

@medyas Sir please can you tell me how refresh compass without setting qilbla stream to null. It refreshes when we move ipad. Mean static Stream _merge<A, B>(Stream streamA, Stream streamB) function called when we move ipad. Please can we call without moving ipad please.

medyas commented 3 years ago

the _merge function creates a new stream that mergers the compass and location stream and calculate qibla. if you want to recall _merge you will need to dispose of the current stream so that a new one is created.