本文转载自: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. docker中crontab无法执行

    1.下载的镜像是ubuntu最简版,默认没有安装crontab 2.业务需求需要crontab 最早解决方案 1.在宿主机里面 1 3  * * * root  cd /data/wwwroot/xx ...

  2. Usefull Resources

    Sql Server Profiler 1. http://www.cnblogs.com/Fooo/archive/2013/02/19/2916789.html 2. http://5439255 ...

  3. Git-分支的建立与合并

    举一个实际工作中可能会遇到的分支建立与合并的例子: 开发某个网站. 为实现某个新的需求,创建一个分支. 在这个分支上开展工作. 假设此时,你突然接到一个电话说有个很严重的问题需要紧急修补,那么可以按照 ...

  4. ps 证件照(1,2寸)

    制作证件照      9*9打印 1,1寸  图片裁剪 2, 2寸 图片裁剪 3,将裁剪完成后的图片选择添加画布  Alt Ctrl  c 将高和宽各加20px  ,背景选择白色 4,将得到的带有白色 ...

  5. sitecore系统教程之内容编辑器中创建项目

    在内容编辑器中创建新项目时,必须先在内容树中选择一个项目,以指示新项目的位置.您可以创建一个新项目作为您选择的项目的兄弟或子项目: 兄弟是您在与所选项目相同的级别创建的项目. 子项是您在所选项下创建的 ...

  6. Robot Framework 遇到过的错误 1. Chrome打开无法数据网址,地址栏只显示data:,

    问题描述:用RF打开网页时未跳转到指定网址,而是显示data:, *** Settings ***Library SeleniumLibrary *** Test Cases ***Login_Tes ...

  7. 20165305 实验三 敏捷开发与XP实践

    实验3-1 敏捷开发与XP实践 http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替换成IDEA 参考 http://www.cnblog ...

  8. Java基础整理

    一.Java中的遍历 1.在java开发中会碰到遍历List删除其中多个元素的情况,如果使用一般的for循环以及增强的for循环,代码会抛出异常ConcurrentModificationExcept ...

  9. javamail邮件Multipart支持同时发text和html混合消息,alternative纯文本与超文本共存

    javamail邮件Multipart支持同时发text和html混合消息alternative纯文本与超文本共存 multipart/mixed:附件. multipart/related:内嵌资源 ...

  10. linux下php中文UTF-8转换Unicode方法和注意事项

    先说下遇到问题:1.php没有内置unicode_ecode函数可以直接使用 2.网上很多资料都是用$str = iconv($encoding, 'UCS-2', $str); window下转换出 ...