Android怎样绕开Camera打开手电筒的LED

Android原生系统没有提供手电筒的API,很多手电筒的apk都是通过打开camera然后调用Flash来打开LED。

这种传统的做法有很多弊端,首先通过camera打开手电筒,会增加因为camera出粗而导致手电筒异常的风险;其次,因为要先打开camera,然后打开Flash,因此会额外增加很多功耗。

因此理想的解决方法是,在HAL层和JNI层封装出手电筒的接口,上层应用直接调用手电筒的API打开LED。

在Android的HAL层和JNI层添加手电筒的接口,包含以下一些步骤:

1. 在HAL层添加Light的接口

a. 定义手电筒LED的文件节点路径:

char const * const TORCH_FILE = “/sys/class/leds/led:flash_torch/brightness”;

b. 定义控制手电筒LED的接口:

static int set_light_torch(struct light_device_t* dev, struct light_state_t const* state)
{
int err = 0;
pthread_mutex_lock(&g_lock);
err = write_int(TORCH_FILE, state->color & 0xFF);
pthread_mutex_unlock(&g_lock);
return err;
}

c. 定义手电筒对应的Light ID:

在Lights.h中添加 #define LIGHT_ID_TORCH “torch”

d. 在open_lights函数里面添加如下代码:

else if (0 == strcmp(LIGHT_ID_TORCH, name))
set_light = set_light_torch;

2. 在JNI层添加相应的接口

a. 在com_android_server_LightsService.cpp文件的init_native( )函数中添加手电筒的Light结构体:

devices->lights[LIGHT_INDEX_TORCH] = get_device(module, LIGHT_ID_TORCH);

b. 在Light类型的enum变量中添加手电筒的类型索引

LIGHT_INDEX_TORCH = 8,

c. 在LightService.java文件中添加手电筒Light的Id

public static final int LIGHT_ID_TORCH = 8;

3. 在Java服务层添加LightServices的接口

a. 在PowerManagerService.java文件中添加相应的接口,具体如下:

在PowerManagerService的类定义中增加手电筒Light的对象

private LightsService.Light mTorchLight;

在systemReady( )接口中创建手电筒Light的实例

mTorchLight = mLightsService.getLight(LightsService.LIGHT_ID_TORCH);

在PowerManagerService的类定义中添加调用手电筒Light的接口

@Override // Binder call
public void setTorchLight(int brightness) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
final long ident = Binder.clearCallingIdentity();
try {
setTorchLightBrightness(brightness);
} finally {
Binder.restoreCallingIdentity(ident);
}
}

public void setTorchLightBrightness(int brightness) {
LightsService.Light light;
synchronized (mLock) {
if (!mSystemReady) {
return;
}
light = mTorchLight;
}
// Control light outside of lock.
light.setBrightness(brightness);
}

b. 在PowerManager.java文件里面定义供应用层调用的手电筒API:

public void setTorchBrightness(int brightness) {
try {
mService.setTorchLight(brightness);
} catch (RemoteException e) {
}
}

c. 在IPowerManager.aidl文件中添加手电筒的接口:

void setTorchLight(int brightness);

d. 在BridgePowerManager.java文件中添加接口:

@Override
public void setTorchLight(int arg0) throws RemoteException {
// pass for now.
}

至此,从HAL到JNI的所有接口都已经添加完毕,应用层可以通过LightService来获取手电筒的Light对象,然后对手电筒进行操作。

关于Zeno Chen

本人涉及的领域较多,杂而不精 程序设计语言: Perl, Java, PHP, Python; 数据库系统: MySQL,Oracle; 偶尔做做电路板的开发,主攻STM32单片机
此条目发表在C/C++分类目录。将固定链接加入收藏夹。