Giter Club home page Giter Club logo

react-native-keyevent's Introduction

React Native KeyEvent

npm version

Capture external keyboard keys or remote control button events

Learn about Android KeyEvent here.

Installation

via npm

Run npm install react-native-keyevent --save

via yarn

Run yarn add react-native-keyevent

Linking

Android:

react-native link react-native-keyevent (for React Native <= 0.59 only)

iOS:

pod install inside your ios folder.

Note: You still must manually register module in MainActivity! (Instructions below under Configuration Android)

Linking Manually

Android

  1. In android/setting.gradle

    ...
    include ':react-native-keyevent'
    project(':react-native-keyevent').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keyevent/android')
    
  2. In android/app/build.gradle

    ...
    dependencies {
        ...
        compile project(':react-native-keyevent')
    }
    
  3. Register module (in MainApplication.java)

    import com.github.kevinejohn.keyevent.KeyEventPackage;  // <--- import
    
    public class MainApplication extends Application implements ReactApplication {
      ......
    
      @Override
      protected List<ReactPackage> getPackages() {
          return Arrays.<ReactPackage>asList(
              new MainReactPackage(),
              new KeyEventPackage()      <------- Add this
          );
      }
    
      ......
    
    }
    

iOS

Follow the instrutions listed here: Manually Linking iOS.

Configuration

Android

Implement onConfigurationChanged method in MainActivity.java

    import android.view.KeyEvent; // <--- import
    import com.github.kevinejohn.keyevent.KeyEventModule; // <--- import


    public class MainActivity extends ReactActivity {
      ......
      @Override  // <--- Add this method if you want to react to keyDown
      public boolean onKeyDown(int keyCode, KeyEvent event) {

        // A. Prevent multiple events on long button press
        //    In the default behavior multiple events are fired if a button
        //    is pressed for a while. You can prevent this behavior if you
        //    forward only the first event:
        //        if (event.getRepeatCount() == 0) {
        //            KeyEventModule.getInstance().onKeyDownEvent(keyCode, event);
        //        }
        //
        // B. If multiple Events shall be fired when the button is pressed
        //    for a while use this code:
        //        KeyEventModule.getInstance().onKeyDownEvent(keyCode, event);
        //
        // Using B.
        KeyEventModule.getInstance().onKeyDownEvent(keyCode, event);

        // There are 2 ways this can be done:
        //  1.  Override the default keyboard event behavior
        //    super.onKeyDown(keyCode, event);
        //    return true;

        //  2.  Keep default keyboard event behavior
        //    return super.onKeyDown(keyCode, event);

        // Using method #1 without blocking multiple
        super.onKeyDown(keyCode, event);
        return true;
      }

      @Override  // <--- Add this method if you want to react to keyUp
      public boolean onKeyUp(int keyCode, KeyEvent event) {
        KeyEventModule.getInstance().onKeyUpEvent(keyCode, event);

        // There are 2 ways this can be done:
        //  1.  Override the default keyboard event behavior
        //    super.onKeyUp(keyCode, event);
        //    return true;

        //  2.  Keep default keyboard event behavior
        //    return super.onKeyUp(keyCode, event);

        // Using method #1
        super.onKeyUp(keyCode, event);
        return true;
      }

      @Override
      public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
          KeyEventModule.getInstance().onKeyMultipleEvent(keyCode, repeatCount, event);
          return super.onKeyMultiple(keyCode, repeatCount, event);
      }
      ......

    }

iOS

This will need to be added in your AppDelegate.m file:

// react-native-keyevent
#import <RNKeyEvent.h>  // import our package after linking

@implementation AppDelegate

//....

/*!
 * react-native-keyevent support
 */
RNKeyEvent *keyEvent = nil;

- (NSMutableArray<UIKeyCommand *> *)keyCommands {
  NSMutableArray *keys = [NSMutableArray new];
  
  if (keyEvent == nil) {
    keyEvent = [[RNKeyEvent alloc] init];
  }
  
  if ([keyEvent isListening]) {
    NSArray *namesArray = [[keyEvent getKeys] componentsSeparatedByString:@","];
    
    NSCharacterSet *validChars = [NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZ"];
    
    for (NSString* names in namesArray) {
      NSRange  range = [names rangeOfCharacterFromSet:validChars];
      
      if (NSNotFound != range.location) {
        [keys addObject: [UIKeyCommand keyCommandWithInput:names modifierFlags:UIKeyModifierShift action:@selector(keyInput:)]];
      } else {
        [keys addObject: [UIKeyCommand keyCommandWithInput:names modifierFlags:0 action:@selector(keyInput:)]];
      }
    }
  }
  
  return keys;
}

- (void)keyInput:(UIKeyCommand *)sender {
  NSString *selected = sender.input;
  [keyEvent sendKeyEvent:selected];
}

@end

Usage

Whenever you want to use it within React Native code now you can:

import KeyEvent from 'react-native-keyevent';

  componentDidMount() {
    // if you want to react to keyDown
    KeyEvent.onKeyDownListener((keyEvent) => {
      console.log(`onKeyDown keyCode: ${keyEvent.keyCode}`);
      console.log(`Action: ${keyEvent.action}`);
      console.log(`Key: ${keyEvent.pressedKey}`);
    });

    // if you want to react to keyUp
    KeyEvent.onKeyUpListener((keyEvent) => {
      console.log(`onKeyUp keyCode: ${keyEvent.keyCode}`);
      console.log(`Action: ${keyEvent.action}`);
      console.log(`Key: ${keyEvent.pressedKey}`);
    });

    // if you want to react to keyMultiple
    KeyEvent.onKeyMultipleListener((keyEvent) => {
      console.log(`onKeyMultiple keyCode: ${keyEvent.keyCode}`);
      console.log(`Action: ${keyEvent.action}`);
      console.log(`Characters: ${keyEvent.characters}`);
    });
  }

  componentWillUnmount() {
    // if you are listening to keyDown
    KeyEvent.removeKeyDownListener();

     // if you are listening to keyUp
    KeyEvent.removeKeyUpListener();

     // if you are listening to keyMultiple
    KeyEvent.removeKeyMultipleListener();
  }

TODOS

  • iOS Support
  • Add iOS Support for keyDown and multipleKeys
  • Implement keyCode and action on iOS
  • Support for TypeScript projects

react-native-keyevent's People

Contributors

aakashsigdel avatar abstractpoint avatar augustl avatar badaz avatar carlos487 avatar cmgustavo avatar dac245 avatar dave-irvine avatar debjitox avatar evgtsn2 avatar ivanushka1703 avatar kennytian avatar kevinejohn avatar stefanostwald avatar tolgaergin avatar toneyavuz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-keyevent's Issues

Listener is not removing.

I have a function and calling it onKeyUpListener. I'm removing the listener in componentWillUnmount.
My code is below:
componentDidMount(){ KeyEvent.onKeyUpListener((keyCode) => { if(keyCode == '67'){ this.handleBackSpace(); } }); }
and

componentWillUnmount() { KeyEvent.removeKeyUpListener(); }

This causing issue on other screens. Actually, Listener is not removing.

Doesn't listen for cmd, backspace, shift, etc.

Currently module works for normal keys such as alphabets,

but cannot catch keys such as backpress, cmd, shift, etc. for iOS at least(didn't check android)

Any ways to fire listener for those keys?

Event Handler Not Firing

I installed like:

yarn add react-native-keyevent
react-native link react-native-keyevent

In my code:

import KeyEvent from 'react-native-keyevent';

class MyComponent extends Component {
  componentDidMount() {
    KeyEvent.onKeyUpListener((keyCode) => {
      console.log(`Key code pressed: ${keyCode}`);
    });
  }
  render() {
    // stuff including TextInputs
  }
}

When pressing a key on the keyboard on an Android device or emulator, the event handler it not called.

Enter key not triggered

Hi,

I am seeing the following issue: react-native-keyevent has been working flawlessly with react-native 0.59 and an early version of react-navigation. I have now upraded to 0.63 and react-navigation 4.4.0. No react-native-key-event stops sending newline characters as soon as the screen is touched.

Any ideas why this would happen?

iOS - ability to keep default key event behavior?

Hi friends,

Thank you for this great library! I have a question:

I'm trying to use this library to work with bluetooth-connected barcode scanners. I created a component in my React Native project that is always listening, and when it gets a set of numbers very quickly it guesses that it is a scan and passes that series of numbers to a handler. We're using this library so that we can have something that is always listening wherever the user is in the application. However, we do have text fields (for search, for instance), where the user will likely type text.

On Android, this is working great; we set it up like this:

  @Override
  public boolean onKeyUp(int keyCode, KeyEvent event) {
    KeyEventModule.getInstance().onKeyUpEvent(keyCode, event);
    return super.onKeyUp(keyCode, event);
  }

so that it triggers our listener and keeps default key behavior. This way users can still type into the text fields (or scan into them if they'd like) and the app is responding appropriately when it thinks it got a scanned UPC.

However, it appears that iOS doesn't pass key events along - as soon as I set up onKeyUpListener, I no longer get typed text in any of the text fields in the app (but scanning is working as it should). I'm just now digging into Apple's docs, but I've never done native development before and am wondering if anyone has a quick answer about how to make that behave the way we'd like... so far I'm thinking that we have to send the key event to the next responder in the chain?

Thanks again; any advice would be very appreciated!

support windows

Do you have a plan to support keyevent in react-native-windows?

Keyevent stops react navigation working with D-pad

I have created an application for android TV it was working perfect but i ran into an issue with google play requesting that the app responds to play / pause requests from an android TV remote or game pad

i looked around and found this package and it seemed to work perfect everything worked good i could click pause and remote and it would work with react-native-video

the issue is once i built the project and created the apk everything stopped working when i loaded my apk on official hardware "Nvidia" shield TV using the controle and game pad the first touchable would get focus but after that i could not navigate to another touchable

Removing react-native-keyevent puts everything back to normal and all touchables can be navigated to again i am using react-native-navigation with react-native-screens to navigate between screens and stop any bleeding through

KeyEventPackage is not abstract and does not override abstract method createJSModules() in ReactPackage

I get this error during building app:

...../node_modules/react-native-keyevent/android/src/main/java/com/github/kevinejohn/keyevent/KeyEventPackage.java:16: error: KeyEventPackage is not abstract and does not override abstract method createJSModules() in ReactPackage
public class KeyEventPackage implements ReactPackage {
^
1 error
:react-native-keyevent:compileReleaseJavaWithJavac FAILED

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':react-native-keyevent:compileReleaseJavaWithJavac'.

Compilation failed; see the compiler error output for details.

I already finished all steps and but cannot build successfully with RN 0.46.
I built in another project with RN 0.47 and it worked. Please check if it has any issue with RN 0.46

I'm using:
"react": "16.0.0-alpha.12", "react-native": "0.46.4",

onKeyDownListener not firing

Hi guys, I'm having a problem with the event handler. onKeyDownListener is not firing. Below some more details about my setup:

  • Linked the library manually
  • Using React Native 0.59.9
  • Not using Expo
  • Using an external keyboard connected via the charger port

Thanks in advance!

KeyEventModule.getInstance() is always null

I followed the tutorial from the ReadMe. But the app always crash when I pressed a key. I debugged and found KeyEventModule.initKeyeventModule() is never been called. Can anyone give me some advice on that?

Thanks

PS. use 0.1.0 version, RN version 0.46

Key event is creating a click on Component

Hi there,

I have been using this library to capture key event coming from a barcode scanner.

I have a very strange issue :
On the screen implementing the Key down event
When scanning the barcode,
-> I do capture the key down event, and the values are good
-> BUT, at some point (I don't know which captured key is doing that), the first Touchable Opacity component is clicked without any action from my side.

What I have tried :

  • This behaviour is not happening when I use a TextInput component and focus on it.
  • For what I have understand, by catching the values of the keyboard, the textinput is preventing React native to interpreting keyboard value as action to do on the screen.

BUT : The textInput is slowing down the catching of Key event which is not a solution for me.

Do you have any clue on how I could solve this ?

Regards

Why is keyDown not supported for iOS?

Im looking to implement this for iOS and Android, android works perfect but as per docs iOS is missing keyDown implementation.

Is there an issue which related to this? I could contribute to support this functionality.

Nothing happens on 2d scanner events

2d scanner reader does not fire any of the handlers, down, up or multiple.

Below you can find my component code.
import React from 'react';
import KeyEvent from 'react-native-keyevent';

export default class ScannerKey extends React.Component {
render() {
return null;
}

componentDidMount() {
    console.log('ScannerKey MOUNTED');
    KeyEvent.onKeyDownListener((keyEvent) => {
        console.log(keyEvent);
    });
    // KeyEvent.onKeyUpListener((keyEvent) => {
    //     console.log(keyEvent);
    // });
    // KeyEvent.onKeyMultipleListener((keyEvent) => {
    //     console.log(keyEvent);
    // });
}

}

build failed.

./gradlew assembleRelease

Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused, use --status for details

Configure project :app
WARNING: Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'.
It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html

Configure project :react-native-keyevent
WARNING: Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'.
It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html
WARNING: The specified Android SDK Build Tools version (23.0.1) is ignored, as it is below the minimum supported version (27.0.3) for Android Gradle Plugin 3.1.4.
Android SDK Build Tools 27.0.3 will be used.
To suppress this warning, remove "buildToolsVersion '23.0.1'" from your build.gradle file, as each version of the Android Gradle Plugin now has a default version of the build tools.

Task :app:bundleReleaseJsAndAssets
warning: the transform cache was reset.
Loading dependency graph, done.
bundle: Writing bundle output to: /Users/bhenav/workspace/bitbucket/haydigo/haydiGoScanSolution/android/app/build/generated/assets/react/release/index.android.bundle
bundle: Done writing bundle output
bundle: Copying 2613 asset files
bundle: Done copying assets

error: resource android:style/TextAppearance.Material.Widget.Button.Borderless.Colored not found.
error: resource android:style/TextAppearance.Material.Widget.Button.Colored not found.
/Users/bhenav/.gradle/caches/transforms-1/files-1.1/appcompat-v7-27.1.1.aar/3e6851486ec366e971e8e588d5ce594a/res/values-v26/values-v26.xml:9:5-12:13: AAPT: error: resource android:attr/colorError not found.

/Users/bhenav/.gradle/caches/transforms-1/files-1.1/appcompat-v7-27.1.1.aar/3e6851486ec366e971e8e588d5ce594a/res/values-v26/values-v26.xml:13:5-16:13: AAPT: error: resource android:attr/colorError not found.

/Users/bhenav/.gradle/caches/transforms-1/files-1.1/appcompat-v7-27.1.1.aar/3e6851486ec366e971e8e588d5ce594a/res/values-v26/values-v26.xml:17:5-93: AAPT: error: style attribute 'android:attr/keyboardNavigationCluster' not found.

/Users/bhenav/.gradle/caches/transforms-1/files-1.1/appcompat-v7-27.1.1.aar/3e6851486ec366e971e8e588d5ce594a/res/values/values.xml:251:5-69: AAPT: error: resource android:attr/fontStyle not found.

/Users/bhenav/.gradle/caches/transforms-1/files-1.1/appcompat-v7-27.1.1.aar/3e6851486ec366e971e8e588d5ce594a/res/values/values.xml:251:5-69: AAPT: error: resource android:attr/font not found.

/Users/bhenav/.gradle/caches/transforms-1/files-1.1/appcompat-v7-27.1.1.aar/3e6851486ec366e971e8e588d5ce594a/res/values/values.xml:251:5-69: AAPT: error: resource android:attr/fontWeight not found.

error: failed linking references.

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':react-native-keyevent:verifyReleaseResources'.

com.android.ide.common.process.ProcessException: Failed to execute aapt

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

  • Get more help at https://help.gradle.org

BUILD FAILED in 2m 18s
176 actionable tasks: 33 executed, 143 up-to-date

on component showing Modal default event is still triggered

So i have component that show Modal to user, then i want the user to press volume up or down.
I already set up the onKeyUp and onKeyDown on MainActivity.java to return true, so default behaviour will be do nothing. Without showing the modal, if user press volume up or down key, there will be no volume slider. But if using modal, if user press the volume key, then the Android volume slider will show. How to hide the system volume slider if using Modal?

Bubbling events

Out of interest, they key events aren't captured if you're in a TextInput field. Any idea how we could cause it to bubble?

KeyEvent.onKeyMultipleListener((keyEvent) does not work

KeyEvent.onKeyMultipleListener((keyEvent) => {
console.log(onKeyMultiple keyCode: ${keyEvent.keyCode});
console.log(Action: ${keyEvent.action});
console.log(Characters: ${keyEvent.characters});
});

This Function Does Not work

iOS volume button support

If I'm not mistaken, currently iOS support for detecting volume button presses is not available, will this be supported in future releases?

error: ';' expected in MainActivity.java

MainActivity
Снимок экрана 2020-09-04 в 15 19 28


package com.myapp;

import android.os.Bundle;

import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;

import expo.modules.splashscreen.SplashScreen;
import expo.modules.splashscreen.SplashScreenImageResizeMode;

import android.view.KeyEvent; // <--- import
import com.github.kevinejohn.keyevent.KeyEventModule; // <--- import
   public class MainActivity extends ReactActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // SplashScreen.show(...) has to be called after super.onCreate(...)
    // Below line is handled by '@expo/configure-splash-screen' command and it's discouraged to modify it manually
    SplashScreen.show(this, SplashScreenImageResizeMode.CONTAIN, false);
  }

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "main";
    }

    @Override
    protected ReactActivityDelegate createReactActivityDelegate() {
        return new ReactActivityDelegate(this, getMainComponentName()) {
            @Override
            protected ReactRootView createRootView() {
                return new RNGestureHandlerEnabledRootView(MainActivity.this);
            }
        };
    }

  @Override
  public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

    // A. Prevent multiple events on long button press
    //    In the default behavior multiple events are fired if a button
    //    is pressed for a while. You can prevent this behavior if you
    //    forward only the first event:
    //        if (event.getRepeatCount() == 0) {
    //            KeyEventModule.getInstance().onKeyDownEvent(keyCode, event);
    //        }
    //
    // B. If multiple Events shall be fired when the button is pressed
    //    for a while use this code:
    //        KeyEventModule.getInstance().onKeyDownEvent(keyCode, event);
    //
    // Using B.
    KeyEventModule.getInstance().onKeyDownEvent(keyCode, event);

        // There are 2 ways this can be done:
        //  1.  Override the default keyboard event behavior
        //    super.onKeyDown(keyCode, event);
        //    return true;

        //  2.  Keep default keyboard event behavior
        //    return super.onKeyDown(keyCode, event);

        // Using method #1 without blocking multiple
        super.onKeyDown(keyCode, event);
        return true;
    }

    @Override  // <--- Add this method if you want to react to keyUp
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        KeyEventModule.getInstance().onKeyUpEvent(keyCode, event);

        // There are 2 ways this can be done:
        //  1.  Override the default keyboard event behavior
        //    super.onKeyUp(keyCode, event);
        //    return true;

        //  2.  Keep default keyboard event behavior
        //    return super.onKeyUp(keyCode, event);

        // Using method #1
        super.onKeyUp(keyCode, event);
        return true;
    }

    @Override
    public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
        KeyEventModule.getInstance().onKeyMultipleEvent(keyCode, repeatCount, event);
        return super.onKeyMultiple(keyCode, repeatCount, event);
    }
  }
}

