[Android] 地點自動完成 Google Places Autocomplete API

Google Place API 是 Google Map API 成員之一,結合地點與商家資訊,提供用戶指定地點附近的資訊,市場上同類的 API 還有 YelpFourSquare

Google Places API

目前 Android 支援的 Google Place API 共有三大功能:
  • 地點挑選器(Place Picker):在地圖上顯示挑選地點附近的商家資訊
  • 目前地點(Place Detection):自動偵測目前所在位置,並顯示附近商家
  • 地點自動完成(Place Autocomplete):輸入部分地點字串後,會回傳符合條件的相關地點資訊,可以搜尋商家名稱、景點、地理位置(例如國家、城市)等資訊
要使用 Google Place API,必須從 Google Developers Console 註冊 Google Places API for Android 的 API Key,Android API 的流量限制是每天 1000 筆請求,超過就要計費。

把申請好的 API Key 加入 AndroidManifest.xml
<application...>
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="xxxxxxxxxxxxxx"/>
        </activity>
</application>

然後加入 Google Play Services 套件
compile 'com.google.android.gms:play-services-places:9.x.x'

Google 的 GitHub 上,有 Google Places API for Android 的範例程式 可參考!

地點自動完成

Google Places API 本身有 Rest Web Service,然而 Android 版本的 API 已經做了包裝,不需要再做網路請求與解析 JSON 資料的動作,這些 API 都已經幫我們做好了。

先增加一個 AutocompleteTextView Layout
<AutoCompleteTextView
    android:id="@+id/autocomplete"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:hint="@string/search_city_hint"
    android:singleLine="true" />

在程式的部分,新建一個 Google API Client
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
                .addApi(Places.GEO_DATA_API)
                .build();

然後需要一個 PlaceAutocompleteAdapter 作為資料顯示的容器,程式碼可以從 Google 範例程式取得,可以直接複製使用。
如果想限制自動完成的結果,可以定義 AutocompleteFilter,再將其傳入 PlaceAutocompleteAdapter,下面的範例是只顯示「城市」。更多篩選類型可參考 Google 文件
AutocompleteFilter filter = new AutocompleteFilter.Builder()
          .setTypeFilter(AutocompleteFilter.TYPE_FILTER_CITIES)
          .build();

adapter = new PlaceAutocompleteAdapter(this, android.R.layout.simple_list_item_1, googleApiClient, null, filter);

以下是執行的結果,也可輸入中文,Google 會自動根據裝置的語系,回傳相對應的名稱。

以下是完整的程式碼

分類:

銀河便車指南

「銀河便車指南」,英文原名「The Hitchhiker's Guide to the Galaxy」(簡稱 H2G2),是英國作家道格拉斯 - 亞當斯(Douglas Adams)在 1979 年間發表的科幻小說,全書共六個系列。這本書的故事情節在 2005 年被拍成電影「星際大奇航」,BBC 也在 1981 年推出電視劇。這本書曾獲得英國 BBC「大閱讀」票選第四名。

分類:

[Android] LeakCanary 檢測記憶體洩漏的工具

在 Android 開發的過程中,時常會遇到某些狀況(通常是網路或資料庫存取),導致物件要作的事情完成了,但沒有正確被回收掉。此時,這個沒被回收的孤兒,就會佔用記憶體,造成記憶體洩漏,也就是一般常說的 Memory Leak。發生 Memory Leak,會發生效能問題導致 Out of Memory、造成 Force Close、甚至可能造成安全問題。

過去在 Eclipse IDE 時代,Eclipse 有推出一個叫做 MAT 的記憶體分析外掛,搭配 Android DDMS 來檢測記憶體洩漏的問題。

在 Android Studio 的時代,Square 這間公司(沒錯,就是推出 okhttpRetrofitPicasso 等一系列知名函式庫,也是大神 Jake Wharton 任職的公司)推出了 LeakCanary 套件,直接安裝在 App 上,藉由在測試環境,以 debug 模式來找出程式中記憶體洩漏的問題。

首先,在 build.gradle 引入下面三個套件,它會藉由 Gradle 的特性,在不同的建置方式,會抓不同的套件。這樣就可以,只在 debug 時正常安裝 LeakCanary 套件,而在 release 到正式環境時,安裝另一個不執行 LeakCanary 檢測的套件。
dependencies {
   debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
   releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
   testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
 }

然後在 Application 加上一行程式碼。就這樣,夠簡單吧!
public class ExampleApplication extends Application {

