您的位置:首页 > 移动开发 > Android开发

SystemProperties源码分析 获取 Android WIFI接口

2013-07-12 00:00 274 查看
**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 }
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: