How to call native android module from react native JS - react-native

I am facing issue in calling my java class methods (android native code) from JS.
I have already followed https://facebook.github.io/react-native/docs/native-modules-android.html but its not working. Please find below the issues which I am facing.
Where we should export android module, I have done it in index.js
import {NativeModules} from 'react-native';
const { ScannerInteractor } = NativeModules;
export default ScannerInteractor;
or
import {NativeModules} from 'react-native';
module.exports = NativeModules.ScannerInteractor;
In a javascript class where I want to call this method how should I import my class, I have written following code. Does it matter if index.js are at same level as of my javascript class?
import ScannerInteractor from "./ScannerInteractor"
I have created member methods then how to call them? As per example, it need to be call as static method call.
ScannerInteractor.startScan(this, null, null);
How to pass context variable from JS, will passing 'this' parameter will work?
I am not getting any error or log messages in the logcat but method is also not getting triggered.
NativeModule class
import com.facebook.react.ReactPackage;
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;
import com.kohl.scan.common.ScannerInteractor;
public class ModuleInjector implements ReactPackage {
#Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
#Override public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ScannerInteractor(reactContext));
return modules;
}
}
ApplicationClass
import com.facebook.react.ReactPackage;
import java.util.Arrays;
import java.util.List;
import com.lugg.ReactNativeConfig.ReactNativeConfigPackage;
import com.reactnativenavigation.NavigationApplication;
import com.oblador.vectoricons.VectorIconsPackage;
import com.rfpproject.ModuleInjector;
public class MainApplication extends NavigationApplication {
#Override
public boolean isDebug() {
// Make sure you are using BuildConfig from your own application
return BuildConfig.DEBUG;
}
protected List<ReactPackage> getPackages() {
// Add additional packages you require here
// No need to add RnnPackage and MainReactPackage
return Arrays.<ReactPackage>asList(
// eg. new VectorIconsPackage()
new ReactNativeConfigPackage(),
new VectorIconsPackage(),
new ModuleInjector()
);
}
#Override
public String getJSMainModuleName() {
return "index";
}
#Override
public List<ReactPackage> createAdditionalReactPackages() {
return getPackages();
}
}
I am calling it from JS script as mentioned below:
onClick1(){
ScannerInteractor.startScan(this, null, null);
//alert('cllllll');
}

It has worked after using
import {NativeModules} from 'react-native';
module.exports = NativeModules.ScannerInteractor;
and
import {NativeModules} from 'react-native'; in the JS class and calling using NativeModules.ScannerInteractor.check()
Still not clear about how to pass context variable as an argument.

Related

React Native Script TelephonyManager not working

Here is my NativScript code for android
package com.chetti; // replace com.your-app-name with your app’s name
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 java.util.Map;
import java.util.HashMap;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.app.Activity;
public class CalendarModule extends ReactContextBaseJavaModule {
CalendarModule(ReactApplicationContext context) {
super(context);
}
#Override
public String getName() {
return "CalendarModule";
}
#ReactMethod
public String createCalendarEvent() {
// I am not sure about how to get TelephonyManager instance!
TelephonyManager manager=(TelephonyManager)getActivity().getSystemService(Context.TELEPHONY_SERVICE);
String phoneNumber1 = manager.getLine1Number();
return phoneNumber1;
}
}
Error throwing are follows->
error: cannot find symbol
TelephonyManager manager=(TelephonyManager)getActivity().getSystemService(Context.TELEPHONY_SERVICE);
^
symbol: method getActivity()
location: class CalendarModule
My requirement is to get the mobile numbers using Native Module for android?.
My specs:
1, React Native 0.68.0
2, node 17
Just putting here a function so that you can get an idea:
#Override
public void onReceive(final Context context, final Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String phoneNumber) {
Log.d("RINGER_IID", phoneNumber);
onCustomCallStateChanged(context, state, phoneNumber);
}
}, PhoneStateListener.LISTEN_CALL_STATE);
}
https://developer.android.com/reference/android/telephony/TelephonyManager
Got through this. Hope this helps.

React Native, Native Modules returns empty object - {}

