編輯:關於Android編程
Android tp的虛擬按鍵處理
現在在越來越多的Android的手機都是虛擬按鍵來操作,但是對於開發者來說可能會關心Android對虛擬按鍵如何處理的。對Linux熟悉的人可能會說,it's easy, 調用input_report_key()。OK,你說的沒有錯誤,但是在android中,google讓你對策略和驅動有了更加深入的了解。
APP------->
Framework------->
Kernel------->
Hardware
上面就是整個Android的Virtual key的整個的框圖。
由於是搞驅動的,所以這裡先從驅動開始說起。
其實說起對virtual key的處理對於驅動來說沒有任何的難處,實現了Touch panel驅動,你也就將virtual key的底層驅動實現了。這裡你試驗了嗎?你可能會說,“不行,這裡實現不了”。是的,這個時候還不行,還有關鍵的步驟得操作。
在這裡,你需要如下代碼加入才可以。
static unsigned int tpd_keycnt = 0;
static int tpd_keys[TPD_VIRTUAL_KEY_MAX]={0};
static int tpd_keys_dim[TPD_VIRTUAL_KEY_MAX][4];// = {0};
static ssize_t cust_virtual_keys_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf) {
int i, j;
for(i=0, j=0;i<tpd_keycnt;i++)
j+=sprintf(buf, "%s%s:%d:%d:%d:%d:%d%s",buf,
__stringify(EV_KEY),tpd_keys[i],
tpd_keys_dim[i][0],tpd_keys_dim[i][1],
tpd_keys_dim[i][2],tpd_keys_dim[i][3],
(i==tpd_keycnt-1?"\n":":"));
return j;
}
static struct kobj_attribute cust_virtual_keys_attr = {
.attr = {
.name = "virtualkeys.cust-tpd",
.mode = S_IRUGO,
},
.show = &cust_virtual_keys_show,
};
static struct attribute *cust_properties_attrs[] = {
&cust_virtual_keys_attr.attr,
NULL
};
static struct attribute_group cust_properties_attr_group = {
.attrs = cust_properties_attrs,
};
struct kobject *properties_kobj;
void tpd_button_init(void) {
int ret = 0, i = 0, j=0;
tpd->kpd=input_allocate_device();
/* struct input_dev kpd initialization and registration */
tpd->kpd->name = TPD_DEVICE "-kpd";
set_bit(EV_KEY, tpd->kpd->evbit);
for(i=0;i<tpd_keycnt;i++)
__set_bit(tpd_keys[i], tpd->kpd->keybit);
tpd->kpd->id.bustype = BUS_HOST;
tpd->kpd->id.vendor = 0x0001;
tpd->kpd->id.product = 0x0001;
tpd->kpd->id.version = 0x0100;
if(input_register_device(tpd->kpd))
TPD_DMESG("input_register_device failed.(kpd)\n");
set_bit(EV_KEY, tpd->dev->evbit);
for(i=0;i<tpd_keycnt;i++)
__set_bit(tpd_keys[i], tpd->dev->keybit);
properties_kobj = kobject_create_and_add("board_properties", NULL);
if(properties_kobj)
ret = sysfs_create_group(properties_kobj,&cust_properties_attr_group);
if(!properties_kobj || ret)
printk("failed to create board_properties\n");
}
void tpd_button_setting(int keycnt, void *keys, void *keys_dim)
{
tpd_keycnt = keycnt;
memcpy(tpd_keys, keys, keycnt*4);
memcpy(tpd_keys_dim, keys_dim, keycnt*4*4);
}
有了上面的代碼,我們的virtual key才可以使用,這裡主要是需要注冊/sys/board_properties/virtualkeys.cust-tpd。這個是framework需要的文件節點。他的出現可以使我們的虛擬按鍵暢通無阻了。
當然,在這裡tpd_keys這個定義key的數組和定義區域的tpd_keys_dim要准確的填充才可以的。具體的填充的規則如下:
0x01: A version code. Must always be 0x01.
<Linux key code>: The Linux key code of the virtual key.
<centerX>: The X pixel coordinate of the center of the virtual key.
<centerY>: The Y pixel coordinate of the center of the virtual key.
<width>: The width of the virtual key in pixels.
<height>: The height of the virtual key in pixels.
對比我的milestone來看看:
0x01:158:32:906:63:57:
0x01:139:162:906:89:57:
0x01:102:292:906:89:57:
0x01:217:439:906:63:57
則可以看出定義了有back,menu,home,search,具體的區域也一清二楚了。
下面就是framework中的處理了,文件在framework/base/services/java/com/android/server/InputManager.java。
在其中通過調用getVirtualKeyDefinitions來獲得定義的虛擬按鍵。
public VirtualKeyDefinition[] getVirtualKeyDefinitions(String deviceName) {
ArrayList<VirtualKeyDefinition> keys = new ArrayList<VirtualKeyDefinition>();
try {
FileInputStream fis = new FileInputStream(
"/sys/board_properties/virtualkeys." + deviceName);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr, 2048);
String str = br.readLine();
if (str != null) {
String[] it = str.split(":");
if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "***** VIRTUAL KEYS: " + it);
final int N = it.length-6;
for (int i=0; i<=N; i+=6) {
if (!"0x01".equals(it[i])) {
Slog.w(TAG, "Unknown virtual key type at elem #"
+ i + ": " + it[i] + " for device " + deviceName);
continue;
}
try {
VirtualKeyDefinition key = new VirtualKeyDefinition();
key.scanCode = Integer.parseInt(it[i+1]);
key.centerX = Integer.parseInt(it[i+2]);
key.centerY = Integer.parseInt(it[i+3]);
key.width = Integer.parseInt(it[i+4]);
key.height = Integer.parseInt(it[i+5]);
if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "Virtual key "
+ key.scanCode + ": center=" + key.centerX + ","
+ key.centerY + " size=" + key.width + "x"
+ key.height);
keys.add(key);
} catch (NumberFormatException e) {
Slog.w(TAG, "Bad number in virtual key definition at region "
+ i + " in: " + str + " for device " + deviceName, e);
}
}
}
br.close();
} catch (FileNotFoundException e) {
Slog.i(TAG, "No virtual keys found for device " + deviceName + ".");
} catch (IOException e) {
Slog.w(TAG, "Error reading virtual keys for device " + deviceName + ".", e);
}
return keys.toArray(new VirtualKeyDefinition[keys.size()]);
}
其實找這個函數的調用的話,其實是發現通過JNI com_android_server_InputManager.cpp,InputReader.cpp來調用的。
最終通過notifyKey()來將key事件上報給app來處理。
在這其中還需要配置:
Key layout file: /system/usr/keylayout/touchyfeely.kl.
key 158 BACK
key 139 MENU
key 102 HOME
key 217 SEARCH
Key character map file: /system/usr/keychars/touchyfeely.kcm.
type SPECIAL_FUNCTION
其實這個例子給我的最大的感受是讓我更加的了解了什麼是策略,什麼是機制,一定要區分清楚。讀源碼可以讓自己的想法也會有些轉變的。
Have Fun!
Volley,小並發網絡請求的好幫手
不得不說,當不了解一件事情的時候,就會像當然的認為,其很神秘。但是當真正的接觸到了這些神秘的item,就不會有這種感覺了。作為一個android開發新手的我,剛接觸到了V
android 二級聯動列表,仿eleme點餐頁面
寫在前面最近手感不錯,老想寫點輪子。正好周末外賣點得多,就仿一仿“餓了麼”好了。先上圖吧,這樣的訂單頁面是不是很眼熟:右邊的listview分好組
[Android] 通過GridView仿微信動態添加本地圖片示例代碼
前面文章講述的都是隨手拍中圖像處理的操作,此篇文章主要講述GridView控件實現添加本地圖片並顯示.主要是關於GridView控件的基本操作,通常可以通過自定義繼承Ba
Android 基礎shape
介紹 簡單來說,shape就是用來在xml文件中定義形狀,代碼解析之後就可以當做Drawable一樣使用官方說明關於shape定義的drawable文件位置:res/dr