SystemProperties源码分析 获取 Android WIFI接口

**SystemProperties.java这个类是@hide的,**所以不对外公开,一般开发者是访问不到的,但是我们可以通过反射机制来使用。通过反射取得wifi的接口名为例!

<!-- lang: java -->
public class SystemInfo{
    private Method methodGetProperty;
    private static SystemInfo instance = new SystemInfo();

    public static SystemInfo getInstance() {
      	return instance;
      }

    private SystemInfo(){
        Class classSystemProperties = Class.forName("android.os.SystemProperties");
         methodGetProperty = classSystemProperties.getMethod("get", String.class);
    }

    public String getProperty(String property) {
        if(methodGetProperty == null) return null;
      	try {

      	  return (String)methodGetProperty.invoke(null, property);

      	} catch(IllegalAccessException e) {
      	  Log.w(TAG, "Failed to get property");
      	} catch(InvocationTargetException e) {
      	  Log.w(TAG, "Exception thrown while getting property");
      	}
      	return null;
   }

   public static void main()
    {
        String interfaceName = 
                        SystemInfo.getInstance().getProperty("wifi.interface");
    }
}

下面通过Android源码讲解SystemProperties.java

SystemProperties.java 在android源码的位置:frameworks/base/core/java/android/os/SystemProperties;

<!-- lang: java -->
public class SystemProperties
{
    public static final int PROP_NAME_MAX = 31;
    public static final int PROP_VALUE_MAX = 91;

    private static native String native_get(String key);
    private static native String native_get(String key, String def);
    private static native int native_get_int(String key, int def);
    private static native long native_get_long(String key, long def);
    private static native boolean native_get_boolean(String key, boolean def);
    private static native void native_set(String key, String def);
    
    public static String get(String key) {
        if (key.length() > PROP_NAME_MAX) {
            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
        }
        return native_get(key);
    }
    public static String get(String key, String def) {
        if (key.length() > PROP_NAME_MAX) {
            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
        }
        return native_get(key, def);
    }
}

这边使用JNI调用了本地方法,这些方法位于:"frameworks/base/core/jni/android_os_SystemProperties.cpp"

<!-- lang: cpp -->
#include "cutils/properties.h"
#include "jni.h"
#include "android_runtime/AndroidRuntime.h"
#include <nativehelper/JNIHelp.h>

namespace android
{
    static jstring SystemProperties_getSS(JNIEnv *env, jobject clazz,
                                          jstring keyJ, jstring defJ)
    {
        int len;
        const char* key;
        char buf[PROPERTY_VALUE_MAX];
        jstring rvJ = NULL;
    
        if (keyJ == NULL) {
            jniThrowNullPointerException(env, "key must not be null.");
            goto error;
        }
        key = env->GetStringUTFChars(keyJ, NULL);
        len = property_get(key, buf, "");
        if ((len <= 0) && (defJ != NULL)) {
            rvJ = defJ;
        } else if (len >= 0) {
            rvJ = env->NewStringUTF(buf);
        } else {
            rvJ = env->NewStringUTF("");
        }  
        env->ReleaseStringUTFChars(keyJ, key);
    error:
        return rvJ;
    }
    
    static jstring SystemProperties_getS(JNIEnv *env, jobject clazz,
                                          jstring keyJ)
    {
        return SystemProperties_getSS(env, clazz, keyJ, NULL);
    }
    
    static JNINativeMethod method_table[] = {
        { "native_get", "(Ljava/lang/String;)Ljava/lang/String;",
          (void*) SystemProperties_getS },
        { "native_get", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
          (void*) SystemProperties_getSS },
        { "native_get_int", "(Ljava/lang/String;I)I",
          (void*) SystemProperties_get_int },
        { "native_get_long", "(Ljava/lang/String;J)J",
          (void*) SystemProperties_get_long },
        { "native_get_boolean", "(Ljava/lang/String;Z)Z",
          (void*) SystemProperties_get_boolean },
        { "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
          (void*) SystemProperties_set },
    };
    int register_android_os_SystemProperties(JNIEnv *env)
    {
        return AndroidRuntime::registerNativeMethods(
            env, "android/os/SystemProperties",
            method_table, NELEM(method_table));
    }
    
};

其中JNINativeMethod是一个结构体,具体定义,请参考

<!-- lang: cpp -->
#include "jni.h"

最后调用了 <!-- lang: cpp --> #include "android_runtime/AndroidRuntime.h"
中的方法:

<!-- lang: cpp -->
int  register_android_os_SystemProperties(JNIEnv *env)

将本地方法注册到虚拟机中

接下来我们分析一下Android系统的Properties

有一些特殊命名的属性会有不同的效果

如ro.开头的属性是只读的

persist.开头的属性,即使重启手机,仍然会存在

Android 的系统属性包括两部分:文件保存的持久属性和每次开机导入的cache属性。前者主要保存在下面几个文件中(列出部分):

bionic/libc/include/sys/_system_properties.h

<!-- lang: cpp -->
#define PROP_SERVICE_NAME "property_service"
#define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"
#define PROP_PATH_SYSTEM_BUILD     "/system/build.prop"
#define PROP_PATH_SYSTEM_DEFAULT   "/system/default.prop"
#define PROP_PATH_LOCAL_OVERRIDE   "/data/local.prop"

system/core/include/private/android_filesystem_config.h

<!-- lang: cpp -->
#define AID_ROOT             0  /* traditional unix root user */
#define AID_SYSTEM        1000  /* system server */
#define AID_RADIO         1001  /* telephony subsystem, RIL */
#define AID_DHCP          1014  /* dhcp client */
#define AID_SHELL         2000  /* adb and debug shell user */
#define AID_CACHE         2001  /* cache access */
#define AID_APP          10000 /* first app user */

system/core/init/property_service.c

系统属性的命名必须以下面这些字段开头,不同的字段需要不同的权限:

<!-- lang: cpp -->
struct {
    const char *prefix;
    unsigned int uid;
    unsigned int gid;
} property_perms[] = {
    { "net.rmnet0.",      AID_RADIO,    0 },
    { "net.gprs.",        AID_RADIO,    0 },
    { "net.ppp",          AID_RADIO,    0 },
    { "net.qmi",          AID_RADIO,    0 },
    { "net.lte",          AID_RADIO,    0 },
    { "net.cdma",         AID_RADIO,    0 },
    { "ril.",             AID_RADIO,    0 },
    { "gsm.",             AID_RADIO,    0 },
    { "persist.radio",    AID_RADIO,    0 },
    { "net.dns",          AID_RADIO,    0 },
    { "sys.usb.config",   AID_RADIO,    0 },
    { "net.",             AID_SYSTEM,   0 },
    { "dev.",             AID_SYSTEM,   0 },
    { "runtime.",         AID_SYSTEM,   0 },
    { "hw.",              AID_SYSTEM,   0 },
    { "sys.",             AID_SYSTEM,   0 },
    { "service.",         AID_SYSTEM,   0 },
    { "wlan.",            AID_SYSTEM,   0 },
    { "dhcp.",            AID_SYSTEM,   0 },
    { "dhcp.",            AID_DHCP,     0 },
    { "debug.",           AID_SHELL,    0 },
    { "log.",             AID_SHELL,    0 },
    { "service.adb.root", AID_SHELL,    0 },
    { "service.adb.tcp.port", AID_SHELL,    0 },
    { "persist.sys.",     AID_SYSTEM,   0 },
    { "persist.service.", AID_SYSTEM,   0 },
    { "persist.security.", AID_SYSTEM,   0 },
    { NULL, 0, 0 }
};

转载于:https://my.oschina.net/mopidick/blog/144255

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值