本文转载自:https://blog.csdn.net/qq_33443989/article/details/77074411

1>. 编写灯光系统的HAL层 之 HAL_light.c
1<. 现在的关于灯光系统的JNI访问框架

2<. 涉及的文件

Java android_system_code/frameworks/base/services/core/java/com/android/server/lights/LightsService.java

JNI: android_system_code/frameworks/base/services/core/jni/com_android_server_lights_LightsService.cpp

Hal: lights.c

默认配色:frameworks/base/core/res/res/values/config.xml
电池灯:frameworks/base/services/core/java/com/android/server/BatteryService.java
通知灯:frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java
1
2
3
4
5
6
7
8
9
3<.怎么写代码

1<. 实现一个名为HMI的hw_module_t结构体
2<. 实现一个open函数,他会根据name返回一个light_device_t结构体
3<. 实现多个light_device_t结构体,每个对应一个DEVICE
    light_device_t结构体里的第一项是hw_module_t结构体,紧接着一个set_light的函数
1
2
3
4
2>. 开始狗血的写代码 : 参考索尼的lights.c
1<. 关键的结构体解释

设置LED状态:
    struct light_state_t {
        /**
         * The color of the LED in ARGB.
         *
         * Do your best here.
         *   - If your light can only do red or green, if they ask for blue,
         *     you should do green.
         *   - If you can only do a brightness ramp, then use this formula:
         *      unsigned char brightness = ((77*((color>>16)&0x00ff))
         *              + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;
         *   - If you can only do on or off, 0 is off, anything else is on.
         *
         * The high byte should be ignored.  Callers will set it to 0xff (which
         * would correspond to 255 alpha).
         */
        unsigned int color;  // 把灯设为什么颜色, 或 把LCD的亮度设为什么

/**
         * See the LIGHT_FLASH_* constants
         */
        int flashMode; // 是否闪烁, LIGHT_FLASH_NONE表示不闪
        int flashOnMS; // 亮的时间
        int flashOffMS;// 灭的时间

/**
         * Policy used by the framework to manage the light's brightness.
         * Currently the values are BRIGHTNESS_MODE_USER and BRIGHTNESS_MODE_SENSOR.
         */
        int brightnessMode;  // 表示LCD的背光亮度模式
    };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2<. 修改函数

set_light_backlight() : 用于控制背光的函数
    char const*const LCD_BACKLIGHT_FILE     = "/dev/backlight-1wire";
    值得一提的是 Tiny4412开发板液晶显示屏采用的是 1线协议 进行处理显示屏数据的
    同时它的驱动程序里指明最大亮度设置为127 {
        if (v > 127) {    //摘抄自Linux3.0.86 tiny4412_1wire_host.c 有厂家提供
            v = 127;
        }
    }

set_light_battery()   :用于处理电量显示的函数
set_light_notifications() : 用于处理有通知的函数
1
2
3
4
5
6
7
8
9
10
11
3<. 上传 && 编译
1<. 上传
hardware/libhardware/modules/lights/lights.c
hardware/libhardware/modules/lights/Android.mk

Android.mk内容:
        LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := lights.tiny4412
        LOCAL_MODULE_RELATIVE_PATH := hw
        LOCAL_C_INCLUDEs := hardware/libhardware
        LOCAL_SRC_FILES := lights.c
        LOCAL_SHARED_LIBRARIES := liblog
        LOCAL_MODULE_TAGS := eng

include $(BUILD_SHARED_LIBRARY)
1
2
3
4
5
6
7
8
9
10
11
12
13
2<. 修改文件:去掉默认的灯光系统文件
vim vendor/friendly-arm/tiny4412/device-tiny4412.mk

: # $(VENDOR_PATH)/proprietary/lights.tiny4412.so:system/lib/hw/lights.tiny4412.so
1
3<. 编译
. setenv
lunch
mmm hardware/libhardware/modules/lights [-B]:强制编译
make snod
./gen-img.sh

4<. 调试
logcat lights:V *:S

[发现问题]:
    1<. 打印级别低:
      [解决方法]:#define LOG_NDEBUG 0

2<. 权限不够:write_string failed to open /sys/class/leds/led1/trigger
      [解决方法]:将linux->led-class.c
          修改:led_class_attrs[]数组:
           __ATTR(brightness, 0666, led_brightness_show, led_brightness_store),
           __ATTR(trigger, 0666, led_trigger_show, led_trigger_store),

[善后工作]将修改过的文件重新上传
1
2
3
4
5
6
7
8
9
10
11
示例代码:
1<. 原厂 lights.c

/*
 * Copyright (C) 2008 The Android Open Source Project
 * Copyright (C) 2011 Diogo Ferreira <defer@cyanogenmod.com>
 * Copyright (C) 2012 The CyanogenMod Project <http://www.cyanogenmod.org>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "lights.sony"

#include <cutils/log.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <math.h>

#include <sys/ioctl.h>
#include <sys/types.h>

#include <hardware/lights.h>
#include "sony_lights.h"

/* Synchronization primities */
static pthread_once_t g_init = PTHREAD_ONCE_INIT;
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;

/* Mini-led state machine */
static struct light_state_t g_notification;
static struct light_state_t g_battery;

/* The leds we have */
enum {
    LED_RED,
    LED_GREEN,
    LED_BLUE,
    LED_BLANK
};

const int LCD_BRIGHTNESS_MIN = 10;

static int write_int (const char *path, int value) {
    int fd;
    static int already_warned = 0;

fd = open(path, O_RDWR);
    if (fd < 0) {
        if (already_warned == 0) {
            ALOGE("write_int failed to open %s\n", path);
            already_warned = 1;
        }
        return -errno;
    }

char buffer[20];
    int bytes = snprintf(buffer, sizeof(buffer), "%d\n", value);
    int written = write (fd, buffer, bytes);
    close(fd);

return written == -1 ? -errno : 0;
}

static int write_string (const char *path, const char *value) {
    int fd;
    static int already_warned = 0;

fd = open(path, O_RDWR);
    if (fd < 0) {
        if (already_warned == 0) {
            ALOGE("write_string failed to open %s\n", path);
            already_warned = 1;
        }
        return -errno;
    }

char buffer[20];
    int bytes = snprintf(buffer, sizeof(buffer), "%s\n", value);
    int written = write (fd, buffer, bytes);
    close(fd);

return written == -1 ? -errno : 0;
}

/* Color tools */
static int is_lit (struct light_state_t const* state) {
    return state->color & 0x00ffffff;
}

static int rgb_to_brightness (struct light_state_t const* state) {
    int color = state->color & 0x00ffffff;
    return ((77*((color>>16)&0x00ff))
            + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;
}

static int brightness_apply_gamma (int brightness) {
    double floatbrt = (double) brightness;
    floatbrt /= 255.0;
    ALOGV("%s: brightness = %d, floatbrt = %f", __func__, brightness, floatbrt);
    floatbrt = pow(floatbrt,2.2);
    ALOGV("%s: gamma corrected floatbrt = %f", __func__, floatbrt);
    floatbrt *= 255.0;
    brightness = (int) floatbrt;
    if (brightness < LCD_BRIGHTNESS_MIN)
        brightness = LCD_BRIGHTNESS_MIN;
    ALOGV("%s: gamma corrected brightness = %d", __func__, brightness);
    return brightness;
}

/* The actual lights controlling section */
static int set_light_backlight (struct light_device_t *dev, struct light_state_t const *state) {
    int err = 0;
    int brightness = rgb_to_brightness(state);

if (brightness > 0) {
        brightness = brightness_apply_gamma(brightness);
        brightness = 4095 * brightness / 255;
    }
    if (brightness < 188)
        brightness = 188;

ALOGV("%s brightness=%d", __func__, brightness);
    pthread_mutex_lock(&g_lock);
    err |= write_int (LCD_BACKLIGHT_FILE, brightness);
    err |= write_int (LCD_BACKLIGHT2_FILE, brightness);

pthread_mutex_unlock(&g_lock);

return err;
}

static int set_light_buttons (struct light_device_t *dev, struct light_state_t const* state) {
    return 0;
}

static void set_shared_light_locked (struct light_device_t *dev, struct light_state_t *state) {
    int r, g, b, i;
    int delayOn, delayOff;
    char *pattern=NULL;
    char dOn[8],dOff[8];

r = (state->color >> 16) & 0xFF;
    g = (state->color >> 8) & 0xFF;
    b = (state->color) & 0xFF;

delayOn = state->flashOnMS;
    delayOff = state->flashOffMS;

if (state->flashOnMS == 1)
        state->flashMode = LIGHT_FLASH_NONE;
    else {
        //PATTERN=DelayOn,DelayOff,FadeIn,FadeOut
        sprintf (dOn,"%d",delayOn);
        sprintf (dOff,"%d",delayOff);
        asprintf (&pattern,"%s,%s,100,100",dOn,dOff);
        ALOGV("pattern=%s",pattern);
    }

switch (state->flashMode) {
    case LIGHT_FLASH_TIMED:
    case LIGHT_FLASH_HARDWARE:
        for (i = 0; i < sizeof(LED_FILE_PATTERN)/sizeof(LED_FILE_PATTERN[0]); i++) {
        write_string (LED_FILE_PATTERN[i], pattern);
        }
        break;

case LIGHT_FLASH_NONE:
        for (i = 0; i < sizeof(LED_FILE_PATTERN)/sizeof(LED_FILE_PATTERN[0]); i++) {
            write_string (LED_FILE_PATTERN[i], PATTERNOFF);
        }
        break;
    }

write_int (RED_LED_FILE, r);
    write_int (GREEN_LED_FILE, g);
    write_int (BLUE_LED_FILE, b);
}

static void handle_shared_battery_locked (struct light_device_t *dev) {
    if (is_lit (&g_notification))
        set_shared_light_locked (dev, &g_notification);
    else
        set_shared_light_locked (dev, &g_battery);
}

static int set_light_battery (struct light_device_t *dev, struct light_state_t const* state) {
    pthread_mutex_lock (&g_lock);
    g_battery = *state;
    handle_shared_battery_locked(dev);
    pthread_mutex_unlock (&g_lock);
    return 0;
}

static int set_light_notifications (struct light_device_t *dev, struct light_state_t const* state) {
    pthread_mutex_lock (&g_lock);
    g_notification = *state;
    handle_shared_battery_locked(dev);
    pthread_mutex_unlock (&g_lock);
    return 0;
}

/* Initializations */
void init_globals () {
    pthread_mutex_init (&g_lock, NULL);
}

/* Glueing boilerplate */
static int close_lights (struct light_device_t *dev) {
    if (dev)
        free(dev);

return 0;
}

static int open_lights (const struct hw_module_t* module, char const* name,
                        struct hw_device_t** device) {
    int (*set_light)(struct light_device_t* dev,
                     struct light_state_t const *state);

if (0 == strcmp(LIGHT_ID_BACKLIGHT, name))
        set_light = set_light_backlight;
    else if (0 == strcmp(LIGHT_ID_BUTTONS, name))
        set_light = set_light_buttons;
    else if (0 == strcmp(LIGHT_ID_BATTERY, name))
        set_light = set_light_battery;
    else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))
        set_light = set_light_notifications;
    else
        return -EINVAL;

pthread_once (&g_init, init_globals);
    struct light_device_t *dev = malloc(sizeof (struct light_device_t));
    memset(dev, 0, sizeof(*dev));

dev->common.tag     = HARDWARE_DEVICE_TAG;
    dev->common.version = 0;
    dev->common.module  = (struct hw_module_t*)module;
    dev->common.close   = (int (*)(struct hw_device_t*))close_lights;
    dev->set_light      = set_light;

*device = (struct hw_device_t*)dev;
    return 0;
}

static struct hw_module_methods_t lights_module_methods = {
    .open = open_lights,
};

struct hw_module_t HAL_MODULE_INFO_SYM = {
    .tag        = HARDWARE_MODULE_TAG,
    .version_major  = 1,
    .version_minor  = 0,
    .id     = LIGHTS_HARDWARE_MODULE_ID,
    .name       = "Sony lights module",
    .author     = "Diogo Ferreira <defer@cyanogenmod.com>, Andreas Makris <Andreas.Makris@gmail.com>",
    .methods    = &lights_module_methods,
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
2<. 修改后 lights.c

/*
 * Copyright (C) 2008 The Android Open Source Project
 * Copyright (C) 2011 Diogo Ferreira <defer@cyanogenmod.com>
 * Copyright (C) 2012 Andreas Makris <andreas.makris@gmail.com>
 * Copyright (C) 2012 The CyanogenMod Project <http://www.cyanogenmod.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_NDEBUG 0
#define LOG_TAG "lights"
#include <cutils/log.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <hardware/lights.h>

char const*const RED_LED_FILE           = "/sys/class/leds/led1/brightness";
char const*const GREEN_LED_FILE         = "/sys/class/leds/led2/brightness";
char const*const BLUE_LED_FILE          = "/sys/class/leds/led3/brightness";
char const*const RED_LED_FILE_TRIGGER   = "/sys/class/leds/led1/trigger";
char const*const GREEN_LED_FILE_TRIGGER = "/sys/class/leds/led2/trigger";
char const*const BLUE_LED_FILE_TRIGGER  = "/sys/class/leds/led3/trigger";
char const*const RED_LED_FILE_DELAYON   = "/sys/class/leds/led1/delay_on";
char const*const GREEN_LED_FILE_DELAYON = "/sys/class/leds/led2/delay_on";
char const*const BLUE_LED_FILE_DELAYON  = "/sys/class/leds/led3/delay_on";
char const*const RED_LED_FILE_DELAYOFF  = "/sys/class/leds/led1/delay_off";
char const*const GREEN_LED_FILE_DELAYOFF= "/sys/class/leds/led2/delay_off";
char const*const BLUE_LED_FILE_DELAYOFF = "/sys/class/leds/led3/delay_off";
char const*const LCD_BACKLIGHT_FILE     = "/dev/backlight-1wire";

/* Synchronization primities */
static pthread_once_t g_init = PTHREAD_ONCE_INIT;
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
/* Mini-led state machine */
static struct light_state_t g_notification;
static struct light_state_t g_battery;

static int write_int (const char *path, int value) {
    int fd;
    static int already_warned = 0;
    fd = open(path, O_RDWR);
    if (fd < 0) {
        if (already_warned == 0) {
            ALOGE("write_int failed to open %s\n", path);
            already_warned = 1;
        }
        return -errno;
    }
    char buffer[20];
    int bytes = snprintf(buffer, sizeof(buffer), "%d\n", value);
    int written = write (fd, buffer, bytes);
    close(fd);
    return written == -1 ? -errno : 0;
}

static int write_string (const char *path, const char *value) {
    int fd;
    static int already_warned = 0;
    fd = open(path, O_RDWR);
    if (fd < 0) {
        if (already_warned == 0) {
            ALOGE("write_string failed to open %s\n", path);
            already_warned = 1;
        }
        return -errno;
    }
    char buffer[20];
    int bytes = snprintf(buffer, sizeof(buffer), "%s\n", value);
    int written = write (fd, buffer, bytes);
    close(fd);
    return written == -1 ? -errno : 0;
}

/* Color tools */
static int is_lit (struct light_state_t const* state) {
    return state->color & 0x00ffffff;
}

static int rgb_to_brightness (struct light_state_t const* state) {
    int color = state->color & 0x00ffffff;
    return ((77*((color>>16)&0x00ff))
            + (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;
}

/* The actual lights controlling section */
static int set_light_backlight (struct light_device_t *dev, struct light_state_t const *state) {
    int brightness = rgb_to_brightness(state);
    ALOGV("%s brightness=%d color=0x%08x", __func__,brightness,state->color);
    pthread_mutex_lock(&g_lock);

/* brightness 0-255 */
    /* LCD_BACKLIGHT_FILE能接收是0-127 */

write_int (LCD_BACKLIGHT_FILE, brightness/2);

pthread_mutex_unlock(&g_lock);
    return 0;
}

static void set_shared_light_locked (struct light_device_t *dev, struct light_state_t *state) {
    int r, g, b;
    int delayOn,delayOff;
    r = (state->color >> 16) & 0xFF;
    g = (state->color >> 8) & 0xFF;
    b = (state->color) & 0xFF;
    delayOn = state->flashOnMS;
    delayOff = state->flashOffMS;
    if (state->flashMode != LIGHT_FLASH_NONE) {
        write_string (RED_LED_FILE_TRIGGER, "timer");
        write_string (GREEN_LED_FILE_TRIGGER, "timer");
        write_string (BLUE_LED_FILE_TRIGGER, "timer");
        write_int (RED_LED_FILE_DELAYON, delayOn);
        write_int (GREEN_LED_FILE_DELAYON, delayOn);
        write_int (BLUE_LED_FILE_DELAYON, delayOn);
        write_int (RED_LED_FILE_DELAYOFF, delayOff);
        write_int (GREEN_LED_FILE_DELAYOFF, delayOff);
        write_int (BLUE_LED_FILE_DELAYOFF, delayOff);
    } else {
        write_string (RED_LED_FILE_TRIGGER, "none");
        write_string (GREEN_LED_FILE_TRIGGER, "none");
        write_string (BLUE_LED_FILE_TRIGGER, "none");
    }
    write_int (RED_LED_FILE, r);
    write_int (GREEN_LED_FILE, g);
    write_int (BLUE_LED_FILE, b);
}

static void handle_shared_battery_locked (struct light_device_t *dev) {
    if (is_lit (&g_notification)) {
        set_shared_light_locked (dev, &g_notification);
    } else {
        set_shared_light_locked (dev, &g_battery);
    }
}

static int set_light_battery (struct light_device_t *dev, struct light_state_t const* state) {

ALOGV("%s flashMode=%d onMS = %d offMS = %d color=0x%08x", __func__,state->flashMode,state->flashOnMS,state->flashOffMS,state->color);

pthread_mutex_lock (&g_lock);
    g_battery = *state;
    handle_shared_battery_locked(dev);
    pthread_mutex_unlock (&g_lock);
    return 0;
}

static int set_light_notifications (struct light_device_t *dev, struct light_state_t const* state) {
    ALOGV("%s flashMode=%d onMS = %d offMS = %d color=0x%08x", __func__,state->flashMode,state->flashOnMS,state->flashOffMS,state->color);
    pthread_mutex_lock (&g_lock);
    g_notification = *state;
    handle_shared_battery_locked(dev);
    pthread_mutex_unlock (&g_lock);
    return 0;
}
/* Initializations */
void init_globals () {
    pthread_mutex_init (&g_lock, NULL);
}

/* Glueing boilerplate */
static int close_lights (struct light_device_t *dev) {
    if (dev)
        free(dev);
    return 0;
}

static int open_lights (const struct hw_module_t* module, char const* name,
                        struct hw_device_t** device) {
    int (*set_light)(struct light_device_t* dev,
                     struct light_state_t const *state);
    if (0 == strcmp(LIGHT_ID_BACKLIGHT, name)) {
        set_light = set_light_backlight;
    }
    else if (0 == strcmp(LIGHT_ID_BATTERY, name)) {
        set_light = set_light_battery;
    }
    else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name)) {
        set_light = set_light_notifications;
    }
    else {
        return -EINVAL;
    }
    pthread_once (&g_init, init_globals);
    struct light_device_t *dev = malloc(sizeof (struct light_device_t));
    memset(dev, 0, sizeof(*dev));
    dev->common.tag     = HARDWARE_DEVICE_TAG;
    dev->common.version = 0;
    dev->common.module  = (struct hw_module_t*)module;
    dev->common.close   = (int (*)(struct hw_device_t*))close_lights;
    dev->set_light      = set_light;
    *device = (struct hw_device_t*)dev;
    return 0;
}

static struct hw_module_methods_t lights_module_methods = {
    .open = open_lights,
};

struct hw_module_t HAL_MODULE_INFO_SYM = {
    .tag = HARDWARE_MODULE_TAG,
    .version_major = 1,
    .version_minor = 0,
    .id = LIGHTS_HARDWARE_MODULE_ID,
    .name = "Sony lights module",
    .author = "Diogo Ferreira <defer@cyanogenmod.com>, Andreas Makris <Andreas.Makris@gmail.com>",
    .methods = &lights_module_methods,
};

Android灯光系统_编写HAL_lights.c【转】的更多相关文章

  1. 8.3 Android灯光系统_编写HAL_lights.c

    注意在led-classes.c中定义的led_class_attrs[]所建立的文件的属性应该改为0666,否则应用程序无权操作它 同时ledtrig-time.c里面对应新建的那几个delay_o ...

  2. 8.1 Android灯光系统_总体框架

    1.框架 APP(java语言实现) ------------------------------- JNI(c++语言实现)     向上提供Java执行c函数的接口  向下访问HAL ------ ...

  3. 8.6 Android灯光系统_源码分析_背光灯

    Change system screen brightness, using android.provider.Settings.System.SCREEN_BRIGHTNESSandroid-er. ...

  4. 8.5 Android灯光系统_源码分析_通知灯

    参考文章(应用程序举例)how to use the LED with Android phonehttp://androidblogger.blogspot.jp/2009/09/tutorial- ...

  5. 8.4 Android灯光系统_源码分析_电池灯

    电池灯的Java代码在batteryservice.java中 电池的状态电量等信息由驱动获得,但驱动不会主动做这些事情,因此肯定有个App调用驱动程序读取电池信息,称这个App为A应用. 还有个Ap ...

  6. Android系统--灯光系统驱动编写

    Android系统开发--Android灯光系统tiny4412_led_class驱动编写 框架分析 led_classdev_4412结构体 创建led_classdev_4412结构体 分配结构 ...

