Skip to content

Instantly share code, notes, and snippets.

@mdp
Last active October 14, 2019 20:17
Show Gist options
  • Save mdp/a501edd93632f13fd9f8 to your computer and use it in GitHub Desktop.
Save mdp/a501edd93632f13fd9f8 to your computer and use it in GitHub Desktop.

Launching an Intent and getting the result from React Native

In this case I'm using the Embedded ZXing library to scan a QR code and return the result to JavaScript land in React Native.

In order to do that we need access to the Activity instance, which is not usually available to ReactPackage classes.

We'll pass the Activity into the QRCodeScanPackage when we add it:

MainActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mReactRootView = new ReactRootView(this);

        mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModuleName("index.android")
                .addPackage(new QRCodeScanPackage(this)) // `this` is the Activity
                .addPackage(new MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

Then in the QRCodeScanPackage we'll need to make sure that the Module also has the Actvity available

QRCodeScanPackage.java

public class QRCodeScanPackage implements ReactPackage {

    Activity mActivity;

    public QRCodeScanPackage(Activity activity) {
       mActivity = activity;
    }

    @Override
    public List<NativeModule> createNativeModules(
            ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();

        modules.add(new QRCodeScanModule(reactContext, mActivity)); //Pass along the `Actviity`

        return modules;
    }

And then of course the Module now has the Activity and can use it to initiate the scan (Basically fire an Intent)

QRCodeScanModule.java

public class QRCodeScanModule extends ReactContextBaseJavaModule {

    Activity mActivity;

    public QRCodeScanModule(ReactApplicationContext reactContext, Activity activity) {
        super(reactContext);
        mActivity = activity;
    }

    public String getName(){
        return "QRCode";
    }

    @ReactMethod
    public void scan() {
        new IntentIntegrator(mActivity).initiateScan();
    }

Last but not least, we need to listen for the activity result and pass the scan data back into JS land:

MainActivity.java

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        String result = data.getStringExtra(Intents.Scan.RESULT);
        Log.d("QR", result);
        ReactContext reactContext = mReactInstanceManager.getCurrentReactContext();
        if (reactContext != null) {
            reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                    .emit("qrScan", result);
        }
    }

All the files are included in this gist

package com.dotp;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import com.facebook.react.LifecycleState;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.google.zxing.client.android.Intents;
public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {
private ReactInstanceManager mReactInstanceManager;
private ReactRootView mReactRootView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new QRCodeScanPackage(this))
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "dOTP", null);
setContentView(mReactRootView);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
String result = data.getStringExtra(Intents.Scan.RESULT);
Log.d("QR", result);
ReactContext reactContext = mReactInstanceManager.getCurrentReactContext();
if (reactContext != null) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("qrScan", result);
}
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
@Override
protected void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onPause();
}
}
@Override
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onResume(this);
}
}
}
package com.dotp;
import android.app.Activity;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.google.zxing.integration.android.IntentIntegrator;
/**
* Created by mdp on 9/26/15.
*/
public class QRCodeScanModule extends ReactContextBaseJavaModule {
Activity mActivity;
public QRCodeScanModule(ReactApplicationContext reactContext, Activity activity) {
super(reactContext);
mActivity = activity;
}
public String getName(){
return "QRCode";
}
@ReactMethod
public void scan() {
new IntentIntegrator(mActivity).initiateScan();
}
}
package com.dotp;
import android.app.Activity;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class QRCodeScanPackage implements ReactPackage {
Activity mActivity;
public QRCodeScanPackage(Activity activity) {
mActivity = activity;
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new QRCodeScanModule(reactContext, mActivity));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment