認真說的話, 這也算不上啥非官方API, 算是一個為了抓取Play store上資訊的一個小小工具: PlaystoreUtil

現在很多網路的服務, 大多有提供開放的REST API來供人寫原生的程式使用, 當然也有非常多並沒有, 像是Play store, 目前就沒開放的API可供存取, 剛好想要有個東西可以查詢某個app在play store上是屬於啥分類的, 所以就乾脆自己自製一個囉…

現在的網頁, 大多結構性很好, 所以就算沒有REST API, 其實也不難處理, 搭配上 jsoup , 可以說輕而易舉

jsoup是一個可以用css selector來解析html的Java函式庫, 有了這個, 解析html可以不用辛苦的爬dom tree, 只要幾行簡單的程式即可:

Document doc = Jsoup.connect("http://example.com/").get;

Elements links = doc.select("a[href]"); // a with href
Elements pngs = doc.select("img[src$=.png]");

再來看看play store

先看看每個app的資訊畫面, 以Facebook為例, 它的url是 –

https://play.google.com/store/apps/details?id=com.facebook.katana&hl=ja

很明顯的, id後面是package name, 另外如果加上"&hl=“可以指定語言, 然後再看到頁面上:

在Facebook (公司名稱)下方有個分類, 可以使用Chrome的開發人員工具(我比較習慣這個), 找到這個連結的css class名稱是”document-subtitle category“,而名稱則在它底下的一個span, 這span有個屬性itemprop, 值是genre

因此, 透過以下這段code就可以取到類別名稱囉

Document doc = Jsoup.connect("https://play.google.com/store/apps/details?id=" + packageName + "&hl=" + locale.getISO3Language()).get();
Elements elements = doc.select("span[itemprop=genre]");

當然, 這方法不只適用於play store, 其他網頁也可以嘗試用這個方法來取得資料

詳細的範例在: https://github.com/julianshen/PlaystoreUtil

Android library project是為了解決Android開發中在不同專案間分享原始碼以及資源檔(resource)而出現的, 傳統的jar並未考慮資源檔的問題, 因此便需要靠Android library project來解決

目前, Android library project已經被廣泛運用, 舉凡ActionbarSherlock, Facebook Android SDK, 很多都已採用這形式

不過現在一般用法還是比較廣泛應用在跟UI相關這類的應用上, 這也合理, 這類的應用常需要包含原始碼和資源檔, 不過它也適合在其他應用上, 舉個例子(好吧, 這例子有點不清不楚), 我們也有可能需要讓所有使用某個library project的應用程式自動加上一個Intent Receiver, 假設這receiver實作上是固定的, 並不需要使用的應用程式自行去繼承, 或是, 我們希望某個Activity的實作是被連結到各個應用程式中, 這類應用使用Android library project也是可以辦到的

這類的應用, 通常還需要在AndroidManifest裡宣告, 除了receiver, activity, 也有可能加上一些service, 甚至是permission, 正常來說, 在建置使用了Android library project的專案時, library project裡的AndroidManifest的內容並不會合併到最後的AndroidManifest裡, 以致於, 雖然在library project內這些都被宣告了, 但成品內可能無法被使用, 這解法也很單純, 只要在應用程式(不是library project)的project.properties裡加上:

manifestmerger.enabled = true

Manifest merger似乎存在有一段時間了, 但似乎也沒看到啥正式的官方文件, 不過目前這方法是可行的就是了

我家裡的電腦是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

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

昨天去了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

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

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

這篇主要來自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);
        }