  @Override public void onCreate() {
    super.onCreate();
    LeakCanary.install(this);
  }
}

因為 LeakCanary 只在 debug 模式下執行,因此只能在模擬器執行,要在實績執行的話,則要用 Android Studio 包裝不含 sign 的 debug apk 檔,然後手動安裝到實績上。

將 App 安裝在模擬器之後,LeakCanary 會自動安裝一個叫做 Leak 的 App 在模擬器上,之後,在手動測試 App 的過程中,如果 LeakCanary 檢測到記憶體洩漏,除了會以通知方式呈現之外,也會將檢測結果紀錄在這個 App 上。

如果 LeakCanary 檢測到記憶體洩漏,會如下畫面以圖形方式將結果呈現(圖片取自官網)。

正常來說,LeakCanary 只會在 debug 模式下執行。因此要將 App release 上架,可以放心的使用 release 來建置 apk。如果還是擔心 LeakCanary 會在正式環境執行,造成用戶困擾的話,也可以在建置之前先把相關程式移除,反正只有一行程式碼。

關於 Leak Canary 的教學與說明,可觀賞 用 LeakCanary 检测内存泄漏 影片(內附中文翻譯)




分類:

如何將電腦畫面經由 Chromecast 投放到電視螢幕上

Chromecast 一般常用的方式,是將手機或平板上的影音投放到電視上。然而 Chromecast 本身也可以投放電腦或筆電的螢幕,小小一台裝置,其實用途很多。

首先要安裝 Chrome 套件,到「Chrome 線上應用程式商店」安裝「Google Cast」這個套件。

安裝之後,Chrome 工具列會多出一個 Chromecast 的投放圖示。

在 Chromecast 已安裝在電視上,並開啟的狀態下,按下投放圖示。

然後按下投放圖示下方的箭號,選擇「投放螢幕 / 視窗 (實驗性)」,此功能目前仍在實驗階段,但使用沒什麼大問題,而且 Mac 和 Windows 都能使用。

選擇要投放的 Chromecast 裝置。

然後選擇要投放電腦全部畫面,或單一開啟的視窗。

投放的過程中,若選擇單一視窗,你的電腦仍可進行其他操作。如果選擇的是整個畫面,則你在電腦上的全部操作,都會反映在投放的電視上,然而 Chromecast 使用的是非同步技術,電腦畫面操作太快的話,電視上會有一點點的延遲。

投放過程中,Chromecast 圖示會亮藍色


只要按下下方浮動視窗的「停止共用」,則可停止投放


然而此種投放方式不會將聲音 Stream 到電視,電視會聽不到電腦的聲音。因此將電腦播放的 DVD 投放到電視時,會呈現只有影像沒有聲音的狀況。要解決這個問題,必須先將 DVD 轉檔成其他的影音格式(MP4、AVI、MOV、RMVB 等格式),然後安裝另一個 Chrome 套件「Videostream for Google Chromecast」,使用這個套件來播放影音檔。

如果工作場合的會議室有電視的話,Chromecast 也可以用來播放電腦的簡報。不過 Chromecast 允許加入相同 Wifi 的裝置都能投放,沒有密碼保護,容易造成投錯電視的窘境。另外,因為 Chromecast 價格不貴,平常習慣使用雙螢幕工作的工程師,倒也可以自己買一台接到電腦螢幕甚至電視上,反正現在 LCD 螢幕都支援 HDMI 了。





分類: ,

系統的監控機制

在開發系統時,工程師都會寫 Log 來除錯,當系統上線到正式環境之後,也會將 Log 模式開啟,如果系統發生錯誤,才能將錯誤訊息寫入 Log 檔,方便日後追蹤。工程師通常很忙,不會沒事去看 Log 檔,而是用戶回報系統出問題時,才會打開正式環境的 Log 檔追查問題。

只是,當用戶告知系統出問題時,通常已經是緊急狀況,而如果系統架構龐大又複雜,那麼如何知道要追查哪些 Log?即便對系統架構很熟的工程師,也不一定能在短時間內找出問題根源。

當然我們都知道,可以透過自動化的方式來監控系統的異常狀況。不過,這個需求提出後,通常會被老闆或 PM 打槍,因為他們認為人力投入到系統開發都來不及了,這些沒有產值的需求, 其 Priority 都是非常低。而且系統出問題,都是工程師倒楣,不會是老闆和 PM 在處理,他們不會痛。

