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.
Related
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.
I am having an issue with react-native-gesture-handler. Whenever I link my react-native-gesture-handler to my project it stops working and shows this error. But after unlinking react-native-gesture-handler from my project the application work fine. But as I need to navigate from several screens, I need gesture handler.
First I thought it was the problem of the react-native version as I was using react-native version 0.57.0 but it's not working on 0.58.0 and 0.55.4 either.
package com.swmansion.gesturehandler.react;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import com.facebook.react.uimanager.PointerEvents;
import com.facebook.react.uimanager.ReactPointerEventsView;
import com.facebook.react.views.view.ReactViewGroup;
import com.swmansion.gesturehandler.PointerEventsConfig;
import com.swmansion.gesturehandler.ViewConfigurationHelper;
public class RNViewConfigurationHelper implements ViewConfigurationHelper {
#Override
public PointerEventsConfig getPointerEventsConfigForView(View view) {
PointerEvents pointerEvents;
pointerEvents = view instanceof ReactPointerEventsView ?
((ReactPointerEventsView) view).getPointerEvents() :
PointerEvents.AUTO;
// Views that are disabled should never be the target of pointer events. However, their children
// can be because some views (SwipeRefreshLayout) use enabled but still have children that can
// be valid targets.
if (!view.isEnabled()) {
if (pointerEvents == PointerEvents.AUTO) {
return PointerEventsConfig.BOX_NONE;
} else if (pointerEvents == PointerEvents.BOX_ONLY) {
return PointerEventsConfig.NONE;
}
}
switch (pointerEvents) {
case BOX_ONLY: return PointerEventsConfig.BOX_ONLY;
case BOX_NONE: return PointerEventsConfig.BOX_NONE;
case NONE: return PointerEventsConfig.NONE;
}
return PointerEventsConfig.AUTO;
}
#Override
public View getChildInDrawingOrderAtIndex(ViewGroup parent, int index) {
if (parent instanceof ReactViewGroup) {
return parent.getChildAt(((ReactViewGroup) parent).getZIndexMappedChildIndex(index));
}
return parent.getChildAt(index);
}
#Override
public boolean isViewClippingChildren(ViewGroup view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && !view.getClipChildren()) {
if (view instanceof ReactViewGroup) {
String overflow = ((ReactViewGroup) view).getOverflow();
return "hidden".equals(overflow);
}
return false;
}
return true;
}
}
You can try manual linking.
Also check this issue out :
https://github.com/kmagiera/react-native-gesture-handler/issues/205
If you get the problem in Android, but not iOS, it could be that you need to add a polyfill for symbols. I can't remember where I found this, but I have used it in my own projects and it works. Just stick it in your index.js:
if (Platform.OS === 'android') {
if (typeof Symbol === 'undefined') {
if (Array.prototype['##iterator'] === undefined) {
Array.prototype['##iterator'] = function() {
let i = 0;
return {
next: () => ({
done: i >= this.length,
value: this[i++]
})
};
};
}
}
}
Is proper way to declare model class like java and how to pass this into second screen in react native?
export default class UserModel {
stateName;
username;
email;
mobile;
gender;
address;
constructor() {}
setStateName(stateName) {
this.stateName = stateName;
}
setUserName(username) {
this.username = username;
}
setEmail(email) {
this.email = email;
}
setMobile(mobile) {
this.mobile = mobile;
}
setGender(gender) {
this.gender = gender;
}
setAddress(address) {
this.address = address;
}
}
Step 1: Make UserModel.js
class UserModel {
constructor() {
stateName,
username,
email,
mobile,
gender,
address;
}
}
Note: Do not Export it if you don't want to set globally.
Step 2 : Screen1.js - Set UserModel and pass from screen1.
_handlePress = async () => {
UserModel.username = "Vishal Patoliya"
this.props.navigation.navigate('UserList',{userData: UserModel});
}
Step 3 : Receiving model class at another screen.
render() {
console.log(TAG, "render() Called.")
const UserModel = this.props.navigation.getParam('userData');
console.log("Username", UserModel.username)
}
OutPut :
01-16 17:30:32.085 4541 5638 I ReactNativeJS: 'Username', 'Vishal Patoliya'
Edit:
After some discussion, this was required answer:
this.props.navigation.navigate('UserList', { userModel: userModel });
this.props.getParam('userModel', /* optional default value */);
I assume this is your UserModel.js.
Now you are able to import the model like other components:
import UserModel from './location/UserModel';
But if you do it like this, you'd have to instanciate UserModel every time you import it.
If you'd like to prevent this, just instanciate a UserModel and export it inside the UserModel.js and import the instance anywhere.
Like this:
class UserModel {
//...
}
export default new UserModel();
other way might be:
export class UserModel {
//...
}
const GlobalUserModel = new UserModel();
export default GlobalUserModel;
to choose in other files what to import:
import { UserModel } from './location/UserModel'; //get new instance
or
import GlobalUserModel from './location/UserModel'; //get global instance
If imported via { UserModel }, you have to instanciate first: new UserModel()
...or vice versa.
Using AureliaCLI and TypeScript.
I have a service which returns a specific type and a component which incorrectly assigns the returned object to a variable of another type:
import { ItemService } from "./itemService";
import { Item } from '../server/backend';
export class ItemDetails {
item: Item = null;
constructor(private itemService: ItemService) {
}
activate() {
this.item = this.itemService.getItem();
}
}
and
import { Seat } from "../server/backend";
export class ItemService {
item: Seat;
constructor() {
this.item = null;
}
getItem(){
return this.item;
}
setItem(item: Seat){
this.item = item;
}
}
This will generate an error when 'au run --watch' is run the first time, but any subsequent change to either file does not produce an error.
Can I configure AureliaCLI to look at dependant files also?
Thanks
Right, as you can probably guess, I am new to TypeScript.
I forgot to add a return type to the service method...
This will cause the error to be triggered:
getItem(): Seat {
return this.item;
}
I am writing a react native app to get IOS and Android Battery status. I search through the net and found few libraries which can get battery level of the phone.
https://github.com/robinpowered/react-native-device-battery
https://github.com/remobile/react-native-battery-status
https://github.com/oojr/react-native-battery
Every library has issues when I try that and not much support for the developer when ask a question on git hub.
Can any one provide me better solution or library to get Battery status of IOS and Android.
Thanks in advance
I wrote my own IOS and Android classes to get the Battery Status. Here are the steps if any one interested on that,
For IOS,
Open the iOS project in XCode
Create 2 new files call BatteryStatus.h and BatteryStatus.m
BatteryStatus.h file should contain following code
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
#interface BatteryStatus : RCTEventEmitter <RCTBridgeModule>
#end
BatteryStatus.m file should
#import "BatteryStatus.h"
#implementation BatteryStatus
RCT_EXPORT_MODULE(BatteryStatus)
- (instancetype)init
{
if ((self = [super init])) {
[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
}
return self;
}
RCT_EXPORT_METHOD(hide) {
}
RCT_EXPORT_METHOD(updateBatteryLevel:(RCTResponseSenderBlock)callback)
{
callback(#[[self getBatteryStatus]]);
}
//manually get battery status by calling following method
-(NSDictionary*)getBatteryStatus
{
float batteryLevel = [UIDevice currentDevice].batteryLevel;
NSObject* currentLevel = nil;
currentLevel = [NSNumber numberWithFloat:(batteryLevel * 100)];
NSMutableDictionary* batteryData = [NSMutableDictionary dictionaryWithCapacity:2];
[batteryData setObject:currentLevel forKey:#"level"];
return batteryData;
}
#end
Inside your react native app, inside your js file add following code
import { NativeModules } from 'react-native';
constructor(props) {
super(props);
this.state = {
batteryLevel: null,
};
}
componentDidMount() {
NativeModules.BatteryStatus.updateBatteryLevel((info) => {
//console.log(info.level)
const level = Math.ceil(info.level);
this.setState({ batteryLevel: level});
});
}
For IOS above code is working for me to get the battery level
For Android,
Open the Android project in Android Studio
Create a group call BatteryStatus and include 2 Files named , BatteryStatusModule.java and BatteryStatusPackage.java
BatteryStatusModule.java Should contain following code
package com.yourproject.BatteryStatus;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
public class BatteryStatusModule extends ReactContextBaseJavaModule {
public BatteryStatusModule(ReactApplicationContext reactContext) {
super(reactContext);
}
#Override
public String getName() {
return "BatteryStatus";
}
#ReactMethod
public void getBatteryStatus(Callback successCallback) {
Intent batteryIntent = getCurrentActivity().registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
if(level == -1 || scale == -1) {
level = 0;
}
//System.out.print("battery level");
//System.out.print(level);
successCallback.invoke(null ,((float)level / (float)scale) * 100.0f);
}
}
BatteryStatusPackage.java should contain following code
package com.yourproject.BatteryStatus;
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 BatteryStatusPackage implements ReactPackage {
#Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new BatteryStatusModule(reactContext));
return modules;
}
#Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
#Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
Inside MainApplication.java include following code
#Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new MapsPackage(),
new BatteryStatusPackage()
);
}
Inside your react native app, inside your js file add following code
import { NativeModules } from 'react-native';
constructor(props) {
super(props);
this.state = {
batteryLevel: null
};
}
getBatteryLevel = (callback) => {
NativeModules.BatteryStatus.getBatteryStatus(callback);
}
6.Call it something like this:
componentDidMount() {
this.getBatteryLevel((batteryLevel) => {
console.log(batteryLevel);
});
}
For Android above code is working for me to get the battery level
Hope this will help some one to get battery level for IOS and ANDROID
We can use react-native-device-info for getting any device's specific information.
Install with command
npm install --save react-native-device-info
# or
yarn add react-native-device-info
Get the battery level of the device as a float comprised between 0 and 1 with getBatteryLevel().
DeviceInfo.getBatteryLevel().then(batteryLevel => {
console.log(batteryLevel);
// 0.759999
});
Note:
Returns -1 on the iOS Simulator
Just some addition to the right answer. You have to override the 'supportedEvents' function in the BatteryStatus.m file to make it work like this :
-(NSArray<NSString *> *)supportedEvents{
return #[#"level"];
}