  7. Android灯光系统--通知灯深入分析【转】

    本文转自:https://www.cnblogs.com/lkq1220/p/6406261.html Android灯光系统--通知灯深入分析 通知的类别 声音 振动 闪灯 APP如何发出通知灯请求 ...

  8. Android灯光系统--通知灯深入分析

    Android灯光系统--通知灯深入分析 通知的类别 声音 振动 闪灯 APP如何发出通知灯请求 getSystemService(获得通知服务) 构造notification 类别 其他参数(颜色, ...

  9. Android灯光系统--深入理解背光灯

    Android灯光系统--深入理解背光灯 一.怎么控制背光灯(简述) APP将亮度值写入数据库 线程检测数据库的值是否发生变化 这种机制成为"内容观察者"--contentObse ...

随机推荐

  1. jQuery清除数组中的空值

    var aa = ["12", "34", "", "423", " "];   console.l ...

  2. jdk8新特性-亮瞎眼的lambda表达式

    jdk8之前,尤其是在写GUI程序的事件监听的时候,各种的匿名内部类,大把大把拖沓的代码,程序毫无美感可言!既然Java中一切皆为对象,那么,就类似于某些动态语言一样,函数也可以当成是对象啊!代码块也 ...

  3. oauth2.0学习笔记(摘抄简化)

    大量摘抄白话简明教程. 附:可以参考<RFC6749协议中文版及oauth2.0>文档 一.OAuth 白话简明教程 1.简述 http://www.cnblogs.com/Ceri/p/ ...

  4. 对象的copy

    一般来讲,java中,对象的copy一般是通过Beans.copy(B, A);用来将A对象复制给B对象,包括对象里面的属性和值. 但但但...... 这样做,有一个很严重的问题,那就是:如果把A对象 ...

  5. windows下配置lua环境

    1.进入lua官网http://www.lua.org/ 2.点击download 3.点击get a binary 4.点击[Lua - joedf's Builds] 5.选择适合自己的版本下载, ...

  6. 启动与关闭WebService

    [1]代码 /* * @brief: 启动WebServcie服务器 * @return:void */ void UPCSoftphoneClient::startWebService() { m_ ...

  7. Redis入门——Java接口

    1. maven配置 <dependency> <groupId>redis.clients</groupId> <artifactId>jedis&l ...

  8. go语言,golang学习笔记1 官网下载安装,中文社区,开发工具LiteIDE

    go语言,golang学习笔记1 官网下载安装,中文社区,开发工具LiteIDE Go语言是谷歌2009发布的专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速 ...

  9. 单台主机上DB2 10.5和arcgis 10.4 空间数据库配置

    该篇文章重点参考arcgis官网说明:http://enterprise.arcgis.com/zh-cn/server/10.4/publish-services/linux/register-db ...

  10. JXNU暑期选拔赛

    最小的数 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submissi ...