2012年8月16日 星期四

申請個人或公司型 Android Developer 開發者帳號

Android Developer Console


摸了 Android app 大概有快一年半吧,一直以來都沒接觸過 Google Play (Android Market) 這塊東西,如今有幸幫公司處理,就來筆記一下啦!購買開發者帳號需要一張有效的信用卡,並透過 Google Wallet 來使用。首先從 Android Developer 官網連入,從右上角選單可以看到 Google Play Developer Console ,點選後進行登入,如果還未註冊為 Android 開發者時,就會顯示註冊畫面,輸入完"開發人員名稱/公司名稱"、"電子郵件地址"、"網站網址"、"電話號碼" 後,就可以點選繼續進行。


Android Market 開發人員發佈協議


接著同意一下條款後,接著就會導到 Google wallet 來進行付款的部份。


註冊成為開發人員


如果要報公司帳,應該要用公司信用卡才行?接著填一填信用卡資料後送出後,驗證完信用卡就算完成吧,並且可以查看 Google wallet 的購買清單狀態或是直接切回 Google Play Developer Console,而 Google Play Developer Console 一開始會顯示資料處理中,但似乎不影響軟體上架的設定:


進行中


過一陣子後,就會顯示已完成的狀態


處理完


如此一來就可以慢慢把玩啦!接著就從右下角的 Upload Application 後,就可以上傳 APK 檔案,並進行後續的設定囉(似乎離軟體上架還有段距離要設定...)。


至於怎樣算是公司型開發者帳號呢,其實就只要修改 Profile 把顯示的名稱改成  XXX Inc. 就差不多了 XD 比 iOS 公司型開發者要容易許多啊啊,並且可以新增無限多的帳號來使用開發者權限。


最後一提,如果公司沒有信用卡並使用個人信用卡去綁公司指定的 Gmail 帳號的話,那用完後可以連 Google Wallet 帳號,在付款方式那邊可以刪掉已綁定的信用卡唷,如此一來就不用擔心自己的信用卡一直綁在公司帳號啦。


2012年8月13日 星期一

[Android] Galaxy Nexus 刷機筆記(重返 Google 親生子?) @ Mac OS X 10.8

七月多推薦周邊親人買 Galaxy Nexus 來用,那時洽逢 SAMSUNG 與 Apple 智慧財產官司的關係,花了好大一把功夫才買到一台(空機價約13.5k附近),雖然不是最便宜的(美國官網公訂價$399美金,台灣有機會可以找到 13k 一台),但看在缺貨情況已經很滿意了。使用上除了拍照有聲音外,還都不錯用,不致於想要 root 它啦,不過,讓我想更新它的主因是...直到 2012-08-11 時,尚未接收到 Android 4.1 OTA 更新通知,查了一下原來這隻手機似乎是港台機?代號是 yakjuzs 並且屬於 SAMSUNG 系列的?也就是系統更新是 SAMSUNG 在維護的,與其等到 SAMSUNG  推出 Android 4.1 更新檔,還不如自己更新吧 :P 於是就下海刷一下吧!


雖然過去工作常編 AOSP 甚至把一些手機 root 研究,但本身使用 Android 手機時,並不太想要 root 或刷機的 :P 例如刷機刷用的檔案有沒被加料等等。故這次更新我主要採用 Google 官方提供的 Factory Images for Nexus Devices 來源,這也是我專挑 Google Nexus 原生手機的主因之一,可以方便地處理一些事務。


刷機有風險,需自行承擔手機失去保固或變成磚頭


手上這隻手機在 "設定" > "關於手機" 可以看到 "基頻版本" 為 I9250XXK1 和 "版本號碼" 有 "ITL41F.I9250ZSKKB" 字樣,並且透過 Android-SDK 來取得 adb/fastboot 等指令來驗證系統,並把手機接上後,也將手機開啟開發者設定,使用 adb devices 和 adb shell 確認手機狀態:


$ adb devices
XXXXXXX

$ adb shell cat /system/build.prop
...
ro.build.id=ITL41F
ro.build.display.id=ITL41F.I9250ZSKKB
ro.build.version.incremental=I9250ZSKKB
...
ro.build.version.release=4.0.1
...
ro.product.model=Galaxy Nexus
ro.product.brand=samsung
ro.product.name=yakjuzs
ro.product.device=maguro
... 


