9 Mar 2010, 11:46am
Android
by lachesis

leave a comment

[筆記]讓Android emulator連intranet

先說明,這算是某種特殊情況,一般Android開發者不見得會遇到同樣情形。總之在公司內部使用Android emu時,打開browser可以使用內部IP連上內部網站,但如果是使用domain name就會失敗,說是無法解析DN。試過使用官方說明的emulator下 -dns-server參數,但直接就在開模擬器時收到無法解析的錯誤了,當然browser一樣不認得內部網站的名稱。強者小Y同事建議改 hosts 檔看看,不過會得到 "failed to copy 'hosts' to '/system/etc/hosts': Read-only file system" 這樣的訊息。找到一篇blog文章提供的解法:Configure hosts File in Android。一開始嘗試是失敗的,後來小Y大人又給了些建議之後成功了。事實上,直接參考該文的做法對 Android 1.5, 1.6 的模擬器都是有效的,但偏偏我剛好正在用來測的是2.1。直接把作法寫在下面:

[通用部分]
如果開了一個以上的模擬器的話請自行加adb參數
0a. 先adb pull /system/etc/hosts hosts抓回local來修改。
0b. 在原本的 127.0.0.1 localhost 加上新的行,寫入你需要的對應如 192.168.1.15 mytestsite,存檔。
1. adb remount (才不會發生Read-only file system錯誤)
2. adb push hosts /system/etc/hosts

[2.0.1, 2.1 only]
這兩個版本會在這邊丟出錯誤訊息,分別為
failed to copy 'hosts' to '/system/etc/hosts': No space left on device
failed to copy 'hosts' to '/system/etc/hosts': Out of memory
解決方法是,開啟模擬器時不要直接從 AVD Manager介面開,請下指令:
$ emulator -avd youravdname -partition-size 128
接著再對這個模擬器使用上面的 hosts修改大法就不會出現錯誤了。

partition size的單位是MB,預設似乎是64。從adb shell 用 df 指令觀察的結果,/system 和 /data 都會被這個設定成這邊指定的值。而1.5, 1.6 的 image 因為剛好沒超過 64MB,還剩下一點空間,所以 hosts 還寫得進去,而 2.x 的 image 有 七萬多K,mount之後 /system 這個 partition 看起來就是全滿,剩下空間 0K。因此 hosts變肥後無法寫入,真的是因為partition爆了。事實上正常的手機確實也不需要留空間給user hack…模擬器還讓我們調參數已經很偷笑了,可惜AVD Manager 的 Start 沒地方可以設定 partition size。若有此需求的話只好麻煩一點手動下指定開emulator囉。

8 Mar 2010, 11:20pm
FFXI
by lachesis

leave a comment

FFXI 垢魔道士を誘っちゃったPT

FFXI 垢魔道士を誘っちゃったPT

雖然是很老的flash,再看一次還是笑到肚子痛,配樂也配的好讚。尤其那隻黑塔魯跟我長一樣… 害我想起小時候也遇過好幾次睡好的怪被打醒然後塔魯就屁屁朝天了。 (*/ω\*)

8 Mar 2010, 10:58pm
ACG
by lachesis

leave a comment

【歌詞】ラブレターのかわりにこの詩を

信蜂 テガミバチ OP2。非常清新的曲風,但其實是相當感傷的歌詞。

ラブレターのかわりにこの詩を
歌:星羅
詞:星羅、中山豪次郎
曲:中山豪次郎

紙に書いたらわかるのかな
言葉にすれば見えるのかな
何も無くなってしまった
だけど身体重く感じた

足りなかった言葉 やっと気付いた
今なら全て包めるのにな

何度名前を呼んでも
決して届かないけど今
思い出す 振り向く笑顔が
まぶしくて きゅっと目を伏せた
もう二度と誰かのこと
すきにならないと思ってたのに
君だったから ほどけたんだ
なのにもう 君が居ないんだ

今は何処を歩いてるんだろう
灯り見失ってしまった

欠けちゃった心 補うために
誰かを想えたら楽なのかな

何度名前を叫んでも
決して届かない夜空に
浮かべてる 柔らかい笑顔
まぶしくて きゅっと目を伏せた
もう一度と誰かの事
すきになろうと思ってみたのに
君の声が 離れないんだ
だから今 君を呼ぶんだ

そっと胸に抱いた 言葉を手紙にたくした
一言でいい 届いてほしい。 涙 ひとしずく 落ちた

何度名前を呼んでも
決して届かないけど今
思い出す 振り向く笑顔が
まぶしくて きゅっと目を伏せた
もう二度と誰かのこと
すきにならないと思ってたのに
君だったから ほどけたんだ
ありがとう今も思うんだ
君だったからほどけたんだ
だから今 君を想うんだ

24 Feb 2010, 2:50pm
Android
by lachesis

leave a comment

[筆記]Android emulator常用指令與技巧

1. 切換 Layout為 Landscape or Protrait: Ctrl + F11 or Ctrl + F12

2. 模擬網路 ON/OFF: F8

3. 模擬有電話打進來的情形: 開兩個模擬器即可互打,電話號碼就是模擬器上的 5554, 5556 etc。

4. 把檔案放到 emu 的 sdcard 或系統目錄
adb push my_song.mp3 /sdcard/my_song.mp3

5. 從 emu 把檔案 copy出來
adb pull /data/data/com.example.android.notepad/databases/note_pad.db note_pad.db

6. 安裝 apk 到 emu 上
adb install c:/android-apk/myapp.apk

7. 進入 emu 的 shell ,可執行 ls, rm 等動作,有root權
adb shell

8. 進入sqlite3 shell,先進入 shell之後
# sqlite3 /data/data/com.example.android.notepad/databases/note_pad.db

以上指令如果在開啟了超過一個模擬器的狀態下,必須指定要針對哪個模擬器
adb -s emulator-5554 shell
列出所有模擬器代號:
adb devices

附註: SQLite資料檔可以使用 push pull 拉到 emu外來使用輔助工具 SQLite Database Browser 來瀏覽或管理,對開發很有幫助。

11 Dec 2009, 1:45pm
Android
by lachesis

leave a comment

[筆記] Android 使用httpclient對self-signed certificate網站進行SSL連線

Android SDK 在進行 https 連線時,對於自簽署的憑證是會拒絕連線的,會得到 Not trusted server certificate 的例外。如果使用 HttpsURLConnection 來連線,網路上可以找到一些破解方法,在此不多談。使用 apache httpclient 其實執行效率比較差一點,但是他最大的好處就是有內建的機制儲存cookie,並且也可以跟隨 server 作自動轉址。網路上資料比較多的是 httpclient 3.x版,Android 使用 httpclient 4 (而且還有些實作被拿掉) 唯一找到比較可信的來源是 apache httpclient 官方的 example。節錄重點段落如下:

        KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
        FileInputStream instream = new FileInputStream(new File("my.keystore"));
        try {
            trustStore.load(instream, "nopassword".toCharArray());
        } finally {
            instream.close();
        }

        SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore);
        Scheme sch = new Scheme("https", socketFactory, 443);
        httpclient.getConnectionManager().getSchemeRegistry().register(sch);

直接把這段拿去用當然只有一個死字。本來看討論以為是要製造一個假的空憑證騙過 httpclient,從 Android 檔案系統有點微妙開始改來改去,一連串不同的例外或直接crash就不多談了。解決了檔案路徑,到底有沒有建立等等方面的問題之後才終於發現,假憑證是不行的…

1. 所以首先,開啟你PC或Mac上的瀏覽器連上目標網站,從憑證管理的地方把該網站的憑證匯出。每個瀏覽器做法都不同,請各位發揮正常工程師的水準做完這件事。以Firefox為例,找到site名後選匯出,多半是會得到一個檔名為 your_site_name.crt 的 X509(PEM) 憑證檔。為了之後使用方便,先把這檔案複製一份並把檔名改為 your_site_name.pem。

2. 將這個憑證格式從 PEM 轉為 BKS 格式。 這是關鍵性的一步啊。

KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());

這行中的 getDefaultType 到底會 get到什麼 type 呢?答案:在 Android 中是 BKS。有 J2ME 經驗的人會想說,我看多半是跟 J2ME 一樣的 Sun JKS 格式吧,而且,我不要用 getDefaultType 就好了,我可以自己指定為 PEM, JKS格式啊。是的,你可以。只是你會得到錯誤訊息說 KeyStore JKS implementation not found。測了半天,看起來 Android 的 httpclient 只吃 BKS 就對了,其他都沒實作。

3. 那格式要怎麼轉?根據網路上找到的資料,可以使用 KeyTool IUI 這個Java工具。打開後從介面選 create → KeyStore,格式選 BKS,自己命名一下,要不要設密碼都可。接著選 import → Keystore’s entry → Trusted certificate → Regular certificate。 Source 的部分選 PEM 並選到剛剛瀏覽器得到的那個檔,Target 當然選 BKS 和剛 create 出來的檔。順利的話你應該就會有一個 your_keystore.bks 之類的檔案了。

4. 要把憑證檔放在 Android app 能讀到的地方,做法有兩種,放在 SD card 中,或直接放在 resources 中。

[方案一] 放在 SD card 的情形:首先模擬器要掛上SD card,這在 Eclipse 用 AVD 工具產生 avd 時就可以順便指定SD了。如果習慣用指令的話,也可以用如下指令產生 image 並 mount 上:

$ mksdcard 512M my_sdcard.so
$ emulator -sdcard ./my_sdcard.so

再來要把憑證檔 copy 到 SD card 中,目前只知道指令的做法:

$ adb push file_path/your_keystore.bks /sdcard

如果有顯示類似 ftp 傳輸速度之類的訊息應該就是成功了。
接著把 android 程式碼中檔案部分改一改

        FileInputStream instream = new FileInputStream(new File("/sdcard/your_keystore.bks"));
        ...
            trustStore.load(instream, null);

如果沒設密碼,可以把 keystore load 的第二個密碼參數改成 null,有設的話當然就把 “nopassword” 改成你的密碼。
基本上這樣應該就大功告成了。

[方案二] 再講講憑證放在 resources 的方法。首先把檔案複製到專案下的 res/raw/your_keystore.bks 。Eclipse 沒有錯誤的話就 ok,否則多半是你檔名不合規格,稍微改改。接著取用方法是把 android 程式碼改成:

InputStream instream = getResources().openRawResource(R.raw.your_keystore);

其它同SD card。

5. 還有一個地方要注意,就是 SSL port。

        Scheme sch = new Scheme("https", socketFactory, 443);

如果你要連的網站不是用 port 443,這邊請記得改掉。

6. 另外如果要使用檔案放在 resources 的做法,getResources() 應該只能在 Activity class 中執行,如果另外包裝連線類別的話請不要直接服用上面的程式碼,要自行從 context 抓到資源再傳過去。

看起來不太複雜的事情我其實還鬼打牆了滿久才解決,希望對各位有點幫助。

10 Dec 2009, 11:19am
Android
by lachesis

leave a comment

[筆記]Android 的 Activity Lifecycle

Activity Lifecycle實驗:1 = Root Activity, 2 = Sub Activity started by 1

Scenario A

  1. 先測單一Activity時,程式啟動,進入主畫面
    onCreate 1
    onStart 1
    onResume 1
  2. 按 BACK,螢幕跑回桌面
    onPause 1
    onStop 1
    onDestroy 1
  3. 選程式icon再進入主畫面
    onCreate 1
    onStart 1
    onResume 1

結論:在 Root 按 BACK 等於結束程式。

Scenario B

  1. 程式啟動進入主畫面
    onCreate 1
    onStart 1
    onResume 1
  2. 按 HOME,螢幕跑回桌面
    onSaveInstanceState 1
    onPause 1
    onStop 1
  3. 選程式icon再進入主畫面
    onRestart 1
    onStart 1
    onResume 1

結論:在 Root 按 HOME 只是把程式放到背景,重新進入後不會執行 onCreate。

Scenario C

  1. 程式啟動進入主畫面
    onCreate 1
    onStart 1
    onResume 1
  2. 按下按鈕,進入畫面2
    onSaveInstanceState 1
    onPause 1
    onCreate 2
    onStart 2
    onResume 2
    onStop 1
  3. 按BACK 返回主畫面
    onPause 2
    onRestart 1
    onStart 1
    onResume 1
    onStop 2
    onDestroy 2

結論:在 Sub 按 BACK,Sub活動會消滅,另外看起來Android滿仔細的,停掉2重開1的流程是有巧妙的安排。

Scenario D

  1. 程式啟動進入主畫面
    onCreate 1
    onStart 1
    onResume 1
  2. 按下按鈕,進入畫面2
    onSaveInstanceState 1
    onPause 1
    onCreate 2
    onStart 2
    onResume 2
    onStop 1
  3. 在畫面2,按HOME 返回桌面
    onSaveInstanceState 2
    onPause 2
    onStop 2
  4. 選程式icon,會直接進入畫面2
    onRestart 2
    onStart 2
    onResume 2

結論:在 Sub活動按 HOME 會暫停Sub (Root早就暫停了),再回到程式是直接 Reactivate Sub畫面

Scenario E

  1. 補充:在 textbox 打字到一半,按POWER鎖住螢幕
    onSaveInstanceState x
    onPause x
  2. 解除鎖定,會直接回app畫面,並且之前的輸入到一半的文字不會消失
    onResume x

Scenario F

  1. 補充:打字到一半,有電話進來
    onSaveInstanceState x
    onPause x
    onStop x
  2. 掛斷電話,畫面及游標回到原來的 textbox,輸入的文字還在
    onRestart x
    onStart x
    onResume x

這裡面有個更讓我在意的事情,就是我在兩個Activity都有overwrite onRestoreInstanceState,並加入message,但是從來都沒有被呼叫過。官方手冊在提到 onSaveInstance 的時候,也是說明這儲存的bundle是讓你在下次onCreate時使用,並沒有提到 onRestoreInstanceState。不論如何,這兩個method並不是在 Lifecycle 中必定會呼叫的程序,不要依賴它們來儲存使用者輸入到一半的資料,照設計目的看來比較像是記住上一次是看到第二頁之類的功能。之後如果有讀到相關說明再補充上來。

上面的實驗雖然 onPause 和 onStop 總是在一起,但根據手冊,Pause 狀態跟 Stop狀態確實是不同。Pause狀態下,使用者不能與這個活動互動,但是仍然看的見它。也就是說如果你產生了一個透明的或不占到全螢幕的子活動,則主活動有可能只會 Pause,而不會 Stop。而Pause狀態對系統來說仍然是alive,只有系統資源真的太低時才會kill它,而Stop的活動相對來說很有機會被殺掉。(不知道 Alert Dialog 與 Parent是不是這種關係)

關於保存狀態或傳遞資料方面,官方SDK手冊強調,如果需要回傳結果給主活動,不要在 onDestroy 加入 setResult function! ,之前被 google 到的某論壇文章騙了,說可以在 onDestroy setResult,怒。根據手冊說,想要做保存資料,例如 user 輸入之類的事情應該放在 onPause,onDestroy 應該只做釋放資源之類的動作,因為 oPause是唯一一個保證會在系統 kill process 之前呼叫並且等待其return的function。實際上測試的結果,確實在 onDestroy 試圖 setResult 是沒有用的,intent 應該是會隨著此sub Activity 被消滅,onActivityResult 的地方會得到 null intent。一般來說返回鍵表示要放棄現在的動作返回,不保留狀態還算合理,但看了一下Android的通訊錄app,按下返回鍵時,其實還是當作 submit 立刻儲存了打到一半的資料,這可能是為了防止編輯到一半電話進來,資料全被清空的滿腔怒火。另外已經在背景的Activity是有機會被kill process的。萬一發生了這事情,在kill process之前會先 onSaveInstanceState(Bundle),下次再 onCreate(Budle) 時就可以使用這 bundle 的動態暫存資料。

總之,儲存永久性資料的動作可以在 onPause做,onDestroy只能做資源回收,比如 connection close,之後有其他心得會再補充資料。

9 Dec 2009, 11:43am
Android
by lachesis

leave a comment

[筆記]Android 多國語言

官網的Hello, L10N,還有 ADT plug-in 都叫大家使用兩個字母的語言代碼,例如 zh, en, ja 來分字串語系檔。圖片則規定要使用語系+地區,例如 zh-rTW。這時候最大的疑惑立刻浮上心頭,那簡體跟繁體字串要怎麼辦(〃*`Д´)。網路上沒有搜到甚麼資料,乾脆自己惡搞看看,直接把/res/values-zh/strings.xml 複製修改成兩份,變成 /res/values-zh-rTW/strings.xml 跟 /res/values-zh-rTW/strings.xml 內容當然分別是簡體跟繁體的。喔! 沒有編譯錯誤,很好。接著開始切換模擬器語系…おおお!還真的會分簡體跟繁體啊!教學幹嘛不寫啊!(`・ω・´)總之姊妹們,有需要的話語系分下去就對了(*´∀`*)
ps. 版本的話,SDK 1.1的模擬器只有德文和英文懶的測,SDK 1.5 和 SDK 2.01 是測試OK的,推論應該是只要手機有支援相關語系都可以。

8 Dec 2009, 1:41pm
Android
by lachesis

leave a comment

[筆記]Android的返回鍵

從Main Activity 使用 startActivity 或 startActivityForResult 產生並切換到 sub Activity之後,如果按下返回鍵,會發生甚麼事? 本來很擔心整個sub Activity只是看不見,但仍然蹲在角落畫圈圈,隨著Main Activity一次一次的再度 startActivity 而產生撿不完的屍體。Google之後再測試一下發現好家在,按下返回鍵系統就會呼叫 onDestroy(),結束掉這個 sub Activity。上以前被寫得很爛的J2ME Midlet 嚇過,真的是很害怕屍體山啊,為了愛護大自然大家一定要做好資源回收喔。∑(´д`*)

關於 BACK key,HOME key,官方Dev Guide 的 Application Fundamentals 的 Activities and Tasks 這個 session 講得滿清楚的。你的整個 App 是一個TASK,root Activity 和 sub Activity,包括中間呼叫系統地圖在內,跑在同一個 TASK process,一個 TASK 就是一個 STACK。主活動也就是程式載入的第一個活動一定是在堆疊底端,它產生子活動時,子活動就被加入堆疊。按下BACK key 時,子活動就從堆疊中被拿出來(丟掉)。子活動的子活動當然也是相同。所以BACK key做的事情就是把現在這個活動拿去丟:P (各位兄弟姊妹們應該沒有忘記STACK是LIFO吧) 而HOME key又會做甚麼? 他不丟東西,他會把這整個TASK / STACK 放到背景。等你在別人家玩一圈,再度按下app icon,背景的那整包 STACK / TASK 就被放回前景。如果剛在是從某個子活動按下HOME,現在應該還是看到剛才的那個子活動才對。BACK key則還是負責殺掉目前的子活動,並不會回到你剛玩過的其他app。謎之聲:不知道為什麼忽然開始覺得好險沒有Forward Key。另外補充一點,就是如果離開去外面玩太久,系統會把TASK中的子活動都殺光,只剩下主活動,下次切回來時看起來就好像新開的應用程式一樣。

上面說的是系統預設行為,TASK 和 Activity 的行為是可以由一些參數設定加以改變的,這邊就不深入討論了。有興趣可以繼續看完上面給的連結。

4 Dec 2009, 10:51am
FFXI
by lachesis

leave a comment

私にとって、シャントット帝国最大の陰謀は…

クローン・タルタル部隊はフォモルだヽ(`Д´)ノ

這次更新之後先去解了超壯闊超感人的塔魯史詩完全召喚篇,接著看山多軍又一次學不乖沒帶解毒藥死掉,再勉為其難的拿了一下巴斯D3棍,之後當然就是衝S斯拉S女王的劇情了。解到萬歲牌塔魯部隊時,時間有些晚應該沒有野團shout了,就先去收集星屑順便開希望看有沒有現地團。這種時間…好吧雖然是米人勸誘就打看看吧。組到最後只有隊長是米人( ´Д`)=3 還是很沒耐性的米人(話說有幾個米人有耐性了) 我說看這編成沒黑,要回去換黑他不想等,當然沒兩下就全滅出來了。沒想到隊長居然畏罪潛逃,剩下五個『日人』,反正就先收星屑吧。後來T塔魯找了Y大來一起打,總之最後打贏了,跟日人也聊的滿愉快的,恩,這其實是前言。
其實因為上班後比較懶神兵勳章都被拔了兩階了,本來打算打完黑白香拖拖就再度封印,不過既然換了からくり士穿的加速褲子總要去感受一下。就這麼吃了一堆自主海老,升了好幾點沒力波後某一天,忽然想到詩跟召都40了還沒去拿AF1。就開著赤掛忍去震動的迴廊秒了一隻眼怪,想說沒練習過solo召喚獸,就又打了個土召換。開赤忍沒有D1也沒teleport可回家,就直接掏出了塔布戒。既然都飛到地下壕了,就去禮拜堂拜拜一下吧。跟fomor無冤無仇的我進了禮拜堂的fomor區當然是不會補消音,正在對書架上下其手找料理書的時候消音掉了。一瞬間忽然聽到fomor唱忍術的唱忍術,轟魔法的轟魔法,完全不知道發生甚麼事就看到本塔魯屁屁朝天了,而且周圍都是fomor,雖然掛了RR也不敢爬起來只好D4。゚(゚´Д`゚)゚。 我…我沒有殺fomor阿哪來的怨み…震驚之餘努力回想了一兩分鐘,忽然腦中浮出一整排黑黑的塔魯高唱香脫脫萬歲的場景(´・ω・`)

『ドルチェ.シャントット!』
『ドルチェ.シャントット!』

グローン.タルタル

7 Nov 2009, 11:10pm
蘋果 電腦
by lachesis

leave a comment

cyberduck for snow leopard

剛剛想要傳東西到 web hosting才驚覺我的太空鴨溺水了…直接連去官網又沒仔細看說明笨笨的抓了3.2.1版當然還是不work。原來for 64bit snow leopard要抓beta版的 orz,目前是3.3b4,提供給跟我一樣瞎的蘋果人….・゚・(ノд`)゚・.