React Native读取系统属性

一、背景

        前段时间,公司需要用React Native做一套电视机顶盒上的视频播放系统,而其中有一项功能是需要读取到机顶盒的卡号,这个卡号提前被生产商写入了系统属性,叫“persist.sys.mmcp.smarcardid”,通过在命令行运行adb shell后,再运行getprop命令可以查出来,如下图:

React Native读取系统属性_第1张图片

        但React Native本身并不提供直接读取系统属性的功能,这时候就需要手动开发一个原生插件来完成这项功能,具体步骤如下。

 二、创建插件

1、创建SystemProperty类

在android\app\src\main\java\com\videoplayer下创建一个java类SystemProperty.java

React Native读取系统属性_第2张图片

 源码如下:

package com.videoplayer;

import android.widget.Toast;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import androidx.annotation.NonNull;

public class SystemProperty extends ReactContextBaseJavaModule {

    private static ReactApplicationContext reactContext;

    private static Method sysPropGet;
    private static Method sysPropSet;

    static {
        try {
            Class S = Class.forName("android.os.SystemProperties");
            Method M[] = S.getMethods();
            for (Method m : M) {
                String n = m.getName();
                if (n.equals("get")) {
                    sysPropGet = m;
                } else if (n.equals("set")) {
                    sysPropSet = m;
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public SystemProperty(ReactApplicationContext context) {
        super(context);
        reactContext = context;
    }

    @NonNull
    @Override
    public String getName() {
        return "SystemProperty";
    }

    @ReactMethod
    public void getSystemProperty(String name,Promise promise) {
        try {
            String value=(String) sysPropGet.invoke(null, name,"");
            promise.resolve(value);
        } catch (Exception e) {
            Toast.makeText(getReactApplicationContext(), "获取卡号出错", Toast.LENGTH_LONG).show();
            promise.reject("获取卡号出错", e);
            e.printStackTrace();
        }
    }
}

该类继承了ReactContextBaseJavaModule,这是开发React Native插件必须要继承的类,并在getName方法中返回SystemProperty,当然也可以返回其他名字,这个名字是在前端JavaScript中要用到的。其中getSystemProperty方法的第一个参数为要获取的系统属性名,第二个参数为Promise类型,在JavaScript端可以使用awiat或then的方式获取数据。

Java 方法需要使用注解@ReactMethod。方法的返回类型必须为void。React Native 的跨语言访问是异步进行的,所以想要给 JavaScript 返回一个值的唯一办法是使用回调函数或者发送事件。

2、创建SystemPropertyPackage类

在 Java 这边要做的最后一件事就是注册这个模块。我们需要在应用的 Package 类的createNativeModules方法中添加这个模块。如果模块没有被注册,它也无法在 JavaScript 中被访问到。在android\app\src\main\java\com\videoplayer下创建一个java类SystemPropertyPackage.java。这个 package 需要在MainApplication.java文件的getPackages方法中提供。这个文件位于你的 react-native 应用文件夹的 android 目录中。

React Native读取系统属性_第3张图片

 源码如下:

package com.videoplayer;

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 androidx.annotation.NonNull;

public class SystemPropertyPackage implements ReactPackage {
    @NonNull
    @Override
    public List createNativeModules(@NonNull ReactApplicationContext reactContext) {
        List modules = new ArrayList<>();

        modules.add(new SystemProperty(reactContext));

        return modules;
    }

    @NonNull
    @Override
    public List createViewManagers(@NonNull ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

3、修改MainApplication类 

在MainApplication.java中添加如下行,注册SystemProperty插件

React Native读取系统属性_第4张图片

三、使用插件

import {
    NativeModules
} from 'react-native';


let value=await NativeModules.SystemProperty.getSystemProperty("persist.sys.mmcp.smarcardid");

你可能感兴趣的:(移动终端,React,Native,大数据)