進入刷機前,請先手動備份需要的資料,實在是過程會清掉系統資料,就像重灌電腦一樣。備份資料嘛,例如手機內的照片、簡訊、鈴聲等等,其中簡訊用 SMS Backup & Restore 這套 Android app 軟體,可以輕鬆地把簡訊匯出 XML 檔案,並支援匯入(若有草稿需先清掉才能正常備份)。


接著,把手機關機後,同時按 "Volume + 鍵" 、 "Volume - 鍵" 和 "Powert 鍵" 一會兒,手機就會進入 fastboot mode:


fastboot_mode


透過指令進行 bootloader unlock (此步將清除手機資料,請詳看 unlock bootloader 訊息),打完就可以看到手機畫面切換為詢問 unlock bootloader ,並透過 Volume +/- 鍵進行選擇切換,並用 Power 鍵確定:


unlock_bootloader


$ fastboot oem unlock
...
OKAY [ 23.924s]
finished. total time: 23.924s


選 YES 後,則將進行 unlock bootloader 並且在 fastboot mode 最下一行顯示紅色的 "LOCK STATE - UNLOCKED" ,代表可以自行安裝(刷機)指定的 OS 啦:


fastboot_unlock


接著就將下載好的 Factory Images for Nexus Devices 解壓縮並擺好位置(在此使用 Factory Images "yakju" for Galaxy Nexus "maguro" (GSM/HSPA+) - 4.1.1 (JRO03C) ,請確認自己手機的狀況),透過一連串的 fastboot 指令進行更新:


$ fastboot flash bootloader /path/yakju-jro03c/bootloader-maguro-primelc03.img
sending 'bootloader' (2308 KB)...
OKAY [ 0.315s]
writing 'bootloader'...
OKAY [ 0.300s]
finished. total time: 0.615s
$ fastboot reboot-bootloader
rebooting into bootloader...
OKAY [ 0.007s]
finished. total time: 0.007s
$ fastboot flash radio /path/yakju-jro03c/radio-maguro-i9250xxlf1.img
sending 'radio' (12288 KB)...
OKAY [ 1.720s]
writing 'radio'...
OKAY [ 1.369s]
finished. total time: 3.088s
$ fastboot reboot-bootloader
rebooting into bootloader...
OKAY [ 0.007s]
finished. total time: 0.007s
$ fastboot -w update /path/yakju-jro03c/image-yakju-jro03c.zip
archive does not contain 'boot.sig'
archive does not contain 'recovery.sig'
archive does not contain 'system.sig'
--------------------------------------------
Bootloader Version...: PRIMELC03
Baseband Version.....: I9250XXLF1
Serial Number........: #################
--------------------------------------------
checking product...
OKAY [ 0.007s]
checking version-bootloader...
OKAY [ 0.008s]
checking version-baseband...
OKAY [ 0.008s]
sending 'boot' (4366 KB)...
OKAY [ 0.589s]
writing 'boot'...
OKAY [ 0.431s]
sending 'recovery' (4708 KB)...
OKAY [ 0.629s]
writing 'recovery'...
OKAY [ 0.500s]
sending 'system' (396675 KB)...
OKAY [ 43.758s]
writing 'system'...
OKAY [ 38.104s]
erasing 'userdata'...
OKAY [ 0.292s]
formatting 'userdata' partition...
Creating filesystem with parameters:
        Size: 14539534336
        Block size: 4096
        Blocks per group: 32768
        Inodes per group: 8144
        Inode size: 256
        Journal blocks: 32768
        Label:
        Blocks: 3549691
        Block groups: 109
        Reserved block group size: 871
Created filesystem with 11/887696 inodes and 97200/3549691 blocks
sending 'userdata' (137559 KB)...
writing 'userdata'...
OKAY [ 28.911s]
erasing 'cache'...
OKAY [ 0.013s]
formatting 'cache' partition...
Creating filesystem with parameters:
Size: 452984832
Block size: 4096
Blocks per group: 32768
Inodes per group: 6912
Inode size: 256
Journal blocks: 1728
Label:
Blocks: 110592
Block groups: 4
Reserved block group size: 31
Created filesystem with 11/27648 inodes and 3566/110592 blocks
sending 'cache' (8832 KB)...
writing 'cache'...
OKAY [ 2.715s]
rebooting...


