"undefined is not a function" when create android native module in ReactNative - react-native

I'm following ReactNative Native Module Guide to write the java class that can be used in JS side. The exported method is show from class ToastModule(exported as ToastAndroid). The show method is below:
public void show(String message, int duration) {
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
All work as expected with the toast button appear when I invoke ToastAndroid.show from Button onPress handler.
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Button,
NativeModules,
} from 'react-native';
const ToastAndroid = NativeModules.ToastAndroid
export default class App extends Component {
handleBTNPressed(){
ToastAndroid.show('Awesome', ToastAndroid.SHORT);
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!!
</Text>
<Button title='click me' onPress={()=>this.handleBTNPressed()}/>
</View>
);
}
}
However, when I further change the function name from
#ReactMethod
public void show(String message, int duration) {
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
to
#ReactMethod
public void showAgain(String message, int duration) {
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
I encounter the following error:"undefined is not a function"
this error shows again if I add a new exported method as following:
#ReactMethod
public void showAgain2(String message, int duration) {
String mes = "Hi " + message;
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
Is there anyone know which step I goes incorrectly?
EDIT==========================
There might already be a ToastAndroid in ReactNative, so I change the name to MyToastExample. However, now the error become the following
Does anyone encounter the same issue?

In this step, check if you have import the right ToastModule, because ReactNative also have a class Called ToastModule.
Check if this line import com.facebook.react.modules.toast.ToastModule; exist in *ReactPackage.java

Try using import instead of require.
In my situation, I was using:
var Contacts = require( "react-native-unified-contacts" );
and I was getting the undefined is not function error.
However, changing to:
import Contacts from "react-native-unified-contacts";
fixed the issue for me.
Clearly require and import treat the modules differently.

Related

Minecraft Forge 1.12.2 - Item Textures Not Loading

When following Cubicoder's modding tutorial for Forge 1.12.2, and creating my first item, the texture for the item will not load. I have double checked all of my code against his code. I have my latest log here. I have my registration handler RegistrationHandler.java down below.
package notacyborg.tutorialmod;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraftforge.event.RegistryEvent.Register;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import notacyborg.tutorialmod.util.RegistryUtil;
#EventBusSubscriber(modid = TutorialMod.MODID)
public class RegistrationHandler
{
#SubscribeEvent
public static void registerItems(Register<Item> event)
{
final Item[] items = {
RegistryUtil.setItemName(new Item(), "first_item").setCreativeTab(CreativeTabs.MISC)
};
event.getRegistry().registerAll(items);
}
}
ModelRegistrationHandler.java
package notacyborg.tutorialmod.client;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import notacyborg.tutorialmod.TutorialMod;
import notacyborg.tutorialmod.init.ModItems;
#EventBusSubscriber(value = Side.CLIENT, modid = TutorialMod.MODID)
public class ModelRegistrationHandler
{
#SubscribeEvent
public static void registerModels(ModelRegistryEvent event)
{
registerModel(ModItems.FIRST_ITEM, 0);
}
private static void registerModel(Item item, int meta)
{
ModelLoader.setCustomModelResourceLocation(item, meta,
new ModelResourceLocation(item.getRegistryName(), "inventory"));
}
}
And my first_item.json model file.
{
"parent": "item/generated",
"textures": {
"layer0": "tutorialmod:textures/items/first_item"
}
}
Any help is appreciated!
Your error log says that it was not able to find the model file of your first_item. Make sure that you have put your first_item.json (model file) in assets/Your-Mod-ID/models/item/first_item.json
In your first_item.json file, line 4 should be:
"textures": {
"layer0": "tutorialmod:item/first_item"
}
Try it out and post an error log too if you encounter any further errors.

How to send SMS programatically in React Native with phone credit

I was looking for a way to send an SMS programmatically in React Native without using 3rd Party APIs like Twilio or Firebase etc. My intention was to use phone credit / the available airtime in my SIM Card.
I found the solution from the following link but edited it a bit since the original wa giving errors during compile:
Note: This solution requires you to extend your current React Native code base with Native Java code modules. But don't let that scare you.
Link: Sending Direct SMS In React-Native Android by Fateme Fazli
Step 1: Create SendSMSModule.java
Go into your android/app/src/main/java/com/your_project_name folder to create the DirectSmsModule.java module, use the below Java code.
//DirectSmsModule.java : This is the name of the Java Class/File
package com.your_project_name; //make sure to change to your project's actual name.
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.uimanager.IllegalViewOperationException;
import android.telephony.SmsManager; //++ make sure this package is available always
public class DirectSmsModule extends ReactContextBaseJavaModule {
public DirectSmsModule(ReactApplicationContext reactContext) {
super(reactContext); //required by React Native
}
#Override
//getName is required to define the name of the module represented in JavaScript
public String getName() {
return "DirectSms";
}
#ReactMethod
public void sendDirectSms(String phoneNumber, String msg) {
try {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phoneNumber, null, msg, null, null);
System.out.println("message sent successfully.");
} catch (Exception ex) {
System.out.println("couldn't send message.");
}
}
}
Step 2: Create DirectSmsPackage.java Module
In the same folder android/app/src/main/java/com/your_project_name where you now have probably 3 Java files, add this 4th one: DirectSmsPackage.java
//DirectSmsPackage.java
package com.your_project_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 com.enoxscanner.DirectSmsModule; // enoxscanner should be replaced with your own package name
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DirectSmsPackage implements ReactPackage {
#Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
#Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
//this is where you register the module
modules.add(new DirectSmsModule(reactContext));
return modules;
}
}
Step 3: Register DirectSmsPackage
Now register the module we have just created above there. This is almost the same as you do with those packages that you have to manually link after adding or installing them.
In the same folder, locate your MainApplication.java file and locate the below section of code then add the line highlighted as add this line: Note, you are editing the getPackages() function
#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 DirectSmsPackage()); //++ add this line here ++
return packages;
}
Step 4: Call the sendDirectSMS in you RN Script
import React, { Component } from 'react';
import { NativeModules, PermissionsAndroid } from 'react-native';
//++ import NativeModules since we are using a Native external module
...
const DirectSms = NativeModules.DirectSms;
export class SMSScreen extends Component {
sendDirectSms = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.SEND_SMS,
{
title: 'Tadiwanashe App Sms Permission',
message:
'Tadiwanashe App needs access to your inbox ' +
'so you can send messages in background.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
DirectSms.sendDirectSms('0772......', 'This is a direct message from your app.');
} else {
console.log('SMS permission denied');
}
} catch (err) {
console.warn(err);
}
}
render() {
return (
<View style={styles.mother_container}>
<View style={styles.container}>
<TextInput secureTextEntry={true} style={styles.input}
underlineColorAndroid="transparent"
placeholder="Enter PIN."
placeholderTextColor="black"
autoCapitalize="none"
onChangeText={this.handlePIN}
textAlign={'center'}
/>
<TouchableOpacity
style={styles.button}
onPress={() => this.sendDirectSms()}>
<Text style={styles.submitButtonText} selectTextOnFocus={true}> Submit </Text>
</TouchableOpacity>
</View>
<AppFooter bgColor='#fff' textColor='grey' />
</View>
)
}
}
export default SMSScreen ;
NOTE:
Such applications that auto Send SMSs might not be allowed on Google.
You will not receive SMSs until your app is Granted permission by the
user, hence we imported PermissionsAndroid.
The link above will give you proper explanation of much of the
details, this is not entirely my work but simply edited accordingly
after realising that the original code for the article had some
errors and as well the article resides on a platform which makes it
hard to give proper contributions compared to SO.