到最後,都是工程師默默地花自己的時間,建置 Log 監控工具(例如 ELK),或者用土法煉鋼的方式,寫工具來監控 Log 檔。這些工具一般是用腳本語言(Scripting Language)寫的,例如 Python 或 PowerShell,如果工程師不會寫腳本語言,請趕快學,Ruby 語言發明人松本行弘,曾經建議工程師不管會幾種程式語言,至少要學會一種腳本語言,我想就是這個原因吧。

除了 Log 的監控之外,正式環境基礎建設的健康狀況,例如 CPU 使用率、記憶體與磁碟空間使用量、Ping 值與網路狀況等,更是要嚴密監控,這些相關的監控工具,可以導入市面上的監控軟體,或者自行寫程式監控。

火災警報器的功能,是偵測到煙霧當下,警報器就會響。如果沒有裝設火災警報器,可能你家火燒厝都還不知道。系統的監控機制也是一樣的道理,當正式環境有錯誤發生時,不管有沒有影響到前端用戶的使用,我們都可以及早知道,然後迅速處理,並防範未然。尤其是一個功能剛釋出到正式環境後,更是要密集監控,雖然在釋出前一定會在測試環境測試過無數次,但畢竟正式環境在配置上還是不同於測試環境,甚至有些詭異的錯誤,只會發生在正式環境。

通常,因為人力和成本的關係,系統監控機制不會一步到位,而是逐步建置,依 80 / 20 法則,較可能出問題的點要先做監控。系統監控的覆蓋率和找到問題根源的時間之關係如下圖,一般來說,覆蓋率越高,當系統異常發生時,越能在短時間內找到問題的根源,進而修正。


我以前曾經管理過一百多台的 Windows Server,系統架構錯綜複雜,不可能一台一台人工檢查,最後本著「做好自動化,遠離肝硬化」的精神,自己寫工具監控 Log 檔,每天把可能有問題的 Log Report 寄出,再用肉眼辨識這些錯誤訊息會不會影響到正式環境的運作,然後再跟工程師討論如何修正。

我把之前自己寫的監控工具放在 Github ,有興趣的朋友可以參考使用。這是用 PowerShell 寫的,只能運行在 Windows 上,並監控 Windows Server。





分類:

[Android] Google Map InfoWindow 的自訂

使用 Google Map 預設的 InfoWindow,如果 InfoWindow 內的文字很長,不但文字無法換行顯示,過多的文字也會被截斷。例如下面這張圖,snippet 的部分文字被截斷了。

要解決這個問題,可以自訂一個 Adapter 來實作 GoogleMap.InfoWindowAdapter

InfoWindowAdapter 提供兩個 Method:getInfoWindow 和 getInfoContents,我們可以自行定義新的 Layout,然後覆寫 getInfoContents。因為 Layout 是自訂的,不但可以修改文字顏色和大小,還可以放圖片。

底下是完整的程式碼
修正後,新的 InfoWindow 長這樣,使用 \n 換行符號可強制文字換行。




分類:

[Web] 使用 Clipboard.js 實作「複製文字到剪貼簿」的功能

以往要在網頁上實作「將文字複製到剪貼簿」,所使用的 JavaScript 函式庫(例如 ZeroClipboard,聽說 ZeroClipboard 2.x 版有改寫成不使用 Flash,但我沒用過),多半都會輔助 Flash 來達到此目的。可是 Flash 不支援多數的手持裝置,且因為安全性的因素,多數的主流瀏覽器已經計畫不再支援 Flash。

這篇文章要介紹一個純 JavaScript 函式庫 Clipboard.js

先說結論,Clipboard.js  使用了一個尚未被多數瀏覽器支援的 JS 函式 execCommand,目前這個函式庫支援新版的 Chrome 和 Firefox,且僅支援 IE 9 以上的版本,以及 Safari 10 以上的版本(Safari 10目前還沒正式推出)。

以下是範例

分類:

[Android] 新版 Firebase 函式庫

今年五月,Google 推出新版 Firebase 函式庫,這是 Firebase 合併到 Google 之後最大的改版,新版 Firebase 函式庫最大的特色是,以既有的雲端平台來蒐集 APP 的分析資料,進而增進 Admob 廣告收益。Firebase 被 Google 定位為 Mobile App 的專屬平台,除了原有的儲存和即時資料庫之外,還增加了分析、廣告、推送(Cloud Message / Notifications)、認證、當機報告、Remote Config、Invites / Dynamic Links、App Indexing 等功能。最重要的是,分析紀錄的儲存無上限,而且只要加入分析函式庫,不用改程式,就能自動收集預設的事件。
細節可參考下面的投影片。
此次的改版證明了 Google 會持續強化 Firebase 的服務,不必擔心 Firebase 會跟隨同樣是 PaaS 的 Parse.com 停止服務。

最近測試了新版的 Firebase Analytics、Crash Reporting、AdMob 這三個函式庫,以下依順序介紹。

前置作業

要安裝新版  Firebase 函式庫,要將 Google Play Services 升級到版本 30 以上,並將 Google Repository 升級到版本 26 以上。

另外,在 Android Studio 的  Project Structure 可導入 Firebase Android Client API,勾選後會自動增加 INTERNET 權限,並新增 firebase-client-android 函式庫,此函式庫為雲端儲存之用,若無此需求,可不需導入。

新增 Firebase 專案

接著到 Firebase 網站,新增一個新的 Android 專案。新增的過程中,需要輸入 Android 的 Package Name,至於 SHA-1 可不填,系統會自動產生。

Firebase 會根據 Package Name 自動生成一個檔名是 google-services.json 的設定檔,這是一個內有 Firebase 帳號和 API 資訊的設定檔,請將這個檔案複製到Android Studio 專案資料夾的  app 目錄下。

最後將指定的套件名稱新增到專案層級和 app 層級的 build.gradle,要注意的是,apply plugin: 'com.google.gms.google-services' 要放在最後一行,否則編譯時會出錯!

Firebase Analytics

將下面這行加入 build.gradle,不需額外程式碼,Firebase Analytics 就能蒐集預設的事件了
compile 'com.google.firebase:firebase-core:9.6.0'
如果要蒐集自訂的事件,可參考 Firebase 文件

Firebase Analytics 和 Google Analytics 兩套產品是獨立運作的,如果 App 原本已經使用 GA,增加 Firebase Analytics 不影響 GA 的使用。

Crash Reporting

將下面這行加入 build.gradle,不需額外程式碼,App 當機時會自動發出當機報告,約莫 2 分鐘後當機報告就會出現在 Firebase Console。
compile 'com.google.firebase:firebase-crash:9.6.0'

和Android 預設的當機報告不同的是,Android 的當機報告是用戶同意才會發送,因此在 Google Play Console 沒有顯示當機報告,不代表一定沒有 Crash 發生,常常是用戶沒有主動回報。Firebase 的當機報告則不需用戶同意,當有 Error 發生時,就會自動發送。

這張圖是 Firebase Crash Report 在網頁上顯示的效果,這裡可以看出錯誤是 OutOfMemoryError,這其實是 Volley 沒有用 Singleton 導致記憶體用量過高所造成的,哎呀,我的眼睛業障重啊!

AdMob

Firebase 官方文件對於 Firebase Admob 的說明是「建議使用,但可選擇的」(Firebase is recommend, but optional),意思是原本已經使用 Google Play Service 的Ads 函式庫的專案,不必改換成 Firebase Admob 函式庫(因為兩者的程式碼、package name、class name 是一樣的),但是 Google 建議更換成 Firebase Admob 函式庫,畢竟 Google 已經逐漸將 Mobile App 的重心移往 Firebase 平台。

如果要使用 Firebase Admob 函式庫,需將下面這行加入 build.gradle, 若 App 原先有使用 Google Play Service 的 ad 函式庫com.google.android.gms:play-services-ads,最好將其移除,既有的 Admob 程式碼不需修改。
compile 'com.google.firebase:firebase-ads:9.6.0'

接著到 AdMob Console 的 Analyze 功能,選擇要連結 Firebase 的 App,點選「Link to Firebase」連結,將 App 與 Firebase 專案關聯。
此時選擇已存在的 Firebase 專案(也可自動建立一個新的 Firebase 專案,然後接著按照下面的說明,先下載一個 json 格式的設定檔,然後將 Firebase SDK 整合到你的 App)

最後要注意的是,如果 App 有使用 Google Play Services 函式庫,這些 Firebase 函式庫的版本號要和 Google Play Services 版本號一致,否則編譯時會出錯。

Google 最近一直在推廣 Firebase,有興趣的朋友可以關注 Firebase 的 Twitter 帳戶,內有教學影片。

分類: , , ,

Copyright © Andy Cheng

Distributed By My Blogger Themes | Blogger Theme By NewBloggerThemes Up ↑