finished. total time: 116.000s


如此一來,手機重開機後,就會是 Android 4.1.1 囉!先測試一下打電話、接電話的基本功能吧!


最後,我還是習慣把手機的 bootloader lock 起來 XD 一樣關機後,同時按住 "Volume + 鍵" 、 "Volume - 鍵" 和 "Powert 鍵" 一會兒,進入 fastboot mode 後,透過指令進行:


$ fastboot oem lock
...
OKAY [ 0.165s]
finished. total time: 0.165s


收工。


一開始只是單純想要手動升到 Android 4.1.1 ,後來發現連拍照聲音也都解決了 XD 只能說剛好買到的 Galaxy Nexus 可能要拿去賣給亞洲(日本?)吧,所以有些地區有規定手機拍照一定要有聲音(防偷拍)。透過這次的系統更新,之後應該可以等 Google 第一波作業系統就升級了吧,不再需要等 SAMSUNG 囉~


2012年8月10日 星期五

[CSS] 使用 CSS Multi-column Layout Module 實作自動分頁

CSS Multi-column Layout Module (html pagination)


兩年前在 Monocle EPUB Reader 看到的作法,今天被朋友問了一下分頁作法,我一時之間也想不起來 XD 只好翻翻以前寫的 HTML EPUB Reader,順便做個筆記吧!


概念是透過 CSS Multi-column Layout Module http://www.w3.org/TR/css3-multicol/ 實作的,假設定一個 DIV 並在裡頭塞滿字,透過設定 [-moz- | -webkit-]column-width = 150px 話,假設瀏覽器視窗為 600px ,那就會一頁看到 4 個 columns 囉。


於是,分頁的作法就是在指定的顯示範圍內,切換指定的 column 而已。


範例:


<html>
       <head>
              <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
              <style type="text/css">
                     #show {
                            position:absolute;
                            height:100%;width:100%;
                            margin: 0;
                            z-index:100;
                            overflow: hidden;
                     }
                     #content {
                            position:absolute;
                            font-size:20px;
                            -webkit-column-gap: 0pt; -webkit-column-width: 1000px;
                            -moz-column-gap: 0pt; -moz-column-width: 1000px;
                            z-index:100;
                     }
              </style>
              <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
              <script type="text/javascript">
                     function windowResize() {
                            var window_width = $(window).width() - 20;
                            var window_height = $(window).height() - 50;
                            window_width += 'px';
                            window_height += 'px';
                            $( '#show' ).width( window_width).height(window_height);
                            $( '#content' ).width(window_width).height(window_height)
                            .css( '-moz-column-width' , window_width ).css( '-webkit-column-width' , window_width );
                     }
                     $( window ).resize( function() {
                            windowResize();
                     } );
                     $( document ).ready( function() {
                            windowResize();
                            $('#prev').click( function() {
                                   //console.log('prev');
                                   var obj = document.getElementById('show');
                                   if( obj.scrollLeft > 0 )
                                          obj.scrollLeft -= $('#show').width();
                                   else
                                          obj.scrollLeft = 0;
                            } );
                            $('#next').click( function() {
                                   //console.log('next');
                                   var obj = document.getElementById('show');
                                   if( obj.scrollLeft < $('#show').width() )
                                          obj.scrollLeft += $('#show').width();
                                   } );
                                   setTimeout(function() { window.scrollTo(0, 1) }, 100);
                     } );
              </script>
       </head>
       <body>
              <button id="prev">Prev</button><button id="next">Next</button>
              <div id="show">
                     <div id="content">
                            <p>大量文字</p>
                     </div>
              </div>
       </body>
</html>


[Linux] 使用 Dropbox Command Line @ Ubuntu 12.04 server

今天看到一篇文章談論關於 team 合作的模式,其中提及 Dropbox 的地位,例如大家組隊參加比賽,在比賽過程中有不少工作的委派跟追蹤,這時候該如何進行?其中有一個微小卻很重要的就是檔案的交換,這時候使用 dropbox 共享某個目錄就顯得很方便,甚至大家可以自定 filename 或 dirname 當做一個 notification,經由 dropbox 同步功能、通知功能就方便達成啦!


