Giter Club home page Giter Club logo

react-native-android-datausage's Introduction

React Native Module for Android - Data Usage per App

This React Native module shows data usage per application in Android (required version 4.4 or later). Your React Native app should be able to read Android Data Usage statistics.

alt text

It uses TrafficStats or NetworkStatsManager (requires Android 6.0 or later).

Installing it as a module in your project

There are many ways to do this, here's the way I do it:

  1. Do npm install --save git+https://github.com/shimatai/react-native-android-datausage.git in your React Native main project.

  2. Link the library:

    • Add the following to android/settings.gradle:

      include ':react-native-android-datausage'
      project(':react-native-android-datausage').projectDir = new File(settingsDir, '../node_modules/react-native-android-datausage/android')
      
    • Add the following to android/app/build.gradle:

      ...
      
      dependencies {
          ...
          compile project(':react-native-android-datausage')
      }
    • Add the following to android/app/src/main/java/**/MainApplication.java:

      package com.company.myapp;
      
      import br.com.oi.reactnative.module.datausage.DataUsagePackage;  // add this for react-native-android-datausage
      
      public class MainApplication extends Application implements ReactApplication {
      
          @Override
          protected List<ReactPackage> getPackages() {
              return Arrays.<ReactPackage>asList(
                  new MainReactPackage(),
                  new DataUsagePackage()     // add this for react-native-android-datausage
              );
          }
      }
    • You need to request some specific permissions to user, so add the following permissions to AndroidManifest.xml (don't forget to declare the XML namespace xmlns:tools):

      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              package="com.company.myapp"
              android:versionCode="1"
              android:versionName="1.0">
      
              <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
              <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
              <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
              <uses-permission
                      android:name="android.permission.PACKAGE_USAGE_STATS"
                      tools:ignore="ProtectedPermissions"/>
      
              <permission
                      android:name="android.permission.PACKAGE_USAGE_STATS"
                      android:protectionLevel="signature"/>
      
              ...
      
      </manifest>
    • For Android 6 or later, user needs to allow the requested permissions, so add the following code to android/app/src/main/java/**/MainActivity.java after the method getMainComponentName():

      package com.company.myapp;
      
      import android.Manifest;
      import android.annotation.TargetApi;
      import android.app.AppOpsManager;
      import android.content.Context;
      import android.content.Intent;
      import android.content.pm.PackageManager;
      import android.os.Build;
      import android.provider.Settings;
      import android.support.v4.app.ActivityCompat;
      
      private static final int READ_PHONE_STATE_REQUEST = 37;
      
      ...
      
      @Override
      protected void onResume() {
              super.onResume();
              requestPermissions();
      }
      
      private void requestPermissions() {
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
              if (!hasPermissionToReadNetworkHistory()) {
                      return;
              }
      
              if (!hasPermissionToReadPhoneStats()) {
                      requestPhoneStateStats();
                      return;
              }
          }
      }
      
      private boolean hasPermissionToReadNetworkHistory() {
              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                      return true;
              }
              final AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
              int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
              android.os.Process.myUid(), getPackageName());
              if (mode == AppOpsManager.MODE_ALLOWED) {
                      return true;
              }
              appOps.startWatchingMode(AppOpsManager.OPSTR_GET_USAGE_STATS,
                      getApplicationContext().getPackageName(),
                      new AppOpsManager.OnOpChangedListener() {
                              @Override
                              @TargetApi(Build.VERSION_CODES.M)
                              public void onOpChanged(String op, String packageName) {
                                      int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS, android.os.Process.myUid(), getPackageName());
                                      if (mode != AppOpsManager.MODE_ALLOWED) {
                                              return;
                                      }
                                      appOps.stopWatchingMode(this);
                                      Intent intent = new Intent(MainActivity.this, MainActivity.class);
                                      if (getIntent().getExtras() != null) {
                                              intent.putExtras(getIntent().getExtras());
                                      }
                                      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                                      getApplicationContext().startActivity(intent);
                              }
              });
              requestReadNetworkHistoryAccess();
              return false;
      }
      
      private boolean hasPermissionToReadPhoneStats() {
              if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED) {
                      return false;
              } else {
                      return true;
              }
      }
      
      private void requestReadNetworkHistoryAccess() {
              Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
              startActivity(intent);
      }
      
      private void requestPhoneStateStats() {
              ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, READ_PHONE_STATE_REQUEST);
      }
  3. Simply add NativeModules to import this React Native module:

    import { NativeModules } from 'react-native';
    
    if (NativeModules.DataUsageModule) {
        // Get data usage of all installed apps in current device
        // Parameters "startDate" and "endDate" are optional (works only with Android 6.0 or later). Declare empty object {} for no date filter.
        NativeModules.DataUsageModule.listDataUsageByApps({
            "startDate": new Date(2017, 4, 22, 0, 0, 0, 0).getTime(), // 1495422000000 = Mon May 22 2017 00:00:00
            "endDate": new Date().getTime()
        },
        (err, jsonArrayStr) => {
            if (!err) {
    	    var apps = JSON.parse(jsonArrayStr);
    	    console.log(apps);
    	    for (var i = 0; i < apps.length; i++) {
    		    var app = apps[i];
    		    console.log("App name: " + app.name + "\n" 
    				    + "Package name: " + app.packageName + "\n"
    				    + "Received bytes: " + app.rx + "bytes\n"
    				    + "Transmitted bytes: " + app.tx + "bytes\n"
    				    + "Received MB: " + app.rxMb + "\n"
    				    + "Transmitted MB: " + app.txMb);
    	    }
            }
        });
    
        // Get data usage of specific list of installed apps in current device
        // Example: get data usage for Facebook, YouTube and WhatsApp.
        // Parameters "startDate" and "endDate" are optional (works only with Android 6.0 or later)
        NativeModules.DataUsageModule.getDataUsageByApp({
                "packages": ["com.facebook.katana", "com.google.android.youtube", "com.whatsapp"],
                "startDate": new Date(2017, 4, 22, 0, 0, 0, 0).getTime(), // 1495422000000 = Mon May 22 2017 00:00:00
                "endDate": new Date().getTime()
            }, 
            (err, jsonArrayStr) => {
                if (!err) {
    	    var apps = JSON.parse(jsonArrayStr);
    	    console.log(apps);
    	    for (var i = 0; i < apps.length; i++) {
    		    var app = apps[i];
    		    console.log("App name: " + app.name + "\n" 
    				    + "Package name: " + app.packageName + "\n"
    				    + "Received bytes: " + app.rx + "bytes\n"
    				    + "Transmitted bytes: " + app.tx + "bytes\n"
    				    + "Received MB: " + app.rxMb + "\n"
    				    + "Transmitted MB: " + app.txMb);
    	    }
            }
        });
    
        // Check if app has permission to access data usage by apps
        // This way will not ask for permissions (check only)
        // If you pass "requestPermission": "true", then app will ask for permissions.
        NativeModules.DataUsageModule.requestPermissions({ "requestPermission": "false" }, (err, result) => {
            var permissionObj = JSON.parse(result);
            if (!permissionObj.permissions) {
                Alert.alert('Give Permission', 
                            'You need to enable data usage access for this app. Please, enable it on the next screen.',
                        [
                            { text: 'Cancel', style: 'cancel', onPress: () => Actions.pop() },
                            { text: 'Give permission', onPress: () => this.requestPermissions() }
                        ],
                        { cancelable: false });
            }
        });
    }

react-native-android-datausage's People

Contributors

brendonhc avatar robo360 avatar shimatai avatar tketa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

react-native-android-datausage's Issues

Don't work on real device running android 8.0

This is a great module that work on the simulator, but when running on a real device (android 8.0) the list of installed apps always returns an empty array. Please if you have a working example it would be great if you can share it with us or if you can give us some hints about how to fix that.

Thank you for your effort and work.

ios support

I see that you did a great job creating this modules and the community is thankful for your work but is there any alternative for ios. or are you planing to add ios support for this library.

and once again thanks for your work.

Why is there no sample?

I saw you wrote more detailed DEADME, it's not bad,I think you must be trying to help someone, but why is there no sample or can direct run sample's apk .I can't confrom this library is useful, maybe it's useful in most devices, but you known android system is too many factory modify it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.