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.
Related
I use the react-native-FBSDK correctly, but, after that update Android Studio to version 3, I receive this error:
Cannot resolve symbol 'CallbackManager'
This is my MainApplication.java
package com.app.dhsriwvboakzzsyqvpjbdxtqmjrlegfclywhtmcgp;
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.sbugert.rnadmob.RNAdMobPackage;
import com.oblador.vectoricons.VectorIconsPackage;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.facebook.CallbackManager;
import com.facebook.reactnative.androidsdk.FBSDKPackage;
import com.facebook.appevents.AppEventsLogger;
import com.facebook.FacebookSdk;
import java.util.Arrays;
public class MainApplication extends Application implements ReactApplication {
private static CallbackManager mCallbackManager = CallbackManager.Factory.create();
protected static CallbackManager getCallbackManager() {
return mCallbackManager;
}
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 RNAdMobPackage(),
new VectorIconsPackage(),
new FBSDKPackage(mCallbackManager)
);
}
#Override
protected String getJSMainModuleName() {
return "index";
}
};
#Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
#Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
I see the question Cannot resolve symbol callbackManager facebook sdk 4.0's lib but I cant resolve my question because I am novice on Android development.
i have problem in react-native-maps .... pls help me
when i add "MapsPackage()" in mainapplication.java ;
React Native: error: constructor MapsPackage in class MapsPackage cannot be
applied to given types
when i delete "MapsPackage()" in mainapplication.java ;
doesnt work maps and i got error "airmap doenst not exist"
my build gradle ;
dependencies {
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:+" // From node_modules
compile 'com.airbnb.android:react-native-maps:0.6.0'
//compile project(':react-native-maps-lib')
}
my mainapplication.java;
package com.polipoolapp;
import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.airbnb.android.react.maps.MapsPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
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 MapsPackage(),
new MainReactPackage()
);
}
#Override
protected String getJSMainModuleName() {
return "index";
}
};
#Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
#Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
my mainactivity.java;
package com.polipoolapp; //<- put your app name
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends ReactActivity {
protected String getMainComponentName() {
return "PolipoolApp"; //<- put your app name
}
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
}
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.
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);
}
}
I need to create an app that involves browsing pdf from phone and then reading it (which will be executed later, once the browsing part is done) and I'm having trouble with it's code. I have gone through the following link I found on stackoverflow, but unfortunately it is not working,
Browse and upload pdf or word file in Android
Here is my MainActivity.java class
import java.io.File;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
public class MainActivity extends AppCompatActivity {
Button btnAttach;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnAttach = (Button) findViewById(R.id.button1);
//button1 is the id of the only button I have in my activity_main.xml
// view products click event
btnAttach.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
button1_OnClick(view);
// Launching All products Activity
}
});
}
public void button1_OnClick(View view) {
getDocument();
}
private void getDocument() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("application/msword,application/pdf");
intent.addCategory(Intent.CATEGORY_OPENABLE);
}
}
protected void onActivityResult ( int req, int result, Intent data)
{
// TODO Auto-generated method stub
super.onActivityResult(req, result, data);
if (result == RESULT_OK) {
Uri fileuri = data.getData();
String docFilePath = getFileNameByUri(this, fileuri);
}
}
// get file path
private String getFileNameByUri(Context context, Uri uri) {
String filepath = "";//default fileName
File file;
if (uri.getScheme().toString().compareTo("content") == 0) {
Cursor cursor = context.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA, MediaStore.Images.Media.ORIENTATION}, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String mImagePath = cursor.getString(column_index);
cursor.close();
filepath = mImagePath;
} else if (uri.getScheme().compareTo("file") == 0) {
try {
file = new File(new URI(uri.toString()));
if (file.exists())
filepath = file.getAbsolutePath();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
filepath = uri.getPath();
}
return filepath;
}
}
As #CherryDT pointed out, startActivityForResult(intent, REQUEST_CODE_DOC); was missing. Added it and fixed the issue.