Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native: write in AsyncStorage with java

So I have this text on the java-side that arrives from an Intent, which I'd like to save to AsyncStorage to being able to access it through React afterwards.

Any chance I can achieve this?

I have:

package com.myapp;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.content.Intent;


import com.facebook.react.LifecycleState;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

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 MainReactPackage())
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

        mReactRootView.startReactApplication(mReactInstanceManager, "BrowseItLater", null);

        setContentView(mReactRootView);

        // This code is from http://developer.android.com/training/sharing/receive.html
        Intent intent = getIntent();
        String action = intent.getAction();
        String type = intent.getType();
        if (Intent.ACTION_SEND.equals(action) && type != null) {
            handleSendText(intent);
        }        
    }

    void handleSendText(Intent intent) {
        String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
        if (sharedText != null) {
            // How can I handle this ????
        }
    }
// ...
}

Or is there any other solution to make MainActivity.java communicate with JS?

like image 530
Augustin Riedinger Avatar asked Jul 25 '26 14:07

Augustin Riedinger


1 Answers

After quite some fight I finally found a solution. It doesn't use AsyncStorage as I read in the source code AsyncStorage could actually be located differently (SQLite, or something else) depending on the phone. Would be dirty to duplicate this logic.

Instead, I created a module like the doc suggests and passed the inputText as an argument to the .addPackage(new EphemeralStoragePackage(inputText)) call in MainActivity.java.

The module exposes a method readOnceAsync to the JS world, which I can later call with:

NativeModules.EphemeralStorage.readOnceAsync((text :string) => {
  if (text.length) {
    this._addValue(text); // this method is in charge of storing in AsyncStorage
  }
})

Here's the detail:

// android/app/src/main/java/com/appname/modules/ephemeralstorage/EphemeralStorageModule.java

package com.browseitlater.modules.ephemeralstorage;

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.facebook.react.bridge.Callback;

import java.util.Map;

public class EphemeralStorageModule extends ReactContextBaseJavaModule {
  private String inputText;

  public EphemeralStorageModule(ReactApplicationContext reactContext, String _inputText) {
    super(reactContext);
    this.inputText = _inputText;
  }

  @Override
  public String getName() {
    return "EphemeralStorage";
  }

  public String getInputText() {
    return inputText;
  }

  @ReactMethod
  public void readOnceAsync(Callback successCallback) {
    successCallback.invoke(getInputText());
    this.inputText = null;
  }

}

And

// android/app/src/main/java/com/appname/modules/ephemeralstorage/EphemeralStoragePackage.java
package com.browseitlater.modules.ephemeralstorage;

import android.app.Activity;

import java.util.*;

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;


public class EphemeralStoragePackage implements ReactPackage {
  private String inputText;

  public EphemeralStoragePackage(String _inputText) {
    super();
    this.inputText = _inputText;
  }

  @Override
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();
    modules.add(new EphemeralStorageModule(reactContext, getInputText()));
    return modules;
  }

  @Override
  public List<Class<? extends JavaScriptModule>> createJSModules() {
    return Collections.emptyList();
  }

  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Collections.emptyList();
  }

  public String getInputText() {
    return inputText;
  }

}

Finally in MainActivity.java, my onCreate method looks like:

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

    Intent intent = getIntent();
    String action = intent.getAction();
    String type = intent.getType();
    String inputText = intent.getStringExtra(Intent.EXTRA_TEXT);

    mReactInstanceManager = ReactInstanceManager.builder()
      .setApplication(getApplication())
      .setBundleAssetName("index.android.bundle")
      .setJSMainModuleName("index.android")
      .addPackage(new MainReactPackage())
      .addPackage(new EphemeralStoragePackage(inputText))
      .setUseDeveloperSupport(BuildConfig.DEBUG)
      .setInitialLifecycleState(LifecycleState.RESUMED)
      .build();

    mReactRootView.startReactApplication(mReactInstanceManager, "BrowseItLater", null);

    setContentView(mReactRootView);

  }
like image 52
Augustin Riedinger Avatar answered Jul 27 '26 03:07

Augustin Riedinger