![]()
今回はHTC Desireに備わっているLED(カメラ撮影用フラッシュ)をネイティブから制御してON/OFFしてみる。
まずはHTC Developerセンターhttp://developer.htc.com/からDesireのソースコードをダウンロードする。今回は「bravo-2.6.32-gd96f2c0.tar.gz」でした。
![]()
ダウンロードしている間に雛形となるプロジェクトをEasyProjectGenerator for Androidで作る。今回はC++プロジェクトとした。
![]()
そして自動生成されたプロジェクトのjniフォルダに、ダウンロードしたHTC Desireのソースコードに含まれるmsm_camera.hをコピーする。
具体的なパスは「bravo-2.6.32-gd96f2c0\ include\ media\ msm_camera.h」。スクリーンキャプチャ用の環境ではtar.gzを解凍できなかったので別PCで解凍してコピーしてきました。
![]()
次にEclipseでプロジェクトを読み込んで実際にLEDを制御するコードを実装する。
#if(true)
#define LOCAL_LOG
#define LOCAL_LOGD
#endif
#include <string.h>
#include <jni.h>
#ifdef LOCAL_LOG
#include <android/log.h>
#endif
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include "msm_camera.h"
/*
//msm_camera.hより
#define MSM_CAM_IOCTL_MAGIC 'm'
#define MSM_CAM_IOCTL_FLASH_LED_CFG _IOW(MSM_CAM_IOCTL_MAGIC, 22, unsigned *)
#define MSM_CAMERA_LED_OFF 0
#define MSM_CAMERA_LED_LOW 1
#define MSM_CAMERA_LED_HIGH 2
#define MSM_CAMERA_LED_LOW_FOR_SNAPSHOT 3
*/
//
// フラッシュコントロール
//
//nModeはMSM_CAMERA_LED_OFF、MSM_CAMERA_LED_LOW、MSM_CAMERA_LED_HIGHなど
//
//事前に↓を実行すること!
// "chmod 666 /dev/msm_camera/config0"
//
int CtrlCameraLED(int nMode)
{
int fd;
int nRet;
fd = open("/dev/msm_camera/config0",O_RDWR | O_NONBLOCK);
if(fd < 0)
return 0;
msm_camsensor_info info;
memset(&info,0,sizeof(info));
nRet = ioctl(fd,MSM_CAM_IOCTL_GET_SENSOR_INFO,&info);
if(nRet < 0 || info.flash_enabled == 0)
{
close(fd);
return 0;
}
nRet = ioctl(fd,MSM_CAM_IOCTL_FLASH_LED_CFG,&nMode);
close(fd);
if(nRet < 0)
return 0;
return 1;
}
//
//フラッシュをサポートしないなら0、サポートするなら0以外を返す
//
//事前に↓を実行すること!
// "chmod 666 /dev/msm_camera/config0"
//
int IsSupportCameraLED(void)
{
int fd;
int nOnOff; //uint_32
int nRet;
msm_camsensor_info info;
fd = open("/dev/msm_camera/config0",O_RDWR | O_NONBLOCK);
if(fd < 0)
return 0;
memset(&info,0,sizeof(info));
nRet = ioctl(fd,MSM_CAM_IOCTL_GET_SENSOR_INFO,&info);
close(fd);
if(nRet < 0)
return 0;
if(info.flash_enabled)
return 1;
return 0;
}
//
// カメラセンサー名の取得
//
//事前に↓を実行すること!
// "chmod 666 /dev/msm_camera/config0"
//
int GetCameraSensorName(char* pszName,int nLen)
{
int fd;
int nOnOff; //uint_32
int nRet;
msm_camsensor_info info;
if(nLen < MAX_SENSOR_NAME)
return 0;
fd = open("/dev/msm_camera/config0",O_RDWR | O_NONBLOCK);
if(fd < 0)
return 0;
memset(&info,0,sizeof(info));
nRet = ioctl(fd,MSM_CAM_IOCTL_GET_SENSOR_INFO,&info);
close(fd);
if(nRet < 0)
return 0;
strcpy(pszName,info.name);
return 1;
}
extern "C"
jboolean Java_com_Test132_Test132Act_NativeIsSupportCameraLED(JNIEnv* env,jobject thiz)
{
if(IsSupportCameraLED)
return JNI_TRUE;
return JNI_FALSE;
}
extern "C"
jboolean Java_com_Test132_Test132Act_NativeCtrlCameraLED(JNIEnv* env,jobject thiz,jint nMode)
{
if(CtrlCameraLED(nMode))
return JNI_TRUE;
return JNI_FALSE;
}
extern "C"
jstring Java_com_Test132_Test132Act_NativeGetSensorName(JNIEnv* env,jobject thiz)
{
char pszName[MAX_SENSOR_NAME];
if(GetCameraSensorName(pszName,MAX_SENSOR_NAME) == 0)
return env->NewStringUTF("Failed");
return env->NewStringUTF(pszName);
}
![]()
java側では、画面をタッチしたら順々にLEDの光量を変更するようにします。
また、/dev/msm_camera/config0を開くには事前にRW属性を付けておかないといけない&RW属性を付けるにはroot権限が必要なので、suコマンドによりchmodを実行する関数も作っておきます。
これで実機で実行すると、、、
package com.Test132;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.TextView;
public class Test132Act extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ExecSuCommand("chmod 666 /dev/msm_camera/config0");
NativeCtrlCameraLED(_nCurrentMode);
TextView tv = new TextView(this);
tv.setText( NativeGetSensorName() );
setContentView(tv);
}
boolean ExecSuCommand(String strCommandLine)
{
try
{
Process process = Runtime.getRuntime().exec("su");
java.io.DataOutputStream os = new java.io.DataOutputStream(process.getOutputStream());
os.writeBytes(strCommandLine + "\nexit\n");
os.flush();
process.waitFor();
return true;
}
catch(java.io.IOException e)
{
}
catch (InterruptedException e)
{
}
return false;
}
int _nCurrentMode = MSM_CAMERA_LED_OFF;
final static int MSM_CAMERA_LED_OFF = 0;
final static int MSM_CAMERA_LED_LOW = 1;
final static int MSM_CAMERA_LED_HIGH = 2;
final static int MSM_CAMERA_LED_LOW_FOR_SNAPSHOT = 3;
@Override
public boolean onTouchEvent(MotionEvent event)
{
switch(event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
switch(_nCurrentMode)
{
case MSM_CAMERA_LED_OFF:
_nCurrentMode = MSM_CAMERA_LED_LOW;
break;
case MSM_CAMERA_LED_LOW:
_nCurrentMode = MSM_CAMERA_LED_HIGH;
break;
case MSM_CAMERA_LED_HIGH:
_nCurrentMode = MSM_CAMERA_LED_LOW_FOR_SNAPSHOT;
break;
case MSM_CAMERA_LED_LOW_FOR_SNAPSHOT:
_nCurrentMode = MSM_CAMERA_LED_OFF;
break;
}
NativeCtrlCameraLED(_nCurrentMode);
break;
}
return true;
}
public native boolean NativeIsSupportCameraLED();
public native boolean NativeCtrlCameraLED(int nMode);
public native String NativeGetSensorName();
static
{
System.loadLibrary("Test132");
}
}
![]()
すると画面にカメラセンサー名の「s5k3e2fx」という文字が表示されて、画面をタッチすると、、、
成功のように思えるのですが、何度タッチしても光量が変わりません。本当なら3段階&OFFの4パターンが順々に変化するはずなのですが、、
プロジェクトファイルをダウンロード
