react-nativebatterylevelnative-modulereact-native-native-module

React Native Get battery status / level Using Native Modules


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


Solution

  • 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,

    1. Open the iOS project in XCode
    2. 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
    
    1. 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,

    1. Open the Android project in Android Studio
    2. 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();
    }
    }
    
    1. Inside MainApplication.java include following code

      @Override
      protected List<ReactPackage> getPackages() {
        return Arrays.<ReactPackage>asList(
            new MainReactPackage(),
              new MapsPackage(),
              new BatteryStatusPackage()
        );
      }
      
    2. 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