2011년 11월 10일 목요일

touch screen이 없는 android에서 app이 죽는 상황

touch screen이 없는 android에서는 Music, Contacts, Phone app이 동작하지 않습니다.

이전 froyo에서는 android 자체가 켜지지 않았지만 gingerbread 부터는 android는 정상 부팅하도록 변경되었습니다.

아래의 메세지와 같이 resource index가 맞지 않아서 죽습니다.

android.content.res.Resources$NotFoundException: Resource contacts

googling 하다가 아래 페이지를 찾았고

https://bugs.launchpad.net/linaro-android/+bug/772528

git log를 보면 fake-ts에 관한 내용이 있습니다.

http://git.linaro.org/gitweb?p=android/device/linaro/common.git;a=commit;h=89a3940ca2ad04a54e4a8aa315f0089ce4621d17

[LINARO] Add fake touchscreen 'driver' to avoid Android activity crash

Some Android activities like 'Music' expect the presence of touchscreen
device, otherwise they would crash due to lacking of corresponding
system resources.

To fix the crash, a fake touchscreen 'driver' is added, which utilizes
uinput to register a touchscreen device in kernel.


touch screen이 없더라도 kernel 드라이버에 fake또는 dummy touch screen driver가 반드시 있어야 합니다.

정확하게는 상황이 이해가 가지 않지만 Music app에서 touch screen을 resource로 관리하고 ts가 없기 때문에 resource index가 문제가 되는 것 처럼 보입니다.

2011년 11월 1일 화요일

android open GL ES 2.0 sample

단말기에서 Open GL ES 2.0이 동작하는 확인 할 수 있는 app

http://code.google.com/p/gdc2011-android-opengl/


svn checkout http://gdc2011-android-opengl.googlecode.com/svn/trunk/ gdc2011-android-opengl-read-only


동작하면 open GL ES 2.0 compatibility 하다고 할 수 있겠죠.


ODROID-A에서 동작하는 모습



2011년 10월 29일 토요일

android-2.3.6_r1(GRK39F) android-2.3.7_r1(GWK74)

android git가 부할해서 간만에 받아 odroid7(s5pc110), odroid-a(s5pc210)와 merge 하였습니다.

android-2.3.6_r1(GRK39F)은 통화에 bluetooth 기능이 추가 된것 같습니다. framework에 bluetooth 관련이 수정 되었고 settings에도 수정 되었더군요.

android-2.3.6_r1(GWK74)는 NFC(nxp)에 firmware upgrade 기능이 추가되었습니다.
저희가 따로 NFC를 개발하는게 있는 관계로 merge를 할 수가 없더군요. chip vendor에서 2.3.7을 release 해주면 그 때 고려 해 봐야 겠습니다.

각 버전은 일단 repo sync로 master를 받으시고 framework/base 폴더에서 git tag를 하시면 현재 어떤 tag가 있는지 확인이 가능합니다.


[~/projects/android-master/frameworks/base]$ git tag
android-1.6_r1
android-1.6_r1.1
android-1.6_r1.2
android-1.6_r1.3
android-1.6_r1.4
android-1.6_r1.5
android-1.6_r2
android-2.0.1_r1
android-2.0_r1
android-2.1_r1
android-2.1_r2
android-2.1_r2.1p
android-2.1_r2.1p2
android-2.1_r2.1s
android-2.2.1_r1
android-2.2.1_r2
android-2.2.2_r1
android-2.2_r1
android-2.2_r1.1
android-2.2_r1.2
android-2.2_r1.3
android-2.3.1_r1
android-2.3.2_r1
android-2.3.3_r1
android-2.3.3_r1.1
android-2.3.4_r0.9
android-2.3.4_r1
android-2.3.5_r1
android-2.3.6_r0.9
android-2.3.6_r1
android-2.3.7_r1
android-2.3_r1


 그리고 repo forall -c git checkout tag명 이렇게 하시면 특정 버전으로 source를 받으실 수 있습니다.

android-4.0.1 버전 emulate도 돌려봤는데 항상 느끼는 거지만 emulate가 너무 느려서...

곧 ICS가 공개 되겠죠... 기대 됩니다.

ODROID-7에 android-2.3.6...


android(Gingerbread)에서 USB 3G Modem 사용하기

android 2.2(froyo)에 HSDPA 3G Modem을 붙여 본 적있습니다.
제 blog에 post한 적이 있습니다.

이번에 gingerbrea(2.3)에 올리는데 성공은 했는데 삽질을 많이 했습니다.
아직 해결 못한 문제도 있고...

ril-daemon이 pppd가 동작하기 전에 특정 동작을 하면 SKTelecom이나 안테나 상태 등을 업데이트 할 수 있습니다. 그런데 이 상태가 되면 pppd로 연결이 실패가 됩니다.

그래서 부팅하고 usb modem이 ril-daemon의 어느 시점 보다 pppd로 접속을 먼저해야 하더라구요.

아래는 참고한 사이트...

그리고 성공 인증샷...

2011년 10월 1일 토요일

android에서 app을 SD에 설치하기 위해 kernel features.


android 2.2 froyo 버전 부터 app을 SD Card에 설치 할 수 있습니다.

2.6.35 kernel 이상부터 아래 feature를 켜 주면 SD Card로 옮기기가 가능합니다.

CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y

CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_TWOFISH_COMMON=y

2010년 10월 5일 화요일

android JNI을 이용하여 serial 읽어 오기

http://developer.android.com/sdk/ndk/index.html

위에 홈페이지에서 ndk를 다운 받고 적당한 디렉토리에 압축을 푼다.

eclipse에서 프로젝트를 하나 생성한다.

프로젝트 생성시 반드시 minSdkVersion="3"을 추가 해야 한다.

AndroidManifest.xml에 추가한다.

project 폴더에 jni 폴더를 만들다.

ndk/sample/ 폴더에 예제를 참조 하여 Android.mk를 생성한다.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := gps_serial
LOCAL_SRC_FILES := gps_serial.c \
jni_serial.c

LOCAL_LDLIBS := -ldl -llog

include $(BUILD_SHARED_LIBRARY)



jni 폴더에 소스를 생성한다.

gps serial를 읽어 오는 gps_serial.h/c를 생성한다.

//---------------gps_serial.h-----------------------//
#ifndef GPS_SERIAL_H
#define GPS_SERIAL_H

char* read_serial();

#endif //GPS_SERIAL_H



//---------------gps_serial.c-----------------------//
#include
#include
#include
#include
#include
#include

#define GPS_SERIAL_NODE "/dev/ttyACM0"
#define READ_COUNT 256
#define LOG_TAG "GPS Serial"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

int fd = -1;
char buf[READ_COUNT];

int openGPS()
{
LOGI("oepnGPS()");

if (fd = open(GPS_SERIAL_NODE, O_RDONLY) >= 0) {
return fd;
} else {
LOGI("failed to oepn!");
return fd;
}
}

void closeGPS()
{
LOGI("closeGPS()");

if (fd)
close(fd);

fd = -1;
}

char* read_serial()
{
int read_count = 0;
int idx = 0;

memset(buf, 0x00, READ_COUNT);

if (fd == -1)
goto out;

read_count = read(fd, buf, READ_COUNT);
LOGI("count %d", read_count);
LOGI("%s", buf);

LOGI("read success!!");

out:
return buf;
}

여기까지는 일반적인 linux 프로그램이다. 단 printf로 메세지를 확인 할 수 없기 때문에 __android_log_print()를 이용하여 log를 확인 해야 한다.

그리고 java와 c library를 연결 할 jni 함수를 만든다.

//---------------jni_serial.c-----------------------/

#include
#include

#include

void Java_com_hardkernel_gpsserial_GPSSerialActivity_openGPS(JNIEnv* env, jobject obj)
{
openGPS();
}

jstring Java_com_hardkernel_gpsserial_GPSSerialActivity_readGPS(JNIEnv* env, jobject obj)
{
return (*env)->NewStringUTF(env, read_serial());
}

void Java_com_hardkernel_gpsserial_GPSSerialActivity_closeGPS(JNIEnv* env, jobject obj)
{
closeGPS();
}

JNI 함수의 이름 규칙은 Java_ 이후에 package name 그리고 jni를 호출 할 class 이름 그리고 함수 이름을 붙여 주면 됩니다.

Java_com_hardkernel_gpsserial_GPSSerialActivity_openGPS
_____패키지이름_______________class 이름_______함수 이름

이제 ndk를 이용하여 build를 해 보자.

jni 폴더에서 [android-ndk가 설치된 폴더]/ndk-build 명령으로 build를 한다.
하고 나면 아래의 그림과 같이 libs 폴더가 생성된다.


//---------------GPSSerialActivity.java-----------------------/
package com.hardkernel.gpsserial;

import com.hardkernel.gpsserial.R;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.TextView;

public class GPSSerialActivity extends Activity {
private TextView mTv;
private Thread mReadThread = null;
private String mString;
boolean mRunning = false;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTv = (TextView)findViewById(R.id.gps_textview);
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if (mReadThread != null && mReadThread.isAlive()) {
Log.w("codewalker", "onPause()");
mRunning = false;
mReadThread = null;
}
closeGPS();
}

@Override
protected void onResume() {
// TODO Auto-generated method stub
Log.w("codewalker", "onResume()");
super.onResume();
openGPS();
if (mReadThread == null) {
mRunning = true;
mReadThread = new Thread(new Runnable() {
public void run() {
while (mRunning) {
try {
Thread.sleep(500);
} catch (InterruptedException ignore) {
}
mString = readGPS();
mHandler.sendMessage(mHandler.obtainMessage());
}
}
});
mReadThread.start();
}
}

@Override
protected void onDestroy() {
if (mReadThread != null && mReadThread.isAlive())
mReadThread.destroy();
// TODO Auto-generated method stub
super.onDestroy();
}
Handler mHandler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
mTv.setText(mString);
};
};

public native String readGPS();
public native void openGPS();
public native void closeGPS();

static {
System.loadLibrary("gps_serial");
}
}

jni 함수를 위와 같이 등록해 주고 load해 주는 코드를 추가 한다.

2010년 8월 18일 수요일

odroid에 T-Login(LM-629HUL) 사용하기

이전에 HSDPA USB Modem(LM-629HUL )을 linux에서 사용하기 위한 내용을 posting 하였습니다.
linux에 먼저 작업한 이유는 odroid-t에 t-login을 사용하기 위해서 입니다.

그래서 이번 내용은 이전에 올렸던 linux 작업했던 내용을 이어서 android에 HSDPA USB Modem porting 방법을 posting합니다.

x86 usb-modeswitch는 libusb-0.1 버전을 사용하였습니다.
하지만 libusb android를 검색하면 libusb-1.0 버전이 있습니다.
그리고 libusb-1.0에 libusb-0.1버전을 사용할 수 있는 libusb-compat가 있습니다.
둘다 android용으로 library가 존재 합니다.
하지만 external에 넣고 빌드 하여 libusb.so와 libusb-compat.so를 만들어지만 dynamic link가 되지 않아서 configure에 --enable-static을 둘다 주고 usb_modeswitch도 static으로 만듭니다.
usbutils 역시 동일하게 static으로 만들면 lsusb를 통하여 usb mode switch가 되었는지 확인이 가능합니다.

여기서부터 추가
external 밑에 아래 세 폴더를 복사 합니다.
monaka-libusb-android-b35de21
monaka-libusb-compat-android-85dc44d
usb-modeswitch-1.1.3

monaka는 Android.mk가 있습니다.

usb-modeswitch-1.1.3에 Android.mk는 아래와 같습니다.

1 ifeq ($(TARGET_ARCH),arm)
2
3 LOCAL_PATH:= $(call my-dir)
4 include $(CLEAR_VARS)
5
6 LOCAL_SRC_FILES:= \
7 usb_modeswitch.c
8
9 LOCAL_SHARED_LIBRARIES := \
10 libusb-compat libusb
11
12 LOCAL_C_INCLUDES := \
13 $(LOCAL_PATH)/include
14
15 LOCAL_CFLAGS := \
16 -Iexternal/monaka-libusb-compat-android-85dc44d/libusb -pthread -rt
17
18 LOCAL_MODULE:= usb_modeswitch
19
20 include $(BUILD_EXECUTABLE)
21
22 endif

이렇게 추가하면 odroidt-img/system/bin/usb_modeswitch와 odroidt-img/system/lib/libusb.so, libusb-compat.so가 생깁니다.

그리고 추가로 external/monaka-libusb-android-b35de21/examples을 컴파일 하면 lsusb가 생깁니다.
Android.mk는 아래와 같습니다.

1 ifeq ($(TARGET_ARCH),arm)
2
3 LOCAL_PATH:= $(call my-dir)
4
5 include $(CLEAR_VARS)
6
7 LOCAL_SRC_FILES:= \
8 lsusb.c
9
10 LOCAL_C_INCLUDES += $(LOCAL_PATH)/android \
11 external/monaka-libusb-android-b35de21
12
13 LOCAL_SHARED_LIBRARIES := \
14 libusb
15
16 LOCAL_CFLAGS := \
17 -pthread -rt
18
19 LOCAL_MODULE:= lsusb
20
21 include $(BUILD_EXECUTABLE)
22
23 endif

이렇게 위에서 언급한 static문제는 해결 되었습니다.
추가 끝

다음 단계로 커널에 usb file system이 올라 가야 합니다. kernel에 usb file system을 추가 하시고
odroid-t는 ramdisk를 사용함으로 vendor/sec/android/conf/init_ramdisk.rc 파일에 usbfs를 mount하도록 추가 합니다.

mount usbfs none /proc/bus/usb

다음 부터는 아래 주소에 있는 x86 emulator에서 HSDPA를 연결한 내용을 참고하였습니다.

내용을 간략하게 설명하면 host linux에 modem을 연결하면 ttyUSB가 생성되고 여기서 command port인 ttyUSB3을 android의 ttyS1으로 연결한다는 내용입니다.

vendor/sec/odroidt/system.prop 파일을 아래와 같이 수정 합니다.

1 #
2 # system.prop for odroidt
3 #
4
5 rild.libpath=/system/lib/libreference-ril.so
6 #codewalker
7 #rild.libargs=-d /dev/ttyS0
8 rild.libargs=-d /dev/ttyUSB3
9 ro.sf.lcd_density=240

다음에 linux atdt sk라고 검색하면 HSDPA를 PPP에서 동작 하도록 하는 내용이 있습니다.
이 부분은 x86에서 가져온 chat이 있다면 desktop과 동일하게 처리 되는 부분입니다.

아래 사이트에 가면 ppp에 관한 내용이 있고 HSDAP USB modem에 AT command로 connection하는 내용이 있습니다.


usb_modeswitch를 통해 usb modem을 storage card에서 modem으로 변경 해줍니다.
insmod /modules/usbserial.ko 'vendor=0x1d74 product=0x00c9'으로 ttyUSB 노드를 생성해 줍니다.
여기서 따옴표를 주지 않으면 두번째 parameter product인자가 제대로 넘어가지 않습니다.
ppp call gprs를 호출 하면 t-login 모뎀이 녹색으로 바뀌면서 동작합니다.

지금은 간략하게 작성하였고 차후에 추가 보강하겠습니다.