8/30/2011

Setup Android build environment


因為自己很常把環境搞爛..要不然就是要幫別人重灌Linux

所以每次都要重新去install一堆有的沒的...

最主要是Android環境最不好弄,因為有些lib tool一定要裝..

其實這些在Google都有教學文件...

但常常因為要重建環境又再去看一次文件,實在很浪費時間..

所以自己就做了一隻script,讓它一次安裝到定位 (除了SDK)

=============

#!/bin/sh

#install jdk 6
sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
sudo add-apt-repository "deb-src http://archive.canonical.com/ubuntu lucid partner"
sudo apt-get update
sudo apt-get install sun-java6-jdk

#install jdk 5
sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu dapper main multiverse"
sudo add-apt-repository "deb http://archive.ubuntu.com/ubuntu dapper-updates main multiverse"
sudo apt-get update
sudo apt-get install sun-java5-jdk

#install required packages with x86
sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev libc6-dev x11proto-core-dev libx11- dev libgl1-mesa-dev g++-multilib tofrodos libncurses5-dev mingw32 libesd0-dev libwxgtk2.6-dev x-dev libstdc++6

# If x64 system, need these lib tool
#sudo apt-get install lib32readline5-dev libstdc++6 lib32z1 lib32z1-dev ia32-lib

Android 2.3 Gingerbread with x86


因為Android 2.3 Gingerbard original code是預設在x64上compile

所以如果你的Linux不是x64的話,是不會讓你compile的。

其實只要改幾個.mk而己 :

project build/
diff --git a/core/main.mk b/core/main.mk
index f761ba5..4ee4bf9 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -68,7 +68,7 @@ $(info Checking build tools versions...)

ifeq ($(BUILD_OS),linux)
build_arch := $(shell uname -m)
-ifneq (64,$(findstring 64,$(build_arch)))
+ifneq (i686,$(findstring i686,$(build_arch)))
$(warning ************************************************************)
$(warning You are attempting to build on a 32-bit system.)
$(warning Only 64-bit build environments are supported beyond froyo/2.2.)

project external/clearsilver/
diff --git a/cgi/Android.mk b/cgi/Android.mk
index 21c534b..37b8246 100644
--- a/cgi/Android.mk
+++ b/cgi/Android.mk
@@ -13,8 +13,8 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
LOCAL_CFLAGS := -fPIC

# This forces a 64-bit build for Java6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64

+LOCAL_CFLAGS += -m32
+LOCAL_LDFLAGS += -m32


LOCAL_NO_DEFAULT_COMPILER_FLAGS := true

diff --git a/cs/Android.mk b/cs/Android.mk
index 9f0e30a..275845d 100644
--- a/cs/Android.mk
+++ b/cs/Android.mk
@@ -9,8 +9,8 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
LOCAL_CFLAGS := -fPIC

# This forces a 64-bit build for Java6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64

+LOCAL_CFLAGS += -m32
+LOCAL_LDFLAGS += -m32

LOCAL_NO_DEFAULT_COMPILER_FLAGS := true

diff --git a/java-jni/Android.mk b/java-jni/Android.mk
index 21b4fd1..c1d38d2 100644
--- a/java-jni/Android.mk
+++ b/java-jni/Android.mk
@@ -34,8 +34,8 @@ LOCAL_C_INCLUDES := \
LOCAL_CFLAGS += -fPIC

# This forces a 64-bit build for Java6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64

+LOCAL_CFLAGS += -m32
+LOCAL_LDFLAGS += -m32

LOCAL_NO_DEFAULT_COMPILER_FLAGS := true

diff --git a/util/Android.mk b/util/Android.mk
index 386f379..b694ef4 100644
--- a/util/Android.mk
+++ b/util/Android.mk
@@ -18,8 +18,8 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/..
LOCAL_CFLAGS := -fPIC

# This forces a 64-bit build for Java6
-LOCAL_CFLAGS += -m64
-LOCAL_LDFLAGS += -m64

+LOCAL_CFLAGS += -m32
+LOCAL_LDFLAGS += -m32


LOCAL_NO_DEFAULT_COMPILER_FLAGS := true

7/12/2011

Covert string to char

這幾個禮拜 , 為了要在Android 2.3上implement HID profile 真的快把我給搞死...

不過還好 , 總算把bluetooth keyboard & mouse給弄出來了 !

過幾天再把一些心得和方法分享給在上面.

因為要自己寫JNI , 遇到上層的JAVA要傳一個字串下來 , 想當然爾JNI一定會宣告Jstring來接JAVA的字串.

但可不能直接把這個字串丟到C/C++的function , 一丟Android就直接process died....

這需要做一些轉換.

但說實在的 , JAVA 非常的不熟...所以直接從bluetooth的JNI抓出來看再改一改放到我的code裡面...

還滿簡單的.


/* Transfer jstring to C for */
const char *c_mac = env->GetStringUTFChars(address, 0);

size_t mac_sz = env->GetStringUTFLength(address) + 1;

char *c_mac_copy = (char *)malloc(mac_sz);

strncpy(c_mac_copy, c_mac, mac_sz);

hidd_command(c_mac_copy,mode);

env->ReleaseStringUTFChars(address, c_mac);



說穿了就是用GetSrtingUTFChars來轉 , 再用GetStringUTFLength來算長度 , 最後再用strncpy來把字串copy過去而己



但要注意的是,上面相對來說是指C++的JNI,如果是C的JNI,就要改成這樣了 :

const char *c_mac = (*env)->GetStringUTFChars(env,address, 0);

size_t mac_sz = (*env)->GetStringUTFLength(env,address) + 1;

char *c_mac_copy = (char *)malloc(mac_sz); // callback data

strncpy(c_mac_copy, c_mac, mac_sz);

hidd_command(c_mac_copy,mode);

(*env)->ReleaseStringUTFChars(env,address, c_mac);



原因在於jni.h的定義,路徑在 dalvik/libnativehelper/include/nativehelper/jni.h :

struct _JNIEnv;
struct _JavaVM;
typedef const struct JNINativeInterface* C_JNIEnv;

#if defined(__cplusplus)
typedef _JNIEnv JNIEnv;
typedef _JavaVM JavaVM;
#else
typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNIInvokeInterface* JavaVM;
#endif


要特別注意了.....這個差點搞死我了= =

6/13/2011

How to capture home key event

在Android 2.3 , 想要取得home key event來做特殊事件 , 應用層是收不到該事件的.

因為Android在framwork layer做掉 , 所以並沒往APP layer上送.

frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java


// First we always handle the home key here, so applications
// can never break it, although if keyguard is on, we do let
// it handle it, because that gives us the correct 5 second
// timeout.
if (keyCode == KeyEvent.KEYCODE_HOME) {
Log.i(TAG,"----2keyCode == KeyEvent.KEYCODE_HOME");
// If a system window has focus, then it doesn't make sense
// right now to interact with applications.
WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
if (attrs != null) {
final int type = attrs.type;
if (type == WindowManager.LayoutParams.TYPE_KEYGUARD
|| type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
// the "app" is keyguard, so give it the key
return false;
}
.............
.............
}


註釋寫的很清楚 , 而其中的重點在於type , 可以看出它有兩個type來判斷對該事件的處理 :

WindowManager.LayoutParams.TYPE_KEYGUARD
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG

所以在APP層 , 想要接收home key event的話 , 改變activity的類型即可 :


/* capture home key event*/
@Override
public void onAttachedToWindow()
{
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
super.onAttachedToWindow();
}


其中的WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG可以改成WindowManager.LayoutParams.TYPE_KEYGUARD

但我測試過 , 用TYPE_KEYGUARD似乎會影響一些View的處理....

==========================

我發現..TYPE_KEYGUARD會使view變成懸浮視窗= =

非常怪異 !! 但實在想不出原因...最後只好自己硬幹 , 如果有人試出問題..別罵我QQ

上面提到定義了這些Typ......所以呢,我就自己定義一組Type !!

首先呢,可以在PhoneWindowManager.Java新增自己的Type :


if(type == WindowManager.LayoutParams.TYPE_DASHBOARD) {
Log.d("DASHBOARD","**** Send the home key event to app ****");
return false;
}


我自己定義了一個叫"TYPE_DASHBOARD"的東東,之後再到framwork/base/core/java/android/view/WindowManager.java去新增 :


@ViewDebug.ExportedProperty(mapping = {
.....
.....
@ViewDebug.IntToString(from = TYPE_DASHBOARD, to = "TYPE_DASHBOARD")
})

---------

public static final int TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15;

/* Send Home key event to app layer */
public static final int TYPE_DASHBOARD = FIRST_SYSTEM_WINDOW+50;


當然了..那個後面數字隨便..50只是我的辛運數字 !!

改其它數字會不會出事就聽天命了...

還沒完 !! 再來到framwork/base/include/ui/InputDispatcher.h新增 :

// Window types from WindowManager.LayoutParams
enum {
.....
.....
TYPE_DASHBOARD = FIRST_SYSTEM_WINDOW+50,
}


到這裡,framwork的地方就改完了,接著只要在自己的APK加上這段 :

/* capture home key event*/
public static final int TYPE_DASHBOARD=2050;
@Override
public void onAttachedToWindow()
{
this.getWindow().setType(TYPE_DASHBOARD);
super.onAttachedToWindow();
}


嘿嘿,這樣接下來只要呼叫dispatchKeyEvent就可以收到Home key事件了 !! 而且不會有任何後遺症了喔 !!

5/05/2011

Install Java 5 on Ubuntu 10.4

某種因素,目前Ubunt 10.4的repository己經把Java 5移除

如果要想安裝Java 5的話,就必須手動加入source,如下操作 :

1.編輯apt-get

sudo vim /etc/apt/sources.list


2.加入source

## For sun-java5-jdk
deb http://ir.archive.ubuntu.com/ubuntu jaunty-updates main multiverse


3.更新repository & 安裝Java 5

sudo apt-get update
sudo apt-get install sun-java5-jdk


結束 !! :)