講了那麼多,我只是要用在虛擬機器上 XDD 這樣機器掛了,至少一些工作的檔案或記錄,可以有多幾版本 sync 到 dropbox 啦,以免哪天機器突然下線欲哭無淚。申請 dropbox 免費帳號 2GB 空間實在很夠用了!更可每一台虛擬機器申請一個帳號(可避免關鍵帳密擺在虛擬機器上),接著常用帳號分享目錄給各台的功能。此外,搭配 GMail 又可以放大絕(YourAccount+VM1@gmail.com)。另外,在工作站上,又可以直接開很多個 user 跑 dropbox 喔。


設定 Dropbox @ Ubuntu 12.04 64bit server:


$ wget -O dropbox.x86.tar.gz "http://www.dropbox.com/download/?plat=lnx.x86"
$ tar -xvf dropbox.x86.tar.gz
$ mv .dropbox-dist/ ~/
$ ~/.dropbox-dist/dropboxd
/home/user/.dropbox-dist/dropboxd: 10: exec: /home/user/.dropbox-dist/dropbox: not found
$ file ~/.dropbox-dist/dropbox
/home/user/.dropbox-dist/dropbox: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, stripped
$ sudo apt-get install ia32-libs
$ ~/.dropbox-dist/dropboxd
This client is not linked to any account...
Please visit https://www.dropbox.com/cli_link?host_id=xxxxxxxxxxxxxxxxx&cl=en_US to link this machine.



Client successfully linked, Welcome Bbs!


如果 OS 環境也是 64Bit 的,那就跟我一樣安裝一下 ia32-libs 即可,當執行 ~/.dropbox-dist/dropbox 時,顯示 This client is not linked to any account... 並給予一支 url 時,就只需開瀏覽器去瀏覽那個 url ,並用你將綁定在機器的帳號登入即可,如此一來,成功後會顯示 Client successfully linked, Welcome Bbs! 訊息。


經由上述流程後,已經設定好 dropbox command line 的使用了,在家目錄可以看到 ~/Dropbox 跟 ~/.dropbox 兩個目錄,其中 ~/Dropbox 就是用來同步的目錄,而 ~/.dropbox 則是綁定帳號的相關資訊,如果要用其他帳號來綁定的話,請刪掉這兩個目錄吧。


設定一下開機自動啟動:


網路上一堆人參考 http://wiki.dropbox.com/TipsAndTricks/TextBasedLinuxInstall/UbuntuStartup 和 http://wiki.dropbox.com/TipsAndTricks/TextBasedLinuxInstall 等等,但我現在都連不上無法看原始的 script


故暫時參考 modified script from here http://wiki.dropbox.com/TipsAndTricks/TextBasedLinuxInstall/UbuntuStartup,這 script 做的事就是找出有哪些 user 的家目錄中有 ~/.dropbox-dist/dropbox ,找到後把它跑起來,如此而已。而這個修改的版本嘛,還滿通用的,只需設定一個 group 名為 dropbox ,並把機器上使用的帳號加入此 group 即可,無需修改 script 囉。


$ sudo cp dropbox-script /etc/init.d/dropbox
$ sudo chmod +x /etc/init.d/dropbox
$ sudo /etc/init.d/dropbox status
Status of dropbox ...
$ sudo update-rc.d dropbox defaults 
Adding system startup for /etc/init.d/dropbox ...
/etc/rc0.d/K20dropbox -> ../init.d/dropbox
/etc/rc1.d/K20dropbox -> ../init.d/dropbox
/etc/rc6.d/K20dropbox -> ../init.d/dropbox
/etc/rc2.d/S20dropbox -> ../init.d/dropbox
/etc/rc3.d/S20dropbox -> ../init.d/dropbox
/etc/rc4.d/S20dropbox -> ../init.d/dropbox
/etc/rc5.d/S20dropbox -> ../init.d/dropbox
$ sudo /etc/init.d/dropbox start
Starting dropbox...
$ sudo /etc/init.d/dropbox status
Status of dropbox ...
dropboxd for USER username: running (pid #####)


最後,如需要更豐富的 dropbox 運行資訊,可以試試 http://www.dropbox.com/download?dl=packages/dropbox.py 這隻程式吧。


2012年7月18日 星期三

Android 開發教學筆記 - 使用 Thread 和 Handler 的差別

簡單的說,不需 UI 更新的,可以挑 Thread 來使用,需要動到 UI 的操作的,請用 Handler 的方式處理。