I've written native module for React Native, everything was done according to official documentation, but something went wrong, and Native Modules returns only empty object.
importing Native Modules in Component Home.js
All Module code was writen according to official docs
import {
NativeModules
} from 'react-native';
const { OptionsPackage } = NativeModules;
console.log(NativeModules) // {}
MainApplication.java file
#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());
packages.add(new OptionsPackage());
return packages;
}
OptionsPackage.java file
package package.name;
import com.facebook.react.ReactPackage;
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 OptionsPackage implements ReactPackage {
#Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
#Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new OptionsModule(reactContext));
return modules;
}
}
OptionsModule.java
package com.downloadmanager;
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 java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.io.InputStream;
...
public class OptionsModule extends ReactContextBaseJavaModule {
ActivityManager activityManager;
int currentSDK;
ReactApplicationContext context;
OptionsModule(ReactApplicationContext context) {
super(context);
this.activityManager = ((ActivityManager) context.getSystemService(ReactApplicationContext.ACTIVITY_SERVICE));
context = context;
currentSDK = android.os.Build.VERSION.SDK_INT;
}
#Override
public String getName() {
return "123";
}
private Map packageInfoToMap(PackageInfo pi) {
PackageManager pm = this.context.getPackageManager();
long longVersionCode;
Map<String, Object> AppInfo = new HashMap<String, Object>();
if(Build.VERSION.SDK_INT >= 28) {
longVersionCode = pi.getLongVersionCode();
} else
{
longVersionCode = pi.versionCode; }
AppInfo.put("packageName", pi.packageName);
AppInfo.put("versionName", pi.versionName);
AppInfo.put("getLongVersionCode", longVersionCode);
AppInfo.put("lastUpdateTime", (pi.lastUpdateTime));
AppInfo.put("firstInstallTime", pi.firstInstallTime);
String title = pi.applicationInfo.loadLabel(pm).toString();
String description = pi.applicationInfo.loadDescription(pm).toString();
Drawable icon = pi.applicationInfo.loadIcon(pm);
AppInfo.put("title", title);
AppInfo.put("description", description);
AppInfo.put("icon", icon);
//get folder
String apkDir = pi.applicationInfo.publicSourceDir;
File file = new File(apkDir);
double size = file.length();
AppInfo.put("filePath", apkDir);
AppInfo.put("size", size);
return AppInfo;
}
#ReactMethod
public List listOfApps(String type) {
List<PackageInfo> packages = this.context.getPackageManager().getInstalledPackages(0);
List<Map<String, Object>> listOfApps = new ArrayList();
for (PackageInfo isPackage : packages) {
boolean isSystem = (isPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM;
if(type == "systemOnly" && isSystem) {
listOfApps.add(this.packageInfoToMap(isPackage));
} else if (type == "nonSystem" && !isSystem) {
listOfApps.add(this.packageInfoToMap(isPackage));
} else {
listOfApps.add(this.packageInfoToMap(isPackage));
}
}
return listOfApps;
}
}
Your getName() override method in OptionsModule is returning "123"
#Override
public String getName() {
return "123";
}
This is how react native gets the name of your module that should show up on react native side.
Try changing it to "OptionsModule" and then in your Home.js do
const {OptionsModule} = NativeModules
Also try calling your #ReactMethod in js to see if it works, don't rely on console logging NativeModules.

Spring Rest Template - why i get "whitelabel error"?

Hi i want to make very simple application that print an openweathermap.org API answer in console. I thought it should works, but when i'm going to an adress in my browser i've got Whitelabel Error Page and nothing in console. I've made two classes. Main:
package com.example.restTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
#SpringBootApplication
public class RestTemplateApplication {
public static void main(String[] args) {
SpringApplication.run(RestTemplateApplication.class, args);
}
#Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
and controller:
package com.example.restTemplate.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
#RestController
public class ConsumeWebService {
#Autowired
RestTemplate restTemplate;
#RequestMapping(value = "localhost:8080/weather")
public void printWeather() {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
System.out.println(restTemplate.exchange("http://api.openweathermap.org/data/2.5/weather?q=London,uk&myAPIKey",
HttpMethod.GET, entity, String.class).getBody());
}
}
Of course i didn't put here my real key to API and i should to declared city and key in params, but i will think about it in future. For now i just want to get a simple output in console and wll be appreciated for your help.
Why do you put "localhost:8080/weather" as value?
Change from
#RequestMapping(value ="localhost:8080/weather")
To
#RequestMapping(value = "/weather")

React Native UI Component

When react native require this native ui component multiple time, starting from the second one, the previous became black.
Any ideas?
#Override
public String getName()
{
return "JWPlayer";
}
#Override
public JWPlayerView createViewInstance(ThemedReactContext context)
{
PlayerConfig playerConfig = new PlayerConfig.Builder().build();
playerView = new JWPlayerView(context.getCurrentActivity(), playerConfig);
playerView.setFullscreen(false, false);
playerView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
playerView.addOnFullscreenListener(this);
playerView.addOnPauseListener(this);
playerView.addOnPlayListener(this);
playerView.addOnSetupErrorListener(this);
playerView.addOnErrorListener(this);
return playerView;
}
I also met this question.
I solved the problem.
see same question ,
this
JWView.java :
import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableMap;
import com.longtailvideo.jwplayer.JWPlayerView;
import com.longtailvideo.jwplayer.configuration.PlayerConfig;
public class JWView extends FrameLayout {
private final Context _context;
private Activity activity = null;
public JWView(Context context) {
super(context);
this._context = context;
this.activity = ((ReactContext) getContext()).getCurrentActivity();
PlayerConfig playerConfig = new PlayerConfig.Builder()
.file("http://img.ksbbs.com/asset/Mon_1605/25d705200a4eab4.mp4")
.autostart(false)
.build();
JWPlayerView playerView = new JWPlayerView(this.activity, playerConfig);
addView(playerView);
}
private final Runnable measureAndLayout = new Runnable() {
#Override
public void run() {
measure(
MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
layout(getLeft(), getTop(), getRight(), getBottom());
}
};
#Override
public void requestLayout() {
super.requestLayout();
// The spinner relies on a measure + layout pass happening after it calls requestLayout().
// Without this, the widget never actually changes the selection and doesn't call the
// appropriate listeners. Since we override onLayout in our ViewGroups, a layout pass never
// happens after a call to requestLayout, so we simulate one here.
post(measureAndLayout);
}
}
JWPlayerViewManager.java:
import java.util.List;
import java.util.ArrayList;
import android.app.Activity;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.longtailvideo.jwplayer.JWPlayerView;
import com.longtailvideo.jwplayer.configuration.PlayerConfig;
public class JWPlayerViewManager extends SimpleViewManager<JWView>
{
#Override
public String getName()
{
return "Jwplayer";
}
#Override
public JWView createViewInstance(ThemedReactContext context)
{
return new JWView(context);
}
}

react-native-call-receiver error react_native_call_receiver does not exist

I am a starter on react native and wanted to use react-native-call-receiver module for learning how to handle call receiving events
I have followed that npm page, and found that in the "register module" section, the author has instructed to add an import statement and new ReactNativeCallReceiver()
However, the template(as shown below)
public class MainApplication extends Application implements ReactApplication {
#Override
protected List<ReactPackage> getPackages() {
......
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
......
within which the code has to be injected is available only in MainApplication.java and not under MainActivity.java in the path android/app/src/main/java/[your-app-namespace]/
(I guess this must be because of the outdated version of manual compared to react. I am using react native 0.41 and react-native-cli 2.0.1)
So i proceeded with the "import" and the "new" statement inside the class, and ran the application, and i get the following error
c:\Myapp\android\app\src\main\java\com\test_nativebase\MainApplication.java:13: error: package ru.getintime.
react_native_call_receiver does not exist
import ru.getintime.react_native_call_receiver.ReactNativeCallReceiver;
^
C:\Myapp\android\app\src\main\java\com\test_nativebase\MainApplication.java:30: error: cannot find symbol
new ReactNativeCallReceiver()
^
symbol: class ReactNativeCallReceiver
2 errors
:app:compileDebugJavaWithJavac FAILED
FAILURE: Build failed with an exception.
C:\Myapp\android\app\src\main\java\com\test_nativebase\MainActivity.java
package com.test_nativebase;
import com.facebook.react.ReactActivity;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
#Override
protected String getMainComponentName() {
return "Test_NativeBase";
}
}
C:\Myapp\android\app\src\main\java\com\test_nativebase\MainApplication.java
package com.test_nativebase;
import android.app.Application;
import android.util.Log;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import ru.getintime.react_native_call_receiver.ReactNativeCallReceiver;
import java.util.Arrays;
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() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new ReactNativeCallReceiver()
);
}
};
#Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
#Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
This is what i did:
Double Checked whether the import statement is available
Double Checked whether the module is installed and saved under node_modules
I checked out github link to file an issue, but the link that is given on npm is broken. Can somebody help me sort out this error please ?