2021 iThome 鐵人賽 Day 1:Intro

本篇文章是 2021 iThome 鐵人賽參賽題目「寫一個列車抵站時間 Android App」的第 1 篇,你可到 iThome 查看原文。 文章目錄 早陣子(2021 年 6 月 27 日)港鐵屯馬綫全綫通車,當日有電視台訪問了一名鐵路迷,他受訪時調寄家傳戶曉的英國民謠《綠䄂子》即興唱了一句自創歌詞「屯馬開通真的很興奮」。那我們就以港鐵實時列車抵站時間做例子,示範一些現在 Android 開發流行的東西。 App 會有兩頁:選擇車站頁和抵站時間頁。選擇車站頁就是列出某條行車綫的車站,讓用戶點選查閱該站的列車抵站時間;抵站時間頁就是顯示某行車綫及車站的列車抵站時間。 ...

September 16, 2021

文字末端 icon 排版

以前試過做一些 UI 是 TextView 旁邊有一個 icon,然後同一行最右邊會有另一個 Button。如果文字過長就加上省略號,但文字不夠長的話 icon 要緊貼那個文字而那個 Button 就固定在右邊。TextView 有 compound drawable,但如果想那個 icon 有 click listener 又用不了。所以最後都要分開 TextView 和 ImageView/ImageButton 兩個 view。 ...

April 10, 2021

Android SMS Verification APIs

SMS 驗證應該是一個在 Android app 頗為常見的需求。一般做法都是先讓用戶填寫電話號碼,然後 app 會把電話號碼交到 backend 再透過 SMS gateway 發送含有驗證碼短訊, 當用戶收到 SMS 後再把內文的驗證碼輸入到 app 中。如果想省卻用戶輪入文字的話有一些 app 會透過 READ_SMS 權限讀取 SMS 內容來抽取驗證碼,但 Google Play 已經限制非預設短訊 app 不可以有 READ_SMS 權限。 ...

March 14, 2021

Notification Channel 自訂音效

自從由 Android 8 開始,如果要顯示 notification 的話就一定要指定一個 notification channel,否則系統不會顯示。Notification channel 的目的是讓用戶能自行調節 app 的各式 notification 的提示方法,例如有沒有音效、會不會彈出 heads-up notification 之類。如果 app 想自訂 notification 的聲音亦都要經 notification channel 設定(但用戶可以之後自行變更 notification channel 的音效) ...

March 13, 2021

Jetpack DataStore 搭配 kotlinx.serialization Protobuf

上月 kotlinx.serialization 出了 1.0 版。除了支援 JSON 之外,還有支援 Protocol Buffers (Protobuf),而且還是跨平台支援。而在前一個月 Android 出了 Jetpack DataStore,它是一個用來取代 SharedPreferences 的 library。它有兩種用法: ...

November 14, 2020

Java 量度單位 (JSR 363 Units of Measurement API)

在日常生活中,我們都會用到不同的量度單位。例如重量有時會用公斤 (kg),有時會用磅 (lb),有時又會用斤之類。如果在 Java 上表示這些數值,用 int、float、double 的話有時會令人理解錯誤,就好像 UNIX timestamp 般一時會用秒一時會用毫秒。為防止人們誤解這個 variable 或 method 的時間單位,通常都要在名稱加上 millis 之類的後綴。知名例子有 System.currentTimeMillis。如果處理時間的話,現成的有 TimeUnit。不過如果去到之前的重量單位的話,JDK 就沒有現成的 class。 ...

August 13, 2020

Moshi Kotlin Codegen + R8 出現 parameter type is null

Moshi 是一個 JSON serialization/deserialization 的 library。和 Gson 不同的是它提供了 Kotlin Codegen,它可以生成 serialization/deserialization 的 adapter class,所以可以避免使用 reflection,而且 adapter 還會參照 Kotlin 的 non-null 和 default value。不過最近發現 production app 會出現 parameter type is null 的錯誤訊息。 ...

March 15, 2020

Firebase Crashlytics 的 CrashlyticsOrgIdException 解決方法

最近為自己的 app 加入 Firebase Crashlytics SDK beta(即是使用 Google 的 Firebase Crashlytics Gradle plugin 而不是用 Fabric 那個),但在 build release APK 時出現下面的錯誤: java.io.IOException: com.google.firebase.crashlytics.buildtools.exception.CrashlyticsOrgIdException: Could not fetch Crashlytics Org Id > com.google.firebase.crashlytics.buildtools.exception.CrashlyticsOrgIdException: Could not fetch Crashlytics Org Id > Could not fetch Crashlytics Org Id > Unable to fetch Crashlytics Org Id using app id 1:731121766578:android:4e799392a2e62811 我的 app 是在 Firebase 開了兩個 project,一個是開發時用的,另一個是 production 用的。但只有 production 才有這個錯誤。如果把 release build 設為不上載 ProGuard/R8 mapping file 的話就不會有這個錯誤。 ...

March 14, 2020

Firebase Cloud Messaging

最近工作需要做 Firebase Cloud Messaging (FCM) 整合,發現了向 Firebase API 直接送出 push 的 HTTP request 都可以生成不同種類的 message。 如果要整合到 Android 的話,需要建立一個新的 Service class 並繼承自 FirebaseMessagingService。這個 Service 有一個叫 onMessageReceived 的 callback method 來接收來自 FCM 的 push 和它的 payload。但原來不是所有的 push 都能被那個 callback 接到,要視乎 push 的種類和你的 app 當時在甚麼情況而定。 ...

February 29, 2020

Android App Icon 規格

一個 app 的第一印象應該是它的 app icon (launcher icon)。在 Android,在不同的時期前後出了好幾個 app icon 規格。但是 Android 介紹不同種類的 app icon 的文件放得非常分散,如果平時沒有一直留意的話都幾乎肯定會做錯或者做漏。以下是全部 Android app 都會用到 app icon: ...

July 20, 2019