2011年5月31日 星期二

我的白板......這大概只有我看的懂 XD


Taken at HTC Research Center (Sindian Branch)

2011年5月26日 星期四

中餐


Taken at HTC Research Center (Sindian Branch)

2011年5月23日 星期一

啦啦啦啦~~iPad2開箱

首先要感謝Ming....從遙遠的韓國幫我找到這台白色64G的iPad2....讓我終於拿到期待以久的iPad2了...還有強尼大人餽贈的紅色Smart cover一只....

回到家就看到這包寫了韓文的包裹

P1050001

驗明正身...是64G的!!

P1050005

開箱了~~~有點金光閃閃~~

P1050007

配件雖然沒啥好看的, 還是來一張

P1050008

在韓國買的缺點就是, 插座不是台灣的規格, 不過沒差啦....還是可以USB充電, 也有舊插頭用

P1050011

呃...實在很不好意思...我生日...還有半年耶, 強尼大人人真好

P1050012

來吧...Smart cover:

P1050013P1050014

最後, 秀一下價格

P1050016

89萬....韓圜.....

 

狀態: 轉移iPad資料中........

2011年5月22日 星期日

Hola! Jack Sparrow

剛去看完, 還是很喜歡Johnny Deep演的Jack Sparrow,不過這次這位Astrid Bergès-Frisbey演的美人魚Syrena也是頗搶眼的呀!這位演員有點Liv Tylor的味道

總覺這劇情還是演不爛, 還是會期待有續集, Jack最後也拿回Black Pearl了, 應該還是會有續集吧.....

下雨了

P162

2011年5月21日 星期六

Ozaki電容觸控筆開箱

本來跑去蘋果店是想為新買的iPad2買個背蓋, 結果背蓋沒買成, 卻順手買了這隻筆: Ozaki iStoke

Photo_5_21_6_13_39_

外盒包裝蠻Apple style的

Photo_5_21_6_14_15_
背面還有說明

Photo_5_21_6_15_02_
搭拉...開箱(好弱~~~)

自己照一張:

Photo_5_21_6_17_18_
用Angry birds來試試吧...

Video_5月_21,_6_35_37_下午.mov Watch on Posterous
塗個鴨吧... XD

Video_5月_21,_6_37_16_下午.mov Watch on Posterous
結論: 筆頭蠻柔軟有彈性的, 用起來算蠻順的, 只是感覺有時後點不精準, 可能手指用習慣了, 另一端筆蓋拔起來有原子筆, 還不錯, 會選上這隻的原因是因為筆蓋上那個夾扣, 還蠻方便的....

2011年5月14日 星期六

生氣鳥戰記 -- 小黃上哪兒去了?


Taken at HTC Research Center (Sindian Branch)

[Android][Tip] How Twitter for Android implements auto completion in post screen?

Twitter for Android popup a user list when you enter "@" in post screen. Like this:

T1

How it implement such feature? The solution can't be simpler - You could use MultiAutoCompeleteTextView to do this.

Here is the sample codes:

And the result:

T2

To use this widget, you need to implement a Tokenizer to tell it where the sub text is. In this case, just find the string between '@' and space.

2011年5月11日 星期三

Google I/O day 2 Chrome keynote感想

進入到Day 2了, 今年跟去年不一樣的地方好像只有把兩天keynote對調而已, 相較之下, 今年的Android強悍太多, 比起來, 還是可以叫Android IO啦...

去年HTML5部分找了一大堆廠商來站台, 比起來今年就遜色許多, in app purchase這功能找來了Mighty Eagle用Angry birds來站台, 讓本來快睡著的我突然醒來了, in app purchase 在Android, iOS已經有了, 並不是太特別, 倒是WebGL寫的Angry birds 讓我眼睛一亮, 只是事後去下載來玩的感覺是, performance沒他宣稱的好, 動畫路徑顯然被簡化過, 表現還不及iOS和Android版本

Chrome OS, 感覺好像沒啥比較亮的進步, 唯一比較亮的是Chromebook的價格, 有點太貴, 以目前Android tablet越來越強悍來看, 這樣的小筆電很容易被Android tablet給邊緣化吧, 畢竟Cloud已經快要不是只有Chrome OS能強調的特色了, 很多東西Android已經具備, 甚至未來也有可能會具備呀

今年送的贈品又有tablet又有筆電, 有去的人還真幸福, 可以好好比較一番, 真恨自己沒搶到票... (還是該恨Google讓我在半夜狂按一小時還搶不到票)....嗚~~~

2011年5月10日 星期二

Google I/O day 1 keynote感想

昨晚熬夜看了Google I/O的live(那是一定要的啦!), 雖然沒睡多少, 到現在依然興奮!

今年Day 1的Keynote搞到真的像是Android I/O一樣, Android儼然是今年必然主角一樣, 不過與我之前想像的不太一樣, 今年沒特別著重在平板, 也沒特別著重在TV和其他裝置, 而是Android本身, Android本身已經適用到手機, 平板, TV這是自然不在話下, ADK, Android@Home的加入, 等於把它延伸到更大的範圍, Movie rental, Google Music更揭示了, Google後面那朵雲可以做Android多大的後盾, 今年的主角不是Android平板呀~~~而是Android everywhere~~~

這些東西朝我理想中的移動裝置越來越接近了, 之前一個想法就是, 一個好的移動裝置, 要有的三個特色, "everywhere", "get connected", 以及"seamless", 要能夠隨處取用(everywhere), 隨處取用並不只是單單針對一個裝置來說而已, 在不同場合可以取用不同適合的裝置, 如手機, 平板, 電視, 甚至智慧型3C家電, 而且這些東西不只要能夠有對外界溝通的管道, 甚至彼此可以互相溝通(Get connected), 這一點似乎Android@Home已經是某種程度上的實現了, 最後是"seamless", 不同的移動裝置除了可以互相溝通外, 甚至在使用轉換上可以"無感", 舉個簡單的例子來說, 當你在看一部電影時, 在等公車時, 可能因為有位子坐著, 所以拿出平板來看比較舒服, 等上了公車後, 人潮擁擠, 你會拿出手機接續著看, 等到了家, 電影還沒看完, 繼續轉到電視上看, 如果像這樣的使用體驗在不同的裝置上可以無縫的接續, 那真的會是更大的威力(不知道拿ADK bluetooth有沒辦法實現這樣的東西)

當所有的裝置都連接了, 在配合後端的雲, 那整個會成為一個Skynet或是Borg呢? :D

不過也不是完全沒負面的東西啦, 像是Music和Movie rental那東西, 勢必會變成Carrier一個惡夢, 智慧型手機替他們爭取到了不少使用者, 但是相對的也得付出代價, 越來越多的連網裝置, 如果基礎的infrastructure跟不上, 那勢必會是災難, 也不只Carrier而已, 對於一些網路的服務來說, 連接的媒體就不再只有PC, 數量會越來越多, 需求的架構就要更加紮實了...

家裡第二台空氣清淨機 - Daikin MC75JSC

P425

家中空氣灰塵多,主臥那台Daikin用了四年,覺得不夠,還是多買了台放客廳,不過總覺新款的沒以前有質感

2011年5月9日 星期一

Generating Facebook key hash for Android

According to Facebook mobile development document (Android), you need to generate a key hash for your application in order to apply Facebook SSO(Single Sign on).

Here is the formal way to do this:

keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64

But sometimes you won't have a tradtional key store especially when building with Android open sources. Keys in Android open sources are in pk8 format. In order to generate key hashes with these keys, you need to tranfer them into a pk12 key store.

I created another way to generate keyhash without keytool and openssl. Here is the source codes: FacebookKeyHashGen

This program get package sigature directly from package itself. 

2011年5月8日 星期日

Mos 春菇豆腐雞肉堡


Taken at 新竹高鐵摩斯漢堡

[POC][筆記][Rhino on Android] - 新的onClickListener

上次的作法:

var button1 = findview(R.id('button1'));

button1.setOnClickListener(function(view, methodName)
{
     if (methodName == "onClick") {
         log("MyScript", "clicked");
} });

 

當然不是很滿意, "if(methodName == "onClick")"這樣的寫法太醜了啦!

所以這次的目標是:

button1.onclick = function(view) {

     log("MyScript", "clicked");

     alert('Hi there!');

};

這樣比較像印象中javascript的寫法

為了達到這目的, 必須在View中加入onclick這個property, 但原本View class(Java)並沒這東西, 如何將它包裝出來?

Rhino對於Javascript使用原生的java objects並不是直接使用, 還是有透過一層包裝, 因此這就是要做出這個property的路了, 包裝的點在於WrapFactory, 而原生的Java object會被包裝長NativeJavaObject 

而Rhino允許我們用自己的WrapFactory取代原本的, 像是這樣:

jsContext.setWrapFactory(new AndroidWrapFactory());

因此我們會需要自己實作這一個AndroidWrapFactory, 把原本的View改用不同的包裝, 而非原本的NativeJavaObject, 基本上只需要實作wrapAsJavaObject即可:

 

這邊用了一個新實作的ViewWrapper來取代NativeJavaObject

本來我的打算是繼承自NativeJavaObject, 然後再加入自己的東西, 不過後來發現這樣的作法總會在"put"時出差錯, 原因是NativeJavaObject是沒辦法加入新的member了(其實這說法有點問題, 應該是只要設prototype給它的話還是可以), 加上一些比較實用的function是定義在ScriptableObject的裡面, 因此, 我最後採用ScriptableObject來包裝

但要如何在ScriptableObject裡面實現像NativeJavaObject那樣可以直接叫用原本的Java class裡面的member呢?這部份不用自己實作, 只要把原本的NativeJavaObject當做這新的ViewWrapper的prototype就好了, 所以這邊constructor呼叫的super contructor是:

public ScriptableObject(Scriptable scope, Scriptable prototype)

===> super(scope, new NativeJavaObject(scope, javaObject, staticType));

defineProperty這包裝是從ScritableObject那邊改寫其中一個過來的, 主要是用來讓我們可以把這些"onlick","onlongclick"包裝成property, 在ViewWrapper可以實作getter和setter, 為了避免名稱上的混淆, 所以把getter的prefix定義成"jsget"而setter是"jsset"

在onlick的setter中, 除了將function object存起來外, 還直接對原本包裝的View設一個OnClickListener, 動作則是執行這個Function object

最後, 前面的範例裡面有一個"alert('Hi! there')", 因此為了"alert()"多實作一個Alert.java出來(跟上面的無關啦), 這是source:

 

接下來的目標, 

  • 包裝一個實際真的可以拿來開發的package, release 0.1 alpha
  • 實作XmlHttpRequest
  • Adapter & AdapterView, Service & Provider

2011年5月7日 星期六

Google code jam: Problem B. Magicka

題目

一直在想說為啥我submit的答案有問題想到沒睡好, 剛剛才發現, 我誤會了一個關鍵句:

it is opposed to something in your element list, then your whole element list will be cleared.

結果我誤解成只有被兩個字元夾住的區域才會clear, test set也沒驗出我的問題.... = ="

這題關鍵除了這個外, 還有

If the two elements from a pair appear at the end of the element list, then both elements of the pair will be immediately removed, and they will be replaced by the element they form.

所以, "1 QFT 1 QF 7 FAQFDFQ"的答案會是"[F, D, T]"而不是"[]"

浪費了一題... :(

 

草莓牛奶

2011年5月4日 星期三

[筆記]一些FQLs

本來是放在我EverNotes內的, 貼一些出來好了, 無聊時玩玩的東西, 沒優化過:

  • 共同喜歡的Page : select name from page where page_id in (select page_id from page_fan where uid=friend_uid and page_id in (select page_id from page_fan where uid=me()))
  • 共同朋友: select name from user where uid in (select uid2 from friend where uid1=me()) and uid in (select uid2 from friend where uid1=friend_uid)
  • 同時都出現的照片: select src from photo where pid in (select pid from photo_tag where subject=friend_uid) and pid in (select pid from photo_tag where subject=me())
  • 屬於某Group的照片: select src from photo where pid in (select pid from photo_tag where subject=group_id)
  • 共同參加的活動: select name from event where eid in (select eid from event_member where uid=me() and rsvp_status='attending') and eid in (select eid from event_member where uid=friend_id and rsvp_status='attending')
  • 都去過的地方(僅限於自己checkin不包含被tag): select name from place where page_id in (select page_id from checkin where author_uid=me()) and page_id in (select page_id from checkin where author_uid=friend_uid)
  • 喜歡過的某人的post:  select message from stream where post_id in (select post_id from like where post_id in (SELECT post_id FROM stream WHERE source_id=friend_uid) and user_id=me())
  • Comments on someone's post: select text from comment where post_id in (SELECT post_id FROM stream WHERE source_id=friend_uid) and fromid=me()

其中"me()"是自己, 有些FQL裡的"me()"可以代換成另一個人的uid

早餐-星巴克總匯三明治


Taken at 高鐵星巴克 Starbucks

2011年5月2日 星期一

[POC][筆記][Rhino] Developing Android with JS - onClickListener

上次做的僅止於setText這個簡單的動作, 那像是處理click這類的怎做?

先拿click來做範例, 在Android中, 如果要替一個view加上處理click動作要利用到View.setOnClickListener, 但setOnClickListener的參數是onClickListener, 這是一個java interface, 在Rhino中如何實作一個Java interface?

首先, 不要被Rhino的文件給騙了, 那有問題(還花了我一個晚上看 :( ), Rhino的source codes裡有個example目錄, 裡面有隻SwingApplication.js, 答案就在這邊

因此, onClick就會像是這樣:

var button1 = findview(R.id('button1'));

button1.setOnClickListener(function(view, methodName)
{
     if (methodName == "onClick") {
         log("MyScript", "clicked");
} });

 

在這function內, 必須要自己判斷methodName來知道是哪個method被呼叫到, 應該是所有的java interface都可以用這樣去實作

OK, 這樣...很醜...繼續改進

2011年5月1日 星期日

公開: 阿格西自傳

More about 公開

這本書前陣子已經熬夜看完了, 想寫這篇一直沒寫, 最早剛出中文版時本來就想看了, 但被厚厚的一本嚇到, 但真的看的時候, 外表只是嚇人的, 整本內容雖多, 但看完還是大呼不不過癮呀!

雖然我網球看的不多, 不過正好他的時代, 我也多多少少有看了一些, 以前就有點蠻喜歡他的特立獨行(我自己也有點特立獨行吧, 總喜歡這類的人), 雖然對上Sampras他總是佔下風, 但他的職業生涯可是比Sampras更長, 成就也不低呀

本想說一個網球選手自己寫的自傳有可能會很沈悶, 但阿格西這本讀來完全不會枯燥, 完全看的出他直率坦蕩的個性, 每字每句毫不修飾, 好像想到啥就講啥, 愛恨分明, 喜歡誰不喜歡誰都明講, 毫不掩飾, 但整本讀起來就是很流暢, 實在看不出他接受的教育並不多

他就像是大多數的天才一樣, 自負, 自信高, 也因為本身的才能跟盛名差點招致毀滅, 但他不會完全倚靠他的天份, 而是想辦法打倒再站起來, 不斷的突破, 直到不能動為止, 雖然, 看得出來, 他真的很不喜歡網球, 其實根本就已經無關喜不喜歡了, 網球已經是他的一部分了

看完這本自傳後, 我只有一個感覺...我真喜歡這傢伙...還真想擁有他那一點點的狂妄呀~~~

Axis 時間軸

More about 時間軸

剛剛把時間軸也給K完了

這本時間迴旋的續作, 讓我有點失望, 比起時間迴旋來說差了不少, 整個故事主軸圍繞著追尋, 追尋失蹤的父親, 追尋假想智慧生物, 但最後的結果卻總覺得有點薄弱

但整體構築出來的世界觀不如時間迴旋來得大, 也不如時間迴旋來的有想像空間

如時間迴旋一樣, 除了原本科幻的故事以外, 也同時陪襯了男女主角的愛情故事, 我喜歡在時間迴旋中, 泰勒與黛安若有似無卻又強烈的牽絆, 雖然花費了很長的時間才修成正果, 但實在讓我蠻羨慕的, 而在時間軸中, 麗絲和特克之間, 就有點讓我覺得有點莫名其妙, 也沒啥很強烈的感覺, 最後雖是一個別離的悲劇下場, 但怎樣就沒啥感覺, 不過愛情故事應該不是重點才對.. :P

雖說遜於時間迴旋不少, 但還算是不錯看的一部小說, 只是沒特別的好看而已...

[POC] Using javascript to develop Android Activity

好久沒玩些好玩的了....先來點小菜....(POC = Prove of concept, 只是剛好有些想法, 所以來證明一下可不可行)

基本的想法是想用類似下面的javascript來寫出Android Activity(當然, 要延伸成其他的應該也沒問題)

https://gist.github.com/950551.js?file=gistfile1

 

這一個script有幾個簡單的組成 : 

  1. getcontentview : 用來指定這個activity所要用的main layout ID
  2. oncreate : 在Activity oncreate時被呼叫
  3. onresume : 在Activity onresume時被呼叫
  4. onpause : 在Activity onpause時被呼叫
  5. 基本延伸函數 : 
    • log: 等同於Log.d
    • findview: 等同於findViewById
    • R.layout("layoutname"): 等同於R.layout.layoutname (同樣的R.id("")也是...)

因為要在原本Android Java的平台上跑Javascript, 所以需要一個Javascript engine做為一個平台, 這邊選用的是Mozilla Rhino

Rhino可以幾乎無痛的在Android上使用, 當然SL4A有更多的script engine的選擇, 但SL4A的方向不同, 我是想弄一個也可以寫一般的Android program的script

初始化Javascript engine

 

第一個版本, 只是拿來實驗的, 所以script先放在asset裡面, 這一段會初始化基本的script engine, 然後從asset目錄裡面載入"init.js"

首先要先初始化一個Context instance, 所有的script執行都是要透過這個Context的, 不用後可以透過.exit()來釋放資源

jsContext.setOptimizationLevel(-1);

setOptimizationLevel(-1)這段很重要, 沒設成-1的話是無法在Android上跑的, 原因是Rhino會把javascript編譯成java bytecode以增加執行效率, 但這bytecode是標準的java bytecode而非Android dalvik的bytecode, 設成-1的話, Rhino會改用Intepreter來跑, 而非先compile

Host objects 和 Host functions

ScriptableObject.putProperty(jsScope, "R", RObj);

ScriptableObject.putProperty(jsScope, "log", new Log());

ScriptableObject.putProperty(jsScope, "findview", new FindViewById(this));

這一段包裝了一個host object和兩個host functions讓script使用(亦即是前述的5)

我把R包裝成另一個Object供javascript使用(因為我還沒找到如何讓Rhino使用static fields), 這包裝叫Rwrapper.java:

只是把R用reflection包裝一下而已

至於javascript function的部份, 其實也不難, 只要implement Function.call就可以了, 這邊實作了兩個(繼承自BaseFunction), Log.java和FindViewById.java

Log.java:

FindViewById.java:

 

不管是Object或是Function, 其實都是被當做objects來看待, 所以只要利用ScriptableObject.putProperty放到目前的scope去就可以給script取用了

目前看來, 這想法可行, 而且還蠻容易的, 缺乏的只是一些包裝而已, 甚至直接對view做操作也是可行的, 有空(會有空嗎?) 再來玩深入點.. :P

 

Recognize your friend with Face.com

替照片上的每個人都加上標籤(tag)是一個蠻好用的功能, 這可以方便你找到有某人的照片, 或是一群人在某時的合照, 如果善加利用是相當好用的功能, 目前主流的幾個相片服務像是Flickr, Facebook, Picasa等等, 都有這樣的功能

其中以Picasa的功能最為先進, 它可以自動幫你把你所有照片裡的朋友都挑出來標示, 不像Flickr跟Facebook就只能手動

如果每張照片都只能手動標示的話, 標示完所有的照片是很累人的, 更何況可能還有很多未標示的舊照片, 就這點來說, Picasa就強勁很多, 至於Facebook和Flickr呢? 所幸有Face.com

Face.com是一個做自動標示的服務, 其實這樣講有點狹隘, 自動標示照片的服務只是它其中一個產品 - PhotoTagger, PhotoTagger的用處就有點像Picasa做的一樣, 自動幫你把照片的人物找出來做標示:

_2011-05-01_8
當然準確度不會到100%那麼高啦, 不過加上手動輔助的話, 已經可以節省不少功夫了

此外還有PhotoFinder和CelebrityFindr....不過這些並不是重點, 它真正比較強大的是, 它乾脆把它的Face detection和Face recogintion 的API開放出來, 讓你可以利用它們的雲端運算做出自己的應用

它的API是以REST的形態提供的, 支援的後端服務有Facebook, Flickr, Twitter, 基本的API也大致相當完整, train, detect, recongnize, tag等等, 如果是做Facebook相關的應用, 甚至可以省略過train的部份, 就可以達到辨識的效果

當然, 剛剛的應用像是PhotoTagger都是以拍完後的照片為目標而做的, 如果拍照完後馬上就可以找出有哪些人可以tag的話, 那就更棒了

為了實驗這個我寫了一個簡單的Android app - Face.me , 只要拿著Android手機對著你朋友拍一張(按螢幕畫面), 它就會利用Face.com去找出你這朋友的名字 (可以從連結下載APK安裝, 因為Camera部分不熟, 寫的不太好, 可能會有bug, 就不open source了 :P) 

這App利用了一個open source的Face.com的Java lib叫face4j, 基本上這lib移植到Android上並不困難, 它用到一些apache commons, http的library, 只要把這些含入就可以

要開發這個, 首先你必須要有Facebook API key和Face.com的API key, Face.com的API key可以到這裡註冊個新的, 另外還得把Facebook的API key和secret註冊到Face.com上(看你信不信任它囉)

Facebook API的部份, 我是用Facebook Android SDK去開發的, 其實也沒用到幾個API, 大致上只有login和取得自己的UID而已

另外由於face4j在reconigize這個method只支援檔案跟url兩種方式, 我另外修改了一個支援input stream的:

https://gist.github.com/950492.js?file=gistfile1

 

剩下的部份就簡單了, 在Camera.takePicture的第三個參數的PictureCallback.onPictureTaken裡加上: