2012年7月19日 星期四

IFTTT

這是測試文...

不過順便介紹一下IFTTT好了
習慣了Posterous會轉文後, 就覺得Blogger在這點上很不方便還好有IFTTT

IFTTT的全名是If this than that

這是一個很好用的東西, 你可以創立很多的recipe來幫助你, 比如說下面這例子:

假如在Blogger發表一篇新文章就.....
設定其實也很簡單, 設定完條件後就設定服務和trigger

這例子是, blogger內加新文章就自動po到Twitter去
照著一步步做, 整個還蠻簡單的

 

[ADK] 連接ADK2012到MacOS Lion

我家裡的電腦是Mac mini, OS是Mac OS Lion, 如果照著ADK2012的開發文件想要去設定環境來開發, 一開始就會碰壁了

在文件中寫著, 你可以從"repo init -u https://android.googlesource.com/accessories/manifest"下載原始碼, 或是下載Mac版的ADK 2012 IDE (應該是由Arduino IDE改的)來開始開發

但不管是IDE也好, 還是照著command line的步驟來做, 都會得到無法在找到/dev/ttyUSB0的錯誤(在IDE裡面也根本看不到這個), 剛用估狗大神查了一下, 有人討論, 但也沒有答案, 最後是在ADK2011的文件裡找到解答, 差的就是FTDI USB Driver, 其實照它講的位置也沒找到mac版本的driver, 只有windows版本的driver, mac版本的可以到FTDI chip的官網下載

裝完FTDI driver後, 打開IDE就可以看到USB serial的位置了

_2012-07-19_11
在我電腦的例子是/dev/tty.usbserial-AH015SE1

接下來如果到"android-accessories/adk2012/board/MakefileBasedBuild"去在重build一次並重燒, 這次會發現, 在做

$> ./flash

這步驟時還是會失敗, 這是因為在這script裡寫死了

UART=/dev/ttyUSB0

所以UART的位置不是這個就會有問題, 因此我改成下列的方式燒

$> android-accessories/ADK2012.app/Contents/Resources/Java/hardware/tools/adk2tool /dev/tty.usbserial-AH015SE1 erase

$> android-accessories/ADK2012.app/Contents/Resources/Java/hardware/tools/bossac --port=tty.usbserial-AH015SE1 -w -b app/bin/test_sam3x_ek_sam3x8-flash.bin

$> android-accessories/ADK2012.app/Contents/Resources/Java/hardware/tools/adk2tool /dev/tty.usbserial-AH015SE1 reset

要照這順序執行, 一開始我不小心erase掉了後, 燒不成功(因為bossac少加了 --port), 整台黑漆漆的不動, 嚇了我一身汗, 以為把它搞掛了... :P

好吧, 可以開始亂改看看了

[Android] ADK 2012 偽開箱

昨天去了GTUG聽了關於Arduino的分享, 硬體我是大外行, 但這東西還真的是很有趣呀! 其實在Google I/O拿到了免費的ADK 2012, 目前也還沒想到除了高級鬧鐘外, 我要拿它來玩啥, 先來個開箱好了...呃...但其實我老早就把箱子給破了....好吧, 這是個偽開箱

 

整個東西其實是用磁鐵吸住的, 所以要把這鬧鐘箱打開, 其實很簡單, 打開後分為兩塊版, 上面那塊版據說是Arduino Due, 下面則是一堆Sensor

 

這一塊就是Due, 後端有SD

 

前端則有兩個USB加上電源, 它可以由USB供電, 也可以由這個電源供電, USB一個是連接PC用, 一個則是手機

 

Sensor則是有溫濕度感應, 大氣壓感應, 光感應, 顏色, 加速度, 磁力, proximity sensor等等... (呃, 這樣還是個鬧鐘嗎?)

當然也有NFC:

整個合體的外觀就像這樣:

 

當然, 這不是普通的Arduino, 這是ADK 2012, Android手機可以透過USB或藍牙與它連結

Android developer網站上有開發簡介: http://developer.android.com/tools/adk/adk2.html

也有一個範例程式, 可以從Play store上下載

Device-2012-07-19-170809

不過還沒想到該拿它來做啥, 不過以這形狀, 如果想拿來做個啥機器人之類的, 就有可能會需要把它給拆了吧?

不過如果能做一個這樣的東西, 也不賴呀:

2012年7月17日 星期二

[Android] Enable/Disable Activity at runtime

這篇主要來自Google I/O 2012這兩個Sessions:

Making Good Apps Great: More Advanced Topics for Expert Android Developers

Doing More With Less: Being a Good Android Citizen

在這兩堂演講中有提到, 可以利用"PackageManager.setComponentEnabledSetting"把不用的Intent receiver給停用, 這在Android中的確相當有用處, 常常Intent broadcast都是一個造成系統忙碌的主要原因, 在早期的Android版本, 甚至常常碰到因"android.net.conn.CONNECTIVITY_CHANGE"所導致的ANR, 這是因為註冊聽這Intent的receiver常常非常的多(大多網路相關, 而智慧型手機最常見就是網路相關的軟體)

不過這邊要講的並不是這個問題, 不過也可以應用到同樣的技巧

Android中, 可以設定多個Activity去處理同一種的Intent, Share (android.intent.action.SEND)就是最典型的例子, 但這也造成另一種困擾, 註冊的應用程式太多, 導致整個Share menu相當的雜亂難選:

由這個例子看來整個list相當的長, 這對使用者來說可能不好用, 而且問題在於, 有些可能不用一開始就出現, 比如說如果沒有登入任何一個e-mail account, Mail這選項是可以被藏起來的, 這作法就是

ShareActivity 預設成disable:

<activity android:name="ShareActivity" android:enabled="false">

這樣如果沒enable它的話, 就不會在Share list出現, 只要我們在某個點(比如說已經完成登入帳號)去enable它, 它就又可以回到這list了:

if(pm.getComponentEnabledSetting(cname) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED ) {
            pm.setComponentEnabledSetting(cname, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
        } else {
            pm.setComponentEnabledSetting(cname, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
        }

2012年7月8日 星期日

Google IO 2012

尼克大說,對Julian的十大IO問題之一應該是"你是自己花錢去的嗎?", 今年的確自費出國參加了幾個活動, 本以為今年也無緣IO了, 不過最終還是成行了, 不用繼續怨念, 這都得感謝很多人呀…首先是Tiffanie的幫忙牽線, 以及Elvis的慷慨讓票(老實說他大可以拿去賣黃牛票賺一筆,卻原價轉賣給我), 還有wuman, 不曉得幫我跟他朋友煩過幾次, 後來聽到尼克大也差點幫我弄到票, 實在非常的感動....還得感謝Arthur, 我這次就可以不用自費出去了(還得間接感謝這時候離職的Johnny :P , 還有也有幫我問的mifong), 反正終於不用在台灣枯坐在電腦前熬夜看轉播, 雖然去了美國還是熬著夜被公司這邊要東西(不是有人拿著保障名額出去的?), 好吧....總歸還是很高興....很感謝這麼多的人....

好了, 感謝完了, 進入正題, 猶豫半天, 還是把這篇當半遊記來寫, 反正好像還在Jet lag (呃, 都回來三四天了), 還睡不著, 適合胡言亂語, 寫寫流水帳

2012年5月9日 星期三

使用HTML5/Javascript做一個像Instagram的相機 (Only works on Opera mini)

Instagram是一個我一直蠻喜歡的service, 主要是簡單, 加上有一些濾鏡可以豐富我隨手拍的照片, 當然, 重要的是, 高價賣給了Facebook而一炮而紅

上星期, 參加了AT&T Palo Alto Hackthon, 拿到大獎的團隊用了一個lib叫 caman.js 的, 這東西讓我有點小小驚艷, 它光用javascript (其實是Coffee script)就實作出了許多影像處理的功能, 這讓我興起想用這個來試著做出類似Instagram的東西, 當然是純用HTML+Javascript

首先面臨的一個問題是, 實作Camera的部份, HTML5支援media capture的方式有三種(請參考Reference 3) : Input tag, device tag, WebRTC (getUserMedia)

但很不幸, 除了Input tag以外, 大部分手機上的browser,如Android browser, Firefox, Chrome, 可以說幾乎全部都不支援, 這可真是有點令人傷心的消息, 因為用Input tag, 會離開browser跳到另一個程式, 這樣就無法結合自己的UI了

不過, 其實也沒那麼絕望, Android上的Opera Mini, 就支援getUserMedia (參考Reference 1)

因此就可以實作出像這樣的東西:

Device-2012-05-10-021018

WebRTC(getUserMedia)的原理是把media stream導到video tag去播放(理應就這樣做), 但這樣出來的比例是camera的比例, Instagram的照片都是方形的, 要實現這點, 其實也不難, 就另外把內容畫到另一個方形canvas, 在video play的時候開始每隔40ms畫一次, 把video畫到canvas的方式也不難, 就把他當image看待就行了

不過當第一次使用時, 瀏覽器會跳出詢問是否允許使用相機的對話窗:

Device-2012-05-10-021029

因為偷懶, 拍照的部份沒沿用原本的canvas, 另起一個Canvas, 並把可用的濾鏡放在下面:

Device-2012-05-10-021056

接下來就是神奇的CamanJS的工作了, CamanJS是一個以CoffeeScript實作出來的影像處理的lib, 還真的蠻厲害的, 害我都有點想研究一下CoffeeScript了

使用方式非常的簡單, 像以下面的程式:

Caman("path/to/image.jpg", "#canvas-id", function () {

    // manipulate image here

    this.brightness(5).render();

});

就可以提高影像的亮度了,

此外還有許多預設的濾鏡, 我也偷懶直接採用, 這就是做出來的效果:

Device-2012-05-10-021122
Device-2012-05-10-020928

Source codes分享於此: https://github.com/julianshen/instagramlikecam

References: 

  1. http://dev.opera.com/articles/view/playing-with-html5-video-and-getusermedia-support/
  2. http://people.opera.com/danield/webapps/instant-camera/
  3. http://www.html5rocks.com/en/tutorials/getusermedia/intro/
  4. http://camanjs.com/

2012年5月7日 星期一

[筆記] Self published B2G app

B2G並未一定要開發者把應用程式發表到一個特別的app store, 網站也可以自行加一個install按鍵, 讓使用者把你的網站當應用程式裝到手機內

首先, 你必須要先有個manifest, 目前manifest並沒強制的檔名, 但文件裡建議叫 xxxx.webapp, 以下是範例內容:

 

{ "name": "MyTestApp", "description": "test app", "launch_path": "/", "icons": { "128": "/img/icon.png" }, "developer": { "name": "Julian Shen" } }

 

然後在網頁內加上檢查是否安裝, 以及安裝的程式碼, 範例如下:

var manifestUrl = 'http://localhost:3000/manifest.webapp'; var app = navigator.mozApps;  function checkInstalled() { var request = app.getSelf(); request.onsuccess = function() { if(request.result) { //installed console.log('installed'); document.getElementById('installmsg').style.display='none'; } else { //not installed console.log('not installed'); } }; }  function install(cb) { var request = app.install(manifestUrl); request.onsuccess = function() { alert('installed'); };  request. function() { alert('Not installed'); } }
這邊要注意的是manifestUrl必須是full path而不是只有相對位置, 寫相對位置, 它還是讀的到, 但會出parse error, 之前害我搞半天一直以為是格式問題, trace了一下Webapps.js, 發現可能是判斷install origin有問題
目前安裝介面很醜:
_2012-05-08_2
安裝完就可以在Home screen看到它的存在了:
_2012-05-08_2

2012年4月16日 星期一

[筆記] Deploy Mojito app to Heroku

First, you need to follow this doc (http://developer.yahoo.com/cocktails/mojito/docs/quickstart/) to install Mojito as a global node module. Why install it globally? Because you need the Mojito command line to create your first app.

Create application with command line:

mojito create app mymojito

Change working directory to "mymojito".

Create a "Procfile" whose content is:

web: mojito start $PORT

Use the following command to create an application on heroku and deploy codes to it.

  • git init
  • git add .
  • git commit -am init
  • heroku create mymojitotest --stack cedar
  • git push heroku master

After successfully commit codes to heroku, you could check running process with "heroku ps". However, you cannot find any running process. That is because there is one important step missed:

heroku ps:scale web=1

This command adds one dyno for web process. After that, you will find one web process when you check with "heroku ps". And the server is now started up. You can check your app with browser.

2012年4月12日 星期四

[筆記] Practice: Open graph with Facebook JavaScript API

Source: https://bitbucket.org/julianshen/videomag/overview

Demo URL: http://growing-wind-8625.herokuapp.com/top

Server: Play framework 2.0 on Heroku

Open graph object: Youtube video, Action: watch

It's not a problem to add youtube video since it already contains open graph meta data in page. All we have to do is call "/me/video.watches?video=youtube_link" with POST.

To post activity to timeline, the permission "publish_actions" is required. 

The result on timeline:

_2012-04-13_2

2012年3月25日 星期日

[拉麵食記] 香港 Mist 創作麵工房 與 秀拉麵

最近好像有點混, 都吃吃喝喝的, po的滿滿blog都拉麵, 連跑去香港參加Hack Event也吃了兩碗拉麵, 該反省一下, 不過反省歸反省, 食記還是要寫一下, 這次也偷懶把兩家併一篇寫

2012年3月17日 星期六

[拉麵食記] 台北 美濃屋

_001
_002

這家店還頗小的, 位子並不是很寬敞, 不過就有種來到日本拉麵店的感覺(也不是很寬敞)

而且, 連同煮麵跟外場服務, 總共也才不過兩個人(一人煮, 一人服務), 所以也難怪出餐的速度不是很快了, 不過小店嘛, 可以原諒...話說回來, 日本很多拉麵店更窄狹, 反而需求的人力也就不需要很多, 位子不多, 出餐的距離也不長

_003

先說餃子...煎的頗脆的, 一面脆一面軟, 口感不差, 我喜歡它的內餡, 蠻香的, 也不會覺得太過油

_004

拉麵的部份我點的是叉燒拉麵, 是他們基本的喜多方醬油拉麵多加幾片叉燒, 屬於醬油系的拉麵, 叉燒薄薄的, 沒啥口感, 就沒啥好說的

湯頭是醬油湯頭, 口感清爽, 並不是像他們說的很鹹(不過以一般台灣人口味來說有可能啦), 算是我最近吃過比較清淡的, 但我覺得還不錯

麵條是整碗中最好吃的, 口感不錯, 雖是細麵, 但有彈性, 還蠻好吃的

_005

雖然服務不是很周到, 等餐也等很久, 但還蠻親切的, 我看隔壁桌的客人本來想點"涼麵"(但其實聽他解說起來就是沾麵), 她還阻止他們, 說第一次來建議還是點拉麵,他們的涼麵在網路上最常被打槍, 就是因為很多顧客來, 不習慣這種吃法之類的, 還真誠懇呀

結帳時, 我跟她說我偏好比較重口味的, 她推薦我他們的味噌叉燒, 我下次會再去試試的

2012年3月10日 星期六

[拉麵食記] 台北 旺味麵場

[[posterous-content:pid___0]]

昨天Amy說, 這家是尼克大大推薦的台北最好吃的拉麵, 剛好這家也在我預計嘗試的清單內, 所以昨天晚上就跑去吃了

台灣吃到的拉麵大多是豚骨系的, 味噌系的不多, 有得話大多也只是吃起來像是味噌湯加麵, 但這家吃起來還真是紮實的味噌拉麵

我點的是季節限定的北海道粉雪拉麵, 就是味噌拉麵上加上一大堆的cheese粉, 湯頭甘口, 也就是比較甜, 但夠厚實, 麵條嚼勁不錯, 還蠻好吃的, 叉燒還算OK, 裡面還有兩條馬鈴薯, 建議不要在一開始就吃, 不然會覺得太硬裡面又涼涼的, 吸收過湯之後就很不錯了

比較大的缺點是, 選錯chesse了, 我以前也吃過這種加上chesse粉的, 不過跟湯頭融合的都不錯, 不會吃到後面, 碗底黏了一大堆黏黏的cheese, 這碗就是這樣, 吃到後面看到那一堆還真有點噁

[[posterous-content:pid___1]]

另外還點了叉燒飯

[[posterous-content:pid___2]]

這碗我沒有很推, 醬汁淋不夠, 叉燒有吃到軟骨沒剃除乾淨, 那個咬也咬不下去, 還得啃出來, 我不是很喜歡

下次想去試試信州味噌的....

2012年3月7日 星期三

[筆記] "Unsafe JavaScript attempt to access frame with URL" error with Facebook Javascript API

The following example shows how to create a simple Facebook login button with Facebook javascript API:

Normally, this page would be reloaded if user finished authorized your app. But it won't be reloaded in Chrome due to the follwing error:

Unsafe JavaScript attempt to access frame with URL https://s-static.ak.fbcdn.net/connect/xd_proxy.php?version=3#cb=f363e58d9&origin=http%3A%2F%2Fwww.ab.com%2Ffcb27588&relation=opener&transport=postmessage&frame=fac4c0f18&access_token=AAAEHZBpoK3B0BALv8Cf96gaKEnn4ZBtXgjCOQCFFhVDL4K0rZAE2NGDcqZCPlZByNNKEDmYSGKHQv8jAUM2yGZCHkOcyXUKhoZD&expires_in=0&signed_request=g7sYd_XQx-EBPtQQGk-0ISRMrUDnT4L4WHAmlNsVFBU.eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsImNvZGUiOiJBUURKYkZBNjZuemduSDBBN0dXWmd2SGxZZkQxQVp4Qm1MSnc0Z3ppUV9FQ25VeEYyZmcyTmJGcFh3UHZDeWhyYnFrT1RxNmRVc2xsb0d4dlFCd290UjRyV0ZsSnJtVjFoNy1QUTlJbTRROXh3MmNKMGU1b0NReWtmT1ZZcXhMUDRVRldVSDgwVU5ic1BLTHdyNk80cFlSVVItQzNIYjhyRWgxek40ZFEzSkpreXhBcU1KSHljcWxETzh2dF96T3ZpN0EiLCJpc3N1ZWRfYXQiOjEzMzExMzg3MjQsInVzZXJfaWQiOiIxMTI5MjgzNDM3In0 from frame with URL http://www.ab.com/login.html. Domains, protocols and ports must match.

Some people use FB.getLoginStatus() to check if user authorized app at page loaded. If page could be reloaded, it's no problem. However, in this case, it's not. 

There are several questions on StackOverflow related to this:

http://stackoverflow.com/questions/3577947/facebook-gives-unsafe-javascript-attempt-to-access-frame-with-url-error-in-chr

http://stackoverflow.com/questions/8013008/facebook-authentication-unsafe-javascript-attempt-to-access-frame-with-url

http://stackoverflow.com/questions/3010170/unsafe-javascript-attempt-to-access-frame-with-url-error-being-continuously

But none of these solves my problem. I don't want to solve this with introduce PHP sdk. I would like to solve it with pure front end codes. 

Therefore, I find 3 solutions:

  1. Ignore the error and register login event to solve the problem:
  2. Add attribute "show-faces="true"" to <fb:login-button> to solve
  3. Add attribute "render-in-iframe="true"" to <fb:login-button> to solve. This is a bad idea since this is an undocumented attribute.

In solution 2 and 3, login-button seems to be placed into an iframe. And 3 would display an incomplete login button (bug?)

2012年2月24日 星期五

[拉麵食記] 台北 山小屋 - 黑魔拉麵

Img_2553
Img_2551

這家離上次去的屯京不遠, 但卻不像屯京一樣大排長龍, 其實店內還坐不到一半, 不過上次吃屯京是吃沾麵, 所以無法比較拉麵, 不過這家山小屋也是蠻好吃的

我點的是 黑魔拉麵 , 跟我上次去大阪吃的黑河童是同類型的, 豚骨湯頭加上黑麻油, 一整碗像墨汁一樣, 豚骨湯頭還蠻鮮甜的, 應該有用心到, 配上黑麻油的香氣, 這碗湯頭是挺不錯的, 麵是細麵, 我要求要略硬, 口感還不錯, 叉燒則是一般

餃子皮有煎脆, 內餡有燙口, 蠻好吃的

最後....好久沒拍的空碗照:

Img_2557

2012年2月19日 星期日

[拉麵食記] 竹北 大海拉麵 - 地獄拉麵

今天又跑去吃拉麵

因為想到說我還沒吃過大海的地獄拉麵, 就跑去吃了一碗, 大海吃過了好幾次, 竹北這家, 我是認為不是很穩定, 有時吃的湯頭太淡, 有時卻又非常濃厚, 不過這附近也沒好吃的拉麵就是了

這碗地獄拉麵是在原先的湯頭上加上辣醬而成的, 本想說感覺沒太大特色, 但吃起來還頗搭的, 辣味襯托出原本湯頭的甜味...

我最喜歡的吃法就是加點一碗蔥, 倒進去豪邁的吃.... 

2012年2月18日 星期六

[拉麵食記] 台北 屯京拉麵

這家是衝著雜誌介紹去吃的, Friday Night, 單槍匹馬去, 居然還要排到快40分鐘, 比平常這時候在台北車站吃花月嵐排更久, 它座位還比較多

雜誌上介紹的是魚豚拉麵, 不過吃過一些魚貝系的湯頭, 我對這種湯頭並不是特別喜歡, 又想吃つけ麵(沾麵), 所以就點了這碗辣的沾麵來吃...(也有不辣的湯頭)

加麵是不加價的, 我又多花了70元加料, 端來就是這麼滿滿的一大碗, 份量還很夠

麵條是捲曲狀的, 還蠻好吸收湯汁的, 只是過軟, 個人偏好硬一點的麵條, 起初沾個兩三下就入口, 感覺湯頭不夠濃, 加上沾麵的溫度比拉麵低一點, 也不覺有多辣, 鹹度是還蠻夠的, 後來把麵料浸入一段時間再撈起吃(等於當拉麵來吃了), 就覺得還不錯了

除了排隊久了點外, 這家還算不錯吃, 下次有機會再去試它的拉麵好了...

2012年2月17日 星期五

[Android][筆記] JavaScript injection in ICS

看來script injection也不算是啥旁門左道了, 在Android 4.0 ICS上的WebView也使用了同樣的技巧了(在Gingerbread上並未看到這樣的codes)

Device-2012-02-17-171716

在ICS的Setting裡面"Accessiblity"裡有個設定叫"Install web script", 其實這東西應該沒使用者看的懂, 其實蠻怪的, 不過既然放了就有它的作用

ICS的WebView裡面有這樣一段codes:

int axsParameterValue = getAxsUrlParameterValue(url);

        if (axsParameterValue == ACCESSIBILITY_SCRIPT_INJECTION_UNDEFINED) {

            boolean onDeviceScriptInjectionEnabled = (Settings.Secure.getInt(mContext

                    .getContentResolver(), Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION, 0) == 1);

            if (onDeviceScriptInjectionEnabled) {

                ensureAccessibilityScriptInjectorInstance(false);

                // neither script injected nor script injection opted out => we inject

                loadUrl(ACCESSIBILITY_SCRIPT_CHOOSER_JAVASCRIPT);

                // TODO: Set this flag after successfull script injection. Maybe upon injection

                // the chooser should update the meta tag and we check it to declare success

                mAccessibilityScriptInjected = true;

            } else {

                // injection disabled so we fallback to the basic built-in support

                ensureAccessibilityScriptInjectorInstance(true);

            }

        } else if (axsParameterValue == ACCESSIBILITY_SCRIPT_INJECTION_OPTED_OUT) {

            // injection opted out so we fallback to the basic buil-in support

            ensureAccessibilityScriptInjectorInstance(true);

        } else if (axsParameterValue == ACCESSIBILITY_SCRIPT_INJECTION_PROVIDED) {

            ensureAccessibilityScriptInjectorInstance(false);

            // the URL provides accessibility but we still need to add our generic script

            loadUrl(ACCESSIBILITY_SCRIPT_CHOOSER_JAVASCRIPT);

        } else {

            Log.e(LOGTAG, "Unknown URL value for the \"axs\" URL parameter: " + axsParameterValue);

        }

這功能啟動的條件是url裡有"axs=1"或是剛講的那個設定是enabled, 而這一整段code是在onPageFinished最後被呼叫到的, 也就是頁面載入完成之後

它主要做的只有:

 loadUrl(ACCESSIBILITY_SCRIPT_CHOOSER_JAVASCRIPT);

這邊並不是強制去載入一個新的URL, 其實他做的就是script injection, ACCESSIBILITY_SCRIPT_CHOOSER_JAVASCRIPT的內容就是:

    // JavaScript to inject the script chooser which will

    // pick the right script for the current URL

    private static final String ACCESSIBILITY_SCRIPT_CHOOSER_JAVASCRIPT =

        "javascript:(function() {" +

        "    var chooser = document.createElement('script');" +

        "    chooser.type = 'text/javascript';" +

        "    chooser.src = 'https://ssl.gstatic.com/accessibility/javascript/android/AndroidScriptChooser.user.js';" +

        "    document.getElementsByTagName('head')[0].appendChild(chooser);" +

        "  })();";

它就是在最後把https://ssl.gstatic.com/accessibility/javascript/android/AndroidScriptChooser.user.js給inject到page

還沒去仔細看js裡面的內容, 似乎都是一些基本的東西的樣子, 還不太知道他的用意, 不過應該跟加速(?) Google本身的頁面有關係, 不然其他web site應該也沒用到這些東西

2012年2月5日 星期日

[Kindle] 使用Calibre來建立中文的分類 - Kindle Collections plugin

雖然Kindle keyboard有鍵盤, 但也只能輸入英文, 因此也沒辦法建立中文的分類, 有時候還蠻頭痛分類的命名

自從買了Kindle後, 還蠻常用Calibre的, 不過很慚愧的是, 常用它來轉文件卻很多功能都沒去發現到, 今天為了想改個Kindle的字型, 才發現它很多好用的plugin可以用, 其中一個就是Kindle Collections plugin

安裝的方法:

_2012-02-06_12
---->

_2012-02-06_12

----> Get a new plugin

然後找到Kindle Collections安裝即可

裝好後可能會沒看到任何東西, 所以必須要去Preferences -> Toolbar設定

選擇"The main toolbar when a device is connected", 從左邊找到Kindle Collections把它放到右邊去, 這時候當你Kindle連上電腦後就可以看到這樣的按鈕在toolbar上:

_2012-02-06_12

它提供的功能包含讓你從Calibre同步分類過去, 也可以手動編輯分類, 我不想同步, 所以我用到的只有手動編輯

另外值得一提的是它有一個"Modify Kindle Settings"的功能, 可以讓你在不用Jailbreak下換字型 (這也是我今天最主要的目的):

_2012-02-06_12

在做這件事之前, 必須先在你Kindle的根目錄開一個"fonts"的目錄並把你的ttf字型檔放進去(檔名格式是xxx-Regular.ttf, xxx-Bold.ttf)

我還蠻喜歡Android ICS的蘿蔔頭(Roboto)字型的, 不過早上弄了半天一直不成功, 後來才發現, Roboto只有英文字型, 如果在中文書內改變字型, 就會跑回預設設定, 也就是原先預設的字型

解決的方法就是要合併中文字型進去, 在Android中, 中文字型是放到DroidSansFallback.ttf去了, 這時候可以用fontforge來合併字型

這邊有提到怎做:

  1. http://7thgen.info/blog/2008/07/merging-font-with-fontforge/
  2. http://fontforge.sourceforge.net/scripting.html

 

Open($1 + ".ttf")

SelectAll()

ScaleToEm(1024)

Generate("temp.ttf", "", 0x14)

Close()

Open($2 + ".ttf")

SelectAll()

ScaleToEm(1024)

MergeFonts("temp.ttf")

Generate("new_" + $2 + ".ttf", "", 0x14)

Close()

 

 

因為Roboto除了正常字體外還有粗體, 斜體, 粗斜體等等字型檔, 我不太確定只合併一個夠不夠, 所以小改了 1 裡面提的script, 假設把上面的script存成merge.pe , 執行的方法如下:

fontforge -script merge.pe DroidSansFallback Roboto-Regular

依序再把其他字型合併

這是正常改成Roboto的結果:

Screen_shot-57283

按"Aa"鍵可以挑字型, 這時候你可以看到字型設定在"alt", 這方法的缺點是, 千萬別改成其他字型, 要不然設定又會跑回預設, 也會找不到"alt"

中文字型也有比原先好看點, 但我還不是很滿意, 之後再來試試其他字型:

Screen_shot-57285

但選單的字型是不會跟著改的, 還是原來的:

Screen_shot-57286

 

 

最後....上面Kindle的screenshot是怎抓的? "Alt + ↑ + G"