react-native-settings icon indicating copy to clipboard operation
react-native-settings copied to clipboard

My listener is called multiple time

Open Daybayzayd opened this issue 5 years ago • 1 comments

Issue

Hello. I'm new in React Native, so maybe it's totally my fault. I tried to listen the location change with the DeviceEventEmitter. It works fine, but everytime i switch my location, my listener is fired 4 times. Always 4 times.

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React, { useEffect } from 'react';
import { DeviceEventEmitter } from 'react-native';
import RNSettings from 'react-native-settings';

const App: () => React$Node = () => {
  console.log('App compoment ..................');
  // const manager = new BleManager();

  useEffect(() => {
    console.log('useEffect Listener');

    const listenLocation = (result) => {
      console.log('listener', result);
      // setHasLocationOn(result[RNSettings.LOCATION_SETTING] === RNSettings.ENABLED);
    };

    RNSettings.getSetting(RNSettings.LOCATION_SETTING).then((result) => {
      console.log('result', result);
      // setHasLocationOn(result === RNSettings.ENABLED);
    });
    DeviceEventEmitter.addListener(RNSettings.GPS_PROVIDER_EVENT, listenLocation);

    console.log(DeviceEventEmitter.listeners(RNSettings.GPS_PROVIDER_EVENT));

    // return () => {
    //   console.log('remove listener');
    //   DeviceEventEmitter.removeListener(RNSettings.GPS_PROVIDER_EVENT, listenLocation);
    // };
  }, []);

  return <>{/* <Home2 manager={manager} /> */}</>;
};

export default App;

The App component is rendered only once. The useEffect is fired only once (in my logs). But when i switch location on/off, the logs show me "listener ..." 4 times.

Sorry if it's my fault or if i misunderstood something. I tried outside the useEffect it's same, i tried with a useEffect and with the callback to unregister when component is unmounted, but it's never fired (and it's logic) inside my useEffect.


Project Files

Android

Click To Expand

MainApplication.java:

package com.tteesstt;

import android.app.Application;
import android.content.Context;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import android.content.IntentFilter;
import io.rumors.reactnativesettings.RNSettingsPackage;
import io.rumors.reactnativesettings.receivers.GpsLocationReceiver;
import com.oblador.vectoricons.VectorIconsPackage;
import com.polidea.reactnativeble.BlePackage;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost =
      new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
          return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
          @SuppressWarnings("UnnecessaryLocalVariable")
          List<ReactPackage> packages = new PackageList(this).getPackages();
          // Packages that cannot be autolinked yet can be added manually here, for example:
          // packages.add(new MyReactNativePackage());
          return packages;
        }

        @Override
        protected String getJSMainModuleName() {
          return "index";
        }
      };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    registerReceiver(new GpsLocationReceiver(), new IntentFilter("android.location.PROVIDERS_CHANGED"));
    SoLoader.init(this, /* native exopackage */ false);
    initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
  }

  /**
   * Loads Flipper in React Native templates. Call this in the onCreate method with something like
   * initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
   *
   * @param context
   * @param reactInstanceManager
   */
  private static void initializeFlipper(
      Context context, ReactInstanceManager reactInstanceManager) {
    if (BuildConfig.DEBUG) {
      try {
        /*
         We use reflection here to pick up the class that initializes Flipper,
        since Flipper library is not available in release mode
        */
        Class<?> aClass = Class.forName("com.tteesstt.ReactNativeFlipper");
        aClass
            .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
            .invoke(null, context, reactInstanceManager);
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      } catch (NoSuchMethodException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        e.printStackTrace();
      }
    }
  }
}

AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  package="com.tteesstt">

    <uses-permission android:name="android.permission.INTERNET" />
    
    <!-- <uses-permission tools:node="remove" android:name="android.permission.BLUETOOTH"/> -->
    <!-- <uses-permission tools:node="remove" android:name="android.permission.BLUETOOTH_ADMIN"/> -->
    <!-- <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/> -->

    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
	
	<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>
    

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme"
      tools:replace="android:allowBackup">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
        android:launchMode="singleTask"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

</manifest>


Environment

Click To Expand

react-native info output:

 OUTPUT GOES HERE
  • Platform that you're experiencing the issue on:
    • [ ] Android

Daybayzayd avatar Jun 30 '20 11:06 Daybayzayd

The same problem, the listener is fired 4 times.

GerardCasadevall avatar Jul 27 '20 14:07 GerardCasadevall