How to get the phone state in React Native

I'm using react native on and android project, and i'm in need of detect the call state of the actives calls of the android device, like incoming, connected, and etc.
I need the phone number of the incoming/outgoin cellphone too.
Thanks in advance!
With react native, you can use react-native-call-state to check the state of the call, using like this:
import React, { DeviceEventEmitter } from 'react-native'
import CallState from 'react-native-call-state';
componentWillMount() {
CallState.startListener();
this.subscription = DeviceEventEmitter.addListener('callStateUpdated', data => { console.warn(JSON.stringify(data)); });
}
componentWillUnmount() {
CallState.stopListener();
}
using java, you can use TelephonyManager, with a setup like:
public class MyPhoneStateListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
handleRinging(incomingNumber);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
handleOffHook();
break;
case TelephonyManager.CALL_STATE_IDLE:
handleIdle();
break;
}
super.onCallStateChanged(state, incomingNumber);
}
}
To get the phone number of a call, you can use react-native-call-detection, here you can have a full example of how to make it, from the beginning to the end.

how to add Headless js log geolocation for continuous interval

In Android Manifest I have added all the required permission for geolocation and added the service name as TimeTracking
package com.timetracking;
import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.HeadlessJsTaskService;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
import javax.annotation.Nullable;
public class TimeTracking extends HeadlessJsTaskService {
#Override
protected #Nullable HeadlessJsTaskConfig getTaskConfig(Intent intent) {
Bundle extras = intent.getExtras();
WritableMap data = extras != null ? Arguments.fromBundle(extras) : null;
return new HeadlessJsTaskConfig(
"TimeTracking", // Use the registered headless Task here
data,
500,
true);
}
}
And in app.js page in react native I have called it.
AppRegistry.registerHeadlessTask('TimeTracking', () => TimeTracking);
but nothing is displaying in console.Please can somebody tell the method to get timeInterval of location.
Thanks in advance.

React Native Android Native UI Component the #ReactProps doesn't execute

I have build a map Native UI Component at the Android platform. When the view is imported in the view as this
<AMapView style={styles.mapContainer} mode={2} onRegionChange={this._onReginChange.bind(this)}/>
The onRegionChange event is executed but the property method doesn't execute. enter link description here
class AMapCustomView extends Component {
constructor(props) {
super(props)
this._onRegionChange = this._onRegionChange.bind(this)
}
_onRegionChange(event: Event) {
if (!this.props.onRegionChange) {
return
}
this.props.onRegionChange(event.nativeEvent)
}
render() {
return <RCTAMap {...this.props} onRegionChange={this._onRegionChange}/>
}
}
AMapCustomView.propTypes = {
...View.propTypes,
mode: PropTypes.number,
onRegionChange: PropTypes.func
}
var RCTAMap = requireNativeComponent('RCTAMap', AMapCustomView)
module.exports = AMapCustomView;
Java Code:
#Override
public Map getExportedCustomDirectEventTypeConstants() {
return MapBuilder.of(
AMapLocationEvent.EVENT_NAME, MapBuilder.of("registrationName", "onRegionChange")
);
}
#ReactProp(name="mode", defaultInt = 1)
public void setMode(AMapView mapView, int type) {
Log.d(TAG, "mode:" + type);
}
Make sure you import com.facebook.react.uimanager.annotations.ReactProp;, I think the path used to change and the old ReactProp will no more work in more recent React Native version.