I am not good in java, could you please help what I did wrong?

Sending keyEvents Support

is there support for sending keyEvents? i need to be able to play/pause mídia players for may application
as discribed here: control-the-default-music-player

long eventtime = SystemClock.uptimeMillis();

/*PLAY*/
Intent downIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
KeyEvent downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, 0);
downIntent.putExtra(Intent.EXTRA_KEY_EVENT, downEvent);
sendOrderedBroadcast(downIntent, null);

/*PAUSE*/
Intent upIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
KeyEvent upEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, 0);
upIntent.putExtra(Intent.EXTRA_KEY_EVENT, upEvent);
sendOrderedBroadcast(upIntent, null);

/*NEXT*/
Intent downIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
KeyEvent downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN,   KeyEvent.KEYCODE_MEDIA_NEXT, 0);
downIntent.putExtra(Intent.EXTRA_KEY_EVENT, downEvent);
sendOrderedBroadcast(downIntent, null);

/*PREVIOUS*/
Intent downIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
KeyEvent downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PREVIOUS, 0);
downIntent.putExtra(Intent.EXTRA_KEY_EVENT, downEvent);
sendOrderedBroadcast(downIntent, null);```

This package is not working.

I try with this code

import React,{useEffect} from 'react'
import {View} from 'react-native'

import KeyEvent from 'react-native-keyevent'

const App = () => {

  useEffect(() => {

    KeyEvent.onKeyDownListener((keyEvent) => {
      console.log(`onKeyDown keyCode: ${keyEvent.keyCode}`);
      console.log(`Action: ${keyEvent.action}`);
      console.log(`Key: ${keyEvent.pressedKey}`);
    });

    // if you want to react to keyUp
    KeyEvent.onKeyUpListener((keyEvent) => {
      console.log(`onKeyUp keyCode: ${keyEvent.keyCode}`);
      console.log(`Action: ${keyEvent.action}`);
      console.log(`Key: ${keyEvent.pressedKey}`);
    });

    // if you want to react to keyMultiple
    KeyEvent.onKeyMultipleListener((keyEvent) => {
      console.log(`onKeyMultiple keyCode: ${keyEvent.keyCode}`);
      console.log(`Action: ${keyEvent.action}`);
      console.log(`Characters: ${keyEvent.characters}`);
    });

    return () => {
      KeyEvent.removeKeyDownListener();
      KeyEvent.removeKeyUpListener();
      KeyEvent.removeKeyMultipleListener();
    }
    
  }, [])

  return(
    <View style={{flex:1,backgroundColor:'white'}}>
      
     
    </View>

  )
}

export default App

No console.log when I press volume button

Dependencies:
"dependencies": {
"react": "18.0.0",
"react-native": "0.69.1",
"react-native-keyevent": "^0.2.8",
"react-native-system-setting": "^1.7.6"
},

Weird issue with KeyDown/KeyUp/Multiple

Hello, I'm trying to detect multiple key press. Like alt+E, ctrl+d and such. Even c+d would help.

I've been trying, but I can't get it to work. I'm using RN 0.59 and the latest react-native-keyevent. I have tested this with an Android 6 and an Android 9 emulator, and an Android 6 device.

I'm currently reacting to keyUp, and if I press and hold, it is fired multiple times, wich I think is weird. Like, REALLY weird. I have tried to use the event.getRepeatCount() in order to just forward it once, but it doesn't work.

If I react to keyDown, it also gets called multiple times. The event.getRepeatCount() doesn't work here either. I have tried each and every combination of return super.method; and super.method; return true; and it doesn't work.

KeyMultiple never fires.

This is my mainactivity:

`package com.sampleapp;

import android.os.Bundle;
import com.facebook.react.ReactFragmentActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
import android.view.KeyEvent;
import com.github.kevinejohn.keyevent.KeyEventModule;

public class MainActivity extends ReactFragmentActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(null);
}

/**
 * Returns the name of the main component registered from JavaScript.
 * This is used to schedule rendering of the component.
 */
@Override
protected String getMainComponentName() {
    return "SampleApp";
}

@Override
protected ReactActivityDelegate createReactActivityDelegate() {
    return new ReactActivityDelegate(this, getMainComponentName()) {
        @Override
        protected ReactRootView createRootView() {
        return new RNGestureHandlerEnabledRootView(MainActivity.this);
        }
    };
}

public boolean onKeyDown(int keyCode, KeyEvent event) {

    // A. Prevent multiple events on long button press
    //    In the default behavior multiple events are fired if a button
    //    is pressed for a while. You can prevent this behavior if you
    //    forward only the first event:
            if (event.getRepeatCount() == 0) {
                KeyEventModule.getInstance().onKeyDownEvent(keyCode, event);
            }
    //
    // B. If multiple Events shall be fired when the button is pressed
    //    for a while use this code:
    //        KeyEventModule.getInstance().onKeyDownEvent(keyCode, event);
    //
    // Using B.
    //KeyEventModule.getInstance().onKeyDownEvent(keyCode, event);

    // There are 2 ways this can be done:
    //  1.  Override the default keyboard event behavior
    //    super.onKeyDown(keyCode, event);
    //    return true;

    //  2.  Keep default keyboard event behavior
    //    return super.onKeyDown(keyCode, event);

    // Using method #1 without blocking multiple
    super.onKeyDown(keyCode, event);
    return true;
  }

  @Override  // <--- Add this method if you want to react to keyUp
  public boolean onKeyUp(int keyCode, KeyEvent event) {
    KeyEventModule.getInstance().onKeyUpEvent(keyCode, event);

    // There are 2 ways this can be done:
    //  1.  Override the default keyboard event behavior
    //    super.onKeyUp(keyCode, event);
    //    return true;

    //  2.  Keep default keyboard event behavior
    //    return super.onKeyUp(keyCode, event);

    // Using method #1
    super.onKeyUp(keyCode, event);
    return true;
  }

  @Override
  public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
      KeyEventModule.getInstance().onKeyMultipleEvent(keyCode, repeatCount, event);
      return super.onKeyMultiple(keyCode, repeatCount, event);
  }

}`

And this is on my reactions component componentDidMount:

`KeyEvent.onKeyUpListener((keyEvent) => {

        console.log("keyboardListener", keyEvent, keyEvent.keyCode, this.props.scannerKeyCode);

        keyHandlerFn(keyEvent, this.props.scannerKeyCode);
        
    }); 
    
    KeyEvent.onKeyMultipleListener((keyEvent) => {
      console.log("multiple!",keyEvent.keyCode);
    });`

Has someone experienced this? I'm a little lost, to be honest. I've been trying to setup a java debug session but right now it's impossible to me.

Thanks for your time.

Usage inside a modal

Catching keyevents work great, except when I am inside a modal. After the modal is started, keyevents (e.g. pressing volume buttons) are sent to the OS as well, changing the volume (which should not happen). I am using the react-native 0.60.6.

Error:Configuration with name 'default' not found.

Hi,when i tried to use the source of you in my android project,but the error "Error:Configuration with name 'default' not found." was given by android studio(2.2.3),and if you had experienced the same trouble with me? look forward to getting response from you! thanks!

Expo Integration?

I have been working on an Expo project and this package is exactly what I am looking for. However EXPO does not allow direct linking. Short of detaching there seems to be no way to get this up and running, let me know if you have ever run into it or have any plans to support it.

64 bit

Hello, will there be support for 64 bit version?

EventListener not working on React Native 0.59.5 in debug mode

When using the package in my RN app in debug mode on my android device (Pixel 3 XL), the Event listener is not triggered.
When using the release mode, the listener is triggered (the {keyEvent.action} always returns a 0 i don't know if thats normal).

Tested on different bluetooth devices.
Any idea if that is normal, do i have to switch to release-version? cant really downgrade the RN version. App should be linked correctly with default configuration.

other package versions:

"react": "16.8.3",
"react-native": "0.59.5",
"react-native-config": "0.11.7",
"react-native-device-info": "2.1.3",
"react-native-elements": "1.1.0",
"react-native-gesture-handler": "1.2.1",
"react-native-keyevent": "0.1.2",
"react-native-material-textfield": "^0.12.0",
"react-native-modal": "^11.0.1",
"react-native-orientation": "3.1.3",
"react-native-paper": "2.16.0",
"react-native-size-matters": "0.2.1",
"react-native-vector-icons": "6.5.0",
"react-navigation": "3.9.1",

onKeyDownListener not being called when a Modal is being shown

A simple example:

This in the App.js will always show the key pressed:

  useEffect(() => {
    KeyEvent.onKeyDownListener((keyEvent: any) => {
      console.log(`Key: ${keyEvent.pressedKey}`);
    return () => KeyEvent.removeKeyDownListener();
  }, []);

But at the moment I show any modal, the event stop being called. A simple modal:

import React, { useState } from 'react';
import { Button, Modal } from 'react-native';

interface Props {
  visible: boolean;
  setVisible: (value: boolean) => void;
}

const KeyListenerModalTest = ({ visible, setVisible }: Props) => {
  return (
    <Modal visible={visible}>
      <Button title={'HIDE'} onPress={() => setVisible(false)} />
    </Modal>
  );
};

export default KeyListenerModalTest;

And the keys log won't show. After I press the button HIDE the keys start to be logged again without any problem.

Registering multiple listeners at once (for example in different screens)

I have a custom hook useKeyEventListener that looks more of less like this:

const useKeyEventListener = () => {
  useEffect(() => {
    KeyEvent.onKeyDownListener(() => { /* do stuff */ })

    return () => {
      KeyEvent.removeKeyDownListener()
    }
  }, [])
}

I've noticed that when I mount this hook in multiple screens, the listener stops working in all screens after it's been removed in one screen.

For example:

  1. call useKeyEventListener hook in HomeScreen
  2. nav to DetailScreen, call useKeyEventListener hook
  3. close DetailScreen, the cleanup phase of useKeyEventListener removes the listener
  4. back in the HomeScreen useKeyEventListener does not work anymore also the hook is still called

So I'm guessing the native code in this library only allows to have one single listener. As soon as it is removed, it stops firing and needs to be explicitly "re-added" to start again.

So my questions are:

  • Is it possible to have multiple listeners registered at once, and if so how can they be identified so that KeyEvent.removeKeyDownListener removes a particular listener?
  • If the library doesn't support registering multiple listeners at once, what strategies would you recommend to achieve that anyways? (Maybe having a global React Context KeyEventListenerContext that tracks which screen is focused and sends key events to that screen, not to others)

Hardware button volume not working ?

when I add 2 method to MainActivity.java, => inside the app button volume not working

@Override  
      public boolean onKeyDown(int keyCode, KeyEvent event) {
        KeyEventModule.getInstance().onKeyDownEvent(keyCode);
        super.onKeyDown(keyCode, event);
        return true;
      }
@Override  
     public boolean onKeyUp(int keyCode, KeyEvent event) {
        KeyEventModule.getInstance().onKeyUpEvent(keyCode);
        super.onKeyUp(keyCode, event);
        return true;
      }

Can you give me a solution to solve this problem?
Im so sorry because my english is not very well ! Thanks

callback not fired after virtual keyboard is used.

Once the virtual keyboard is used, onKeyMultipleListener doesn't work anymore. Dont know about the other listeners because this is the only one I use.

I have to restart the app to get it working again. Once the virtual keyboard is used the listener stops working.

MainApplication.java is different.

Hi,

Could you help me, the file MainApplication.java is a little different from your doc.
How could I modify it?
Thank you

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

Attempt to invoke virtual method 'void com.github.kevinejohn.keyevent.KeyEventModule.onKeyUpEvent(int, android.view.KeyEvent)' on a null object reference

Hello, currently using keyevent in project. And sometimes in Bugsnag i see thees errors:

java.lang.NullPointerException · Attempt to invoke virtual method 'void com.github.kevinejohn.keyevent.KeyEventModule.onKeyUpEvent(int, android.view.KeyEvent)' on a null object reference

Bugsnag referring on MainActivity.java:31 - com.appname.MainActivity.onKeyUp.
There is some code from mainActivity.

@Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        KeyEventModule.getInstance().onKeyUpEvent(keyCode, event); < this line
        super.onKeyUp(keyCode, event);
        return true;
    }

So.. Where can be problem..?
react-native-keyevent version - 0.1.2
RN - 0.54.4

Listen when screen is off

Hello,
I first want to thank you about this really good library. I am using it to hijack a media control BLE device (I needed a 5 buttons remote, it activates KEYCODE_MEDIA_PLAY_PAUSE, KEYCODE_VOLUME_UP, etc) and it works fine !
This good work is unfortunately restricted by the android activity lifecycle. It is not working when app is on but screen is locked. I tried other libraries that are made for media control but they listen to only specific events (for example no volume button press, only a volume change).
As far as I searched, it seems not easy to make a service that can do this.
Can you tell me anything about this feature (you tried, you know a library, it's ongoing) ?
Best regards,

on iOS arrow key events are not fired unless shift is held down

It looks like this has something to do with the code in AppDelegate.m, but I don't know enough about the language at the moment to suggest a fix sorry.

As the arrow keys were all I wanted anyway I have just done this for now:

    for (NSString* names in namesArray) {
      NSRange  range = [names rangeOfCharacterFromSet:validChars];

      [keys addObject: [UIKeyCommand keyCommandWithInput:names modifierFlags:0 action:@selector(keyInput:)]];
      
      // TODO: arrow keys not working unless shift modifier is held too
      // if (NSNotFound != range.location) {
      //   [keys addObject: [UIKeyCommand keyCommandWithInput:names modifierFlags:UIKeyModifierShift action:@selector(keyInput:)]];
      // } else {
      //   [keys addObject: [UIKeyCommand keyCommandWithInput:names modifierFlags:0 action:@selector(keyInput:)]];
      // }
    }

Thank-you for the library!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.