Google I/O 2016 結束一段時間了,今年總共放出 影片 182 部 ,其中和 Android 相關的 影片有 65 部 ,為了要快速了解今年本部門的守備範圍內有哪些新東西,大家分著把影片看過一輪後再與彼此分享,順便各自寫了些摘要分享出來給國內的 App 開發者們。
Android at Google I/O 2016 上集
Android at Google I/O 2016 中集可以幫助獨立遊戲製作去處理一些沒有能力處理的細節,常運用的如下:
Pre-registration:可以讓用戶做預先註冊,當遊戲正式釋出的時候便能立即通知用戶安裝,有助於第一時間便有使用量,並且這些初期用戶的忠誠度通常會較高。
Gamer ID:現在可以建立一個不帶個人資料的 game id 專門使用於遊戲登入,且可以自訂頭像,不再需要使用 google+ 帳號。
Video Recording API:需求 Android 5.0 以上,且手機需安裝最新版的 Play Games,簡單便可以實作遊戲歷程錄製及分享,可以幫助散播遊戲知名度。
Player Stats API:可以分析使用者行為分類為重度課金客戶或有可能不玩了,開發者可以做出相應的特殊應對,也可以對好幾天沒玩的用戶做出通知以吸引他回歸。
In-app Promotion支援 promo codes,可以在 Play 或遊戲中輸入。
為了改善 ListView 以下問題,進而衍生出 RecyclerView:
– 有很多 long tail features 導致衍生出 ListView 未定義的行為
– 重覆的功能,如:item click listener or view click listener?
– Animation 困難
– 越來越複雜的 ListView item
RecyclerView 有三個主要的元件分別如下,而 RecyclerView 本身則是各個元件中樞:
1. Layout Manager:負責整個 RecyclerView 各個 item 的排版,可以是 Linear, Grid, Straggered Grid, RecyclerView 並不知道每個 item 的位置,因此在滑動的時候由 RecyclerView 接收手指的動作,再告訴 Layout Manager 滑動,當畫面需要更多的 item 時也是由 layout Manager 提供,除此之外 RecyclerView 只負責提供 item 的基本資訊,這個 item 是屬於標題還是內容等也是交給 Layout Manager 負責。
2. Item Animator:views 的動畫
3. Adapter:負責創建 view, view holder 以及綁定資料到 view holder 上、通知 RecyclerView 資料改變、處理點擊事件。
每當 LayoutManager 跟 RecyclerView 要指定位置的 item 時,RecyclerView 會先去 cache 內尋找,如果有就回傳,沒有的話就會去跟 Adapter 拿,此時會先去 RecycledViewPool 找看看有沒有同一個 ViewType 的 view holder 可以使用,如果沒有才重新創一個 view holder 不然就會用該 view holder 來綁定所需的資料。刪除和新增也是一樣,都是由 Layout Manager 透過 Recycler View 交給 Adapter 處理,這樣能重覆利用 view holder 並減少 inflation 的花費。
另一種情況是 Layout Manager 因為 Adapter 的資料有改變而重算 layout 時,有些 views 已經沒再使用了,但 ItemAnimator 要加上 fade out animation,所以 RecyclerView 會把每個沒用到的 View 透過 Child Helper 加到一個 ViewGroup,並從 Layout Manager 隱藏起來,再去通知 ItemAnimator 去做動畫,結束後會再通知 Adapter 去做 cache 或 recycle。
對於 view holder 的使用上最重要的是避免被銷毀,當遇到這種情況就會造成效能上的問題,以下列出了一些可能的情況:
以下是 RecyclerView 中其他重要元件
最後的 Tips & Tricks
講者首先對 Accessibility 做一個定義,創造一個任何人都可以使用的產品,接著講者提到了 APPlicable 這個組織,APPlicable 的目的在於幫助 Startups 讓他們的 App 更加適用於任何人,並且 APPlicable 邀請開發者和 Startups 一起發想如何讓盲人和坐著輪椅的人更方便使用他們的 App。
講者從三個面向來講解如何創造一個任何人都能使用的 App
– TalkBack 主要設計給盲人以及有視力損傷的人,透過手勢點按到 UI,TalkBack 可以唸出這個 UI 的敘述,TalkBack 有兩種方式可以導覽,
– Linear Navigation 是當一個元件 被 focus,使用者可以透過滑動,瀏覽附近的元件
– explore by touch 是先 focus 一個元件,使用者按著該元件不放,然後滑動到附近的元件,該元件就會呈現 foucs 的狀態,
接著 TalkBack 就會唸出這個元件的敘述,快速雙擊即可開啟該 App
– BrailleBack,像是一個點字機的裝置,由鍵盤和控制桿所組合,由這個裝置和使用者互動
– Switch Access,主要是設計給坐輪椅的人或者是使用觸控螢幕不方便的人,透過一個擁有兩個大按鈕的裝置,設定一個按鈕是下一步,另外一個按鈕是選擇,就能模擬出像是 Linear Navigation 的方式使用 TalkBack
– Voice Access,可以使用聲音來和裝置做互動,如果開發者想要使用 Accessiblity API,建議一定要測試 Switch Access 和 TalkBack API
– Content Labeling,使用 android:contentDescription 去設定 ImageButton,ImageView and CheckBox 的 label,讓 TalkBack 可以唸出這些元件上的敘述,幫助元件和使用者互動。針對可編輯的 UI 元件,像是 EditText,請使用 android:hint or android:labelFor
– Touch Target Size,設定一個讓使用者能夠輕鬆不費力的就能夠點擊到的大小, 建議大小是大於 48×48 dp,也能延展 View 的邊緣,藉著使用 TouchDelegate
– Contrast,利用對比,讓使用者更加容易分辨出哪些是背景,哪些是可以互動的元件。
– View attributes,在 Layout 中,可以注意以 group 為單位,加上 android:focusable 標籤幫助使用者導覽元件。
Continue developing and testing with Accessibility in mind:講者建議,最好的方式還是使用人為測試,這樣才能模擬那些盲人或行動不便的人是如何操作 App,找出他們使用上的痛點。此外,講者介紹使用 Accessiblity Testing Framework,他是由 Espresso & Roboletric 所整合而成的,可以透過以下方式來開啟 Accessibility 測試,只要在 Setup 中打開 Accessibility.enable() 即可
@Override
protected void setUp() throws Exception {
AccessibilityChecks.enable();
}
Google 提出 Accessibility Scanner,他是一個能夠掃出沒有符合 Accessibility 元件,並且能夠提供建議的工具
提升 App 的評價主要需要做到:
1. 主動提升軟體的品質
2. 傾聽使用者的意見與需求
使用 Firebase 可以讓你很方便的在上線前在真實環境下做很完整的測試,並在短時間內得到結果,在發布新版的時候,你可以選擇發佈給多少使用者,不需要一次部署到全部使用者的裝置,這樣可以減少新產生的問題造成的衝擊,使用 Proguard 的開發者,現在可以把 mapping 檔放到開發人員後台中,這樣你查看問題的時候,直接就可以看到原始的 stack trace。
Firebase Crash Reporting 剛上線,目前完全免費,可以提供 Android 與 iOS 開發者使用,並可以利用 Firebase 來告知發生 crash 的使用者問題的處理狀態,他同樣可以使用上傳的 Progard mapping 檔來產生解混淆的 stack trace。
傾聽使用者意見是很重要的,畢竟使用者總是對的。在正式版還沒有上線前,您可以提供早期體驗版本讓想要試用的使用者測試看看,在體驗階段,使用者可以傳送私人的意見給開發人員,既不會造成評價下降,又可以得到很多寶貴的意見。
在 Rating 跟 Review 的部分,除了可以查看隨時間的變化外,現在可以分別查看不同國家的使用者所給的結果,Review 中新增了 Highlights 可以重點節錄出使用者所給的主要評價,針對使用者所給的 review,您可以將通知打開,以保持對 review 的最近狀態的掌控。Google 提供了 review 的 api,可以得到 JSON 格式的每個 review 資料,不只可以讓您自己設計客戶經驗改進平台,也能整合進現有的管理平臺如 zendesk。
回覆使用者的意見是一件很重要的事,平均來說在開發者回覆後所造成使用者重新評價得到的星星數上升 0.71,是一個令人驚訝的數字。
這是一場極基礎的 Android TV 開發課,和 1、2 年前課程內容差不多,一開始主持人說為什麼會講這堂課,在於他拜訪很多開發者後,發現大多數的人說太忙了,沒空學習 Android TV 如何開發,於是他們決定再次和開發者們強調,開發 Android TV 和開發 Android mobile App 是一模一樣的,它們之間使用相同的 SDK 相同的開發工具,也都有很容易使用的模擬器,只在於 Design guideline 不一致。
開發 Android TV App 的第一項 UI guideline 是必須在 AndroidManifest 中指定 android:banner 且這張圖片上必須要有 App 的完整名稱,原因是 Android TV 的 App 列表不像 Mobile 會在 icon 底下秀出字串,接著如果你想讓 App 執行在 Android TV 上時預設開啟另一個 Activity,可以增加另一個 Activity 但除了在 intent-filter 加上 MAIN 之外,還要加上 android.intent.category.LEANBACK_LAUNCHER 如此就可以做到在 Mobile 上和 TV 各開啟不同的 default Acticity。
大多數的 Android TV Device 沒有電話、觸控功能,所以開發者還必須為 AndroidManifest 加上 android.hardware.touchscreen 與 camera 等硬體功能為 android:required=”false” 的宣告,以免在 TV 的 Google Play 上無法列出此 App。
接下來講者提到以前 smart phone 尚未出現時,我們很習慣用方向鍵操作 UI 與選擇功能,而這就其實就是 Android TV 遙控器操作 TV App 的概念,只要注意 UI Element 的 focusable=”true” 與 android:nextFocusRight, nextFocusLeft 等相對應的元件即可,並不會太複雜。
有些開發者可能會認為電視的 1080p 等像素是固定的,但有些電視廠商會將上、下、左、右保留一些些空間顯示特殊的字卡,如果開發者是用 1080p 的比例在設計 UI 碰到這類螢幕就會遇到邊緣被裁切的狀況,所以畫面的邊緣 5% 盡可能的留 padding、margin 不要放資訊。
接下來講者介紹了 Leanback Library 這個可以讓開發者很快的設計出像 Google Play 這類型 UI flow 的工具,裡面包含了像 BrowseFragment, DetailsFragment, PlaybackOverlayFragment, SearchFragment 等 UI 元件,已經處理好 focus 的順序與列表捲動置中的功能。
在 Android TV 的首頁可以看到很多媒體卡片,在 TV 上叫作 Recommendations 是由各個 App 發送出來的,實作方式非常的簡單就和一般的 Notification 差不多,但需要注意的是如果太常將用戶沒興趣的資訊發送到首頁上,可能導致用戶更快程除應用程式,講者建議參考用戶的行為發送有相關的,例如他感興趣影片的下一集。
而將 Android TV App 開發好後即將面對的就是上架,在上架時如果你的 AndroidManifest 有 leanback 的宣告,就可以勾選此應用程式為 TV App,送出後 Google Play 會審核這個 App。
這篇在談論 Android Transition API 如何幫助你寫滑順的轉場動畫。首先轉場動畫是如何做的呢?在兩個場景之間必須先描述要在動畫中移動的元件,讓系統捕捉之後,接著定義動畫的樣式,Transition 會在兩個場景間自動過渡先前描述的元件。
在 API 19+ 加入了幾個有用的 API,如 ChangeBounds API,能幫助我們移動或調整 View 的大小,不需要透過 RequestLayout 來重繪畫面,那非常耗效能;Fade API, 提供淡入淡出的過渡顯示;AutoTransition API 則集了前述兩個 API 的大成,能同時做淡入淡出及移動位置、改變大小的轉變。
API 21+ 之後,又新增了一些相關的 API,Slide API,可以從邊緣進入或離開畫面;ChangeClipBounds 可以調整動畫中元件的邊界大小;ChangeTransform 影響 view 的旋轉和縮放;ChangeImageTransform 則可將 Image 縮放大小;PathMotion API 可以控制動畫移動的路徑;Propagation + Epicenter API 則可以安排開始前的延遲時間,讓轉場動畫整體看起來是接續著完成的。
畫面轉場有兩種類型,一種是常用的整個內容的轉場,另一種是 Shared Element,只指定某個 View 在轉場中移動,當然也可以同時使用這兩種類型。但要了解所有動畫的繪製其實都在第二個進入的畫面,系統捕捉了第一頁畫面的內容透過我們描述的轉場樣式繪製在目標畫面上。
你可以在這些地方找到許多 sample code
https://github.com/googlesamples/android-unsplash
https://github.com/nickbutcher/plaid
https://github.com/googlesamples/android-topekahttps://github.com/googlesamples/android-ourstreets
https://developer.android.com/training/transitions/index.html
ExoPlayer 是開源與 app 等級的 media player library。可以支援 Android TV 與其他 API 16 + 的裝置。ExoPlayer 分別會使用到 Android 原生的 MediaExtractor、MediaCodecs 與 AudioTrack api,MediaExtractor 用來處理網路下載、資料緩存,最後影像與聲音隔離,MediaCodecs 負責解密,最後再把解密過的內容交給 AudioTrack 去播放。對於網路下載、資料緩存、影音隔離這三部分,ExoPlayer 提供客製化的功能,你可以根據你要播放的內容去做一些變化。
為什麼要使用 ExoPlayer?
在 gradle import ExoPlayer。
使用 TrackRender 定義要播放的多媒體類型,如 MediaCodecVideoTrackRenderer 可以用在影片,MediaCodecAudioTrackRender 則是用在音樂。
要建構 TrackRender 之前必須先傳入 SampleSource,SampleSource 則是包含了 format info 與 media sample。
ExoPlayer 則提供了以下幾種 SampleSource:
a. ExtractorSampleSource 用來播放 MP3,M4A,WebM,MPEG-TS 與 AAC。
b. ChunkSampleSource 用來撥用 DASH 與 SmoothStreaming。
c. HlsSampleSource 用來播放 HLS。
SampleSource 則是利用 DataSource 来載入多媒體數據,
常用到的 DataSource 有:
a. DefaultUriDataSource 用來播放本機或網路上的多媒體檔案;
b. AssetDataSource 用來播放 assets folder 裡面的多媒體檔案。
如果是 Adaptive streaming 則需要在 DataSource 裡定義 BandwidthMeter。
最後則是將定義好的 TrackRender 丟給 ExoPlayer。
ExoPlayer 也提供多種 event listenter 方便你去實做一些 call back。
Exoplayer 提供了 ExtractorSampleSource 用來播放傳統格式的多媒體檔案,包含 MP3、M4A、MP4、WebM、MPEG-TS 與 AAC。除了播放傳統格式的多媒體檔案,ExoPlayer 最大的特色就是支援 adaptive bitrate streaming,即在播放的時候會根據網絡狀況自動調節畫質。
DASH、SmoothStreaming 與 HLS 都是通過小塊的方式加載(通常2到10秒的長度),每當一塊媒體被 request,client 將會選擇一種可能的規格。例如:如果網絡情況比較好,client 就會選擇高質量來播放,如果網絡比較差則會選擇低畫質播放。
由於 ExoPlayer 比 Android 原生的 MediaPlayer 強大太多了,講者在最後還是希望大家都可以使用 ExoPlayer 來開發影音 app。
什麼是 Android TV 咧?Smart TV、STB、Streaming Box、Gaming Consoles 都是 Android TV,他們都是 Android 系統,繼承 Android 框架,TV Input Framework (TIF) 將多種來源 content 整合到 TV Channels,以下介紹 TIF 的概念與 Channel App 基本實作方法
什麼是 TV Input Framework (TIF) 咧?
當使用者開啓裝置上安裝 (或 OEM) 的 Live TV App 之後,可以像是傳統電視般收看各個頻道,但實際上各個頻道的內容來自於各種輸入來源
經由 TIF 將包括 HDMI、IP TV、STB 或 Channel App 等輸入來源,轉換到 TIF 的系統資料庫並以 content provider 的方式提供給 Live TV App 的 channels,同時獲取頻道或節目像是標題等相關訊息,當使用 Live TV App 時,會有和傳統電視功能極為相似的使用者體驗。
接下來介紹 Channel App 的實作方式,相關 class 都在 package “android.media.tv” 裏面,其中最主要開發者會需要修改到的是以下兩個 Java classes
TvContract: 定義頻道和節目在系統資料庫的欄位資料
TvInputService: 繪製內容到 Surface
一開始建議使用 Android Studio 直接匯入 Channel App sample 專案來修改: New > Import sample > Android tv > Sample TV Channel App (TV Input) using TIF
開發流程:Import Sample -> Change Resources -> Modify Code (Optional) -> Add to your App (Optional),如果你已經有開發了 Android TV App 只需要在 manifest 宣告 Service 即可 ex.
<service android:name=”YourTvInputService” android:label=”…”
android:permission=”android.permission.BIND_TV_INPUT”>
<intent-filter>
<action android:name=”android.media.tv.TvInputService” />
</intent-filter>
<meta-data android-name=”android.media.tv.input”
android:resource=”@xml/sample_tv_input” />
</service>
這篇是 Android Team 的人出來做 Q&A,以下節錄問題及回答
Question: 在某些歐洲國家許多的 Android 裝置有相容性的議題,在某些裝置中可能沒有 Google Play services 或 Google Framework,請問你可以談談 Android Team 為了這件事情做了哪些事情嗎?Answer: Google 在 CTS (Compatibility Test Suite) 上做了很多努力,以確保有平等的環境。這可以讓開發者的 App 在各種裝置上都能順利運行,Google 也積極的與製造商合作,讓能通過相容性測試裝置的涵蓋率增加。
Question: 目前 Android 支援 Java 8 的 Stream,想知道未來有沒有可能可以使用像是 java.lang.invoke, java.time 等等的 Java 8 APIs.Answer: 我們希望從開發者口中聽到哪些對你們是重要的,像是不斷的從開發者中聽到 Stream、Functional interface 很重要,因此我們加入了這些 API,但我們還想知道更多。目前我們的確正在關注 Time 這個 API。
Question: 我想知道你們什麼時候會支援 SwiftAnswer: 我們目前沒有計畫
Question: 我想知道你們是否有計畫為了 Android 整合一套預設的開發模式,像是微軟使用 MVC,當你建立新頁面,就會一併建立 Controller、View 與 Model。Answer: 從平台的觀點來看,我們不是很在乎你的應用程式是如何組成的,因此我們不會特別去規範這件事情。這完全是視情況而定,而不該是被平台所綁定。
Question: 當 inflate 有許多資源需備載入的 Views 的時候,在低 IO 的裝置上,會因為 main thread 忙碌中而得到約 100 ~ 500 毫秒的停頓。同時 View Framework 為了確保不會讓 view 做 reparent 而 hold 住 thread。想知道我們是否可以去看 Framework 並且允許在 View 建立時使用 Multi-thrading 來改善效能。Answer: 對於這個議題,建議你可以去最近的 Support Library,我相信我們有在裡面提供 Async View Inflator 讓你可以不用在 main thread 做 inflation。
Question: 我有兩個問題,一個是我們是否可以在 VR 使用 Android View,第二個是你們未來有支援開發 VR 的工具嗎?Answer: 第二個答案是目前沒有任何關於開發工具的事項要發表,第一個問題,我們替你傳達給 VR team 這個意見回饋
Question: 在 Android Studio 中我們目前已經整合 Native Debugging 未來是否還會有 Native Profiling 呢?Answer: 我們正在研究這項事情,歡迎你讓我們知道你想看到些什麼。
Question: 你們有計劃提供 Native Camera Capture API 嗎?Answer: 目前在 Android N 有提供。
Question: 你們有辦法在 release 版裡面移除 dex bytecode 嗎?這樣就無法對你的 app 進行逆向工程Answer: 我們目前沒計畫做這件事情,並且對我們來說只移除 dex 有困難。
Question: 當我們使用 Clang 時,我們是否需要讓其他的 library 也使用 Clang 進行編譯Answer: 不需要,你可以混用 Clang 或其他的編譯器編出來的東西。
Question: 你們有像是發行 Android One 那樣的新計畫嗎?在一些新興市場中,對於低階手機的規格很凌亂。想知道你們對於低階手機的看法。例如制定一些標準或其他的事情。Answer: 目前內部正在思考如何建立一個又棒,又容易升級且可以得到安全性更新等等的裝置。或是人們是否可以輕易升級他們的系統,像是 N to O。目前沒辦法談太多細節,但目標就是能夠更容易建立更加統一的裝置
Question: 想請教關於裝置轉向的問題,當裝置轉向時,整個 Activity 需要重建,這時你就必須要 cache 所有的西,這可能會造成許多問題。
所以想知道你們是否有計劃建立一個更輕量型的 layout 來處理轉向的問題,例如 view 只需要移動到新的位置就好。
Answer: 如果你的資源會隨著轉向而改變,我想你唯一的選擇就是重建。另外也可以透過減少需要被重建的資料來縮短重建的時間。例如可以使用 model layer 來存放那些資料。這樣可以減少很多效能上的問題。由於 Multi-window 即將要推出的關係,我們更鼓勵開發者自己處理 resize 的問題
Question: 你們能提供壓力感測的螢幕嗎?Answer: 我們認為 long press 與 force press 是同一件事情。實際上我們在 MotionEvent 就有提供 API 讓你捕捉你在螢幕上所施的力。
Question: 你認為目前提供給 User 最佳的導覽方式為何?Answer: 這必須根據你的 App 的架構而定。你可以參考 Material Design Spec,他告訴你何時該使用漢堡、Navigation Drawer、Bottom Tabs 或其他相關的模式。我們也一直不斷的在實驗新的模式、新的需求,我們的 Material Design Team 再將它變成一個標準並分享給每個人。
日本、韓國、台灣、香港 和東南亞(簡稱為 APAC)佔據了 50% 的 app market 營收,但在韓國及日本的遊戲排名都被當地的遊戲佔據,講者舉例日版和全球版怪物彈珠的遊戲封面風格完全不同,且遊戲內容有時是當地熟悉文化的延伸,另外針對在地文化或用戶回饋舉辦活動,也有助增長營收。
當開發商想要前進一個新的市場時,必須要先了解目標市場並做好規劃,做好在地化翻譯(慣用的計數單位也要注意),設置當地的用戶協助機制,最後可以利用 Google play 來做到更多。
Google 有提供簡單的 APK 自動翻譯功能,可以試水溫用。
擴展方針針對營收或安裝數需要先決定好,在 APAC 的國家中,日韓的營收回饋高,但宣傳費也高,東南亞的宣傳費低,營收回饋低,台港的營收回饋居中,使用者也有不錯的忠誠度,如果是均衡方針或是對全球化不熟悉,可以先從這兩地下手(講者還有列出分析 APAC 各國成功的遊戲類型及各國的訊息平台偏好。)
另外針對不同國情,可以提供不同的消費方案,針對消費水準調整價格也可以增加購買量及用戶。
當你在使用電腦的列印功能前,你必須要先下載正確的驅動程式,做好一堆令人挫敗的設定後才能正常使用。所以 Google 與許多的列印大廠共同組成的 Mopria Alliance 合作,共同制訂新的標準讓使用者能更簡單的完成列印的工作。
先簡單了瞭解一下 Android print 架構及原理:
– Print Service : 印表機的驅動
– Print Manage : 控制中樞,負責連接其他部份
– Print Spooler : 顯示畫面、通知、目前的列印工作和管理列印工作
– 當使用者要列印時,應用程式會去告訴系統,接著就會有一個 collaborative process 被叫起來按照使用者的設定,產生出要列印的內容。舉例來說,當使用者將紙張的尺寸變大,你的應用程式或許因為空間變大了想把原先只有一列的料資改成兩列,這時候你的應用程式就會按照使用者的設定去做 layout, rendering。
另外這次也把 layout 跟 rendering 切開來,layout 負責找出總共幾頁、哪些東西應該放在哪一頁的哪個位置,而 redering 則是負責將 layout 出來的結果轉成 pixels。原因是當一整個文件有1000 頁時, 必須去 layout 整份文件, 才能知道總共有多少頁, 有哪些東西在哪一頁, 但是當使用者在看 6, 7 頁的預覽時, 你不需要 render 1000 頁, 因為你所需要的就只有去 render 使用者能看到的那兩頁。
在使用 print API 時,PrintDocumentAdapter 是非常重要的部份,它根劇使用者在畫面上的選擇產生 PDF,在 onLayout, onWrite 時做 layout, rendering,也提供 ResultCallback,像是 onLayoutFinish, onLayoutFailed, onLayoutCancel 回傳結果。
除了上述自訂 Adapter 做 layout 及 rendering 的 API 外,有些開發者只想單純的列印照片、文件,他們對於產生 PDF 並不瞭解,關於這個部份也提供了簡單的 Class 利用 standard rendering command 來實現,如下:
– Simple PDF generation:跟 Android rendering APIs 一樣的方式生成 PDF
– Print a bitmap:使用 support library 提供的 PrintHelper
– Print HTML:使用 WebView 所提供的 method 得到 PrintDocumentAdapter
從 KitKat 到目前的改變:
– Before KitKat : 發出 intent 給印表機廠商所提供的 app 做列印
– KitKat: 使用了 print API 的架構,可供使用者選擇份數、紙張大小等 …
– Lillipop: 新增了預覽
– Marshmallow: 沒有大改變
– N:以上所介紹
現在最大的問題就是當使用者第一次列印時會先導到 Google Play Store 下載所需要的 Print Service,但這個步驟只需要做一次。
常見的問題
Pepper 是一個由 SoftBank 開發的機器人,他也加入 Andorid 這個大家庭的行列。現在要開發機器人相關的程式,可以在 Android Studio 透過 plugin 使用 Pepper SDK,開發者可以透過 SDK 讓 Pepper 使用既有的動作,也可以透過 SDK 自創獨特的動作。另外,Pepper SDK 提供 chat editor,讓使用者可以輸入一些簡單的 script,就能使用語音命令,可以創造一連串的問題和答案寫入 chat file 之中,Pepper 就會根據這份 chat file 來做對應的回答。此外,SDK 提供模擬器讓開發者不需要有真的機器人就可以開發機器人相關 App。
講者使用兩個 demo 來說明 Pepper 現在能做到什麼
1. Magic Hand
Pepper 有兩個 camera 用來辨識周遭的物體以及三維空間的概念,Pepper 辨識使用者的手勢,來做出相對應的動作。
2. Cardboard
使用者可以透過 Cardboard 來和機器人做連動,Pepper 會把他所看到的資料回傳到 Cardboard,讓使用者在遠處也可以用 Pepper 的視野監控家裡的狀況
ART (Android Runtime) 負責連接系統與 Android Framework,負責運算直譯與記憶體管理,他跟效能有重大的關係,基本上我們需要保證每秒 UI 可以用 60FPS 來更新,讓使用者有順暢的體驗,再過去使用 Dalvik 的時候,為了讓 memory 可以很有效的利用,在效能上有所捨棄,另外因為過去垃圾回收機制比較簡單,造成效能上的使用經驗比較差,針對以下五個指標,ART 都較 Dalvik 的效能更好:
– 運算效率
– App 啟動時間
– 畫面流暢度
– 電源效率
– 記憶體效率
在效能的提升上,ART 不需要 JIT 的啟動就能開始運行程式。Lollipop 中先使用了 Quick Compiler,但是 JIT 不適合用在較複雜的最佳化,例如 inline,所以後來換成使用Optimizing Compiler使用了以下方法來做最佳化:
– Static Single Assignment
– inlining
– linear scan register allocator
在ART的進化中,他們使用各種 Benchmark 來測試,發現效能持續有在改善,他們使用的大部分最佳化技術與平台無關,所以在個平台上都得到了效能的提升,為了在程式執行之前最佳化,每次系統升級的時候都必須花很多時間重新最佳化每一支 App,這在原本一年大約一次的更新上,還是使用者可以接受的狀況。但因為安全因素,發布更新的時間變得越來越短,甚至有可能一個月就出現一個新的版本,這樣的情況下使用者很難接受 ART 預先最佳化的緩慢。
為了改善這個狀況,JIT 又回到了 Android 中,但是 JIT 在記憶體使用與耗電上效能較差,所以後來使用了一種混合式的編譯方式,其中的細節考量了類似將解壓縮與檢查移到安裝階段。
再混合編譯、執行方式中,第一次執行程式的時候 JIT 會平行開始執行並且最佳化重度處理的函數,同時執行環境會做 profiling,並將結果存下來,之後再使用者充電、閒置的時候,系統會開始分析存下來的 profile,針對執行的狀況來最佳化程式並產生新的可執行擋,這些 profile 在使用者執行不同的情境的使用時,會跟著成長並改善這些情境的最佳化狀態,紀錄的資訊包括了這些函數呼叫的次數,執行的時間,是否為啟動時必須要呼叫的函數,是否在 UI 執行緒上跑。針對啟動時間,他們設計了直接載入預初始化的Heap,像是inflate layout這件事就可以預先完成。
一開始講者問聽眾,認為 Data Binding 仍在 Beta 的舉手,結果有超多人舉手的,講者說其實已經正式 Release 了,請大家盡情的去使用。接下來講者花了幾分鐘介紹什麼是 Data Binding,這部份可以到這裡瀏灠
A Little About Data Binding
https://goo.gl/9sMNR9
接下來講者開始介紹 2016 年秋季在 Data Binding 上會出現哪些新的功能,第一項是 Two way data binding 只要加上一個等號變成像 @={user.name} 就可以成為 two way data binding,但要注意例如 EditText 這種元件在 Java code 內改變了值,觸發 UI Element 改變,又立即往回觸發 Java model 改變的這種狀況,避免方法是在 setText 內判斷是否為同樣的字串。在這裡講者提到一個 Data binding 的重要觀念,並不是所有的 Attributes 都可以做 Data binding,必須是改變時會發出事件的成員才可以,但大多數開發者會在意的例如 text、checked、rating、progress 等都可以做 binding。
如果在畫面上有多個 UI Element 同時 binding 一個 attribute 例如 ImageView, TextView, CheckBox 的 android:visibility 皆綁定 user.isAdult 的狀況,講者認為這樣是不直覺的寫法,他建議應該幫 ImageView 取一個名字例如 @+id/avatar,然後另外兩項綁定 avatar.visibility 比較有邏輯,另外如果你想在 XML 裡寫 android:visibility=”@{seeAds.checked? View.VISIBLE : View.GONE}” 也是有支援的。
事件例如 android:onClick 也是有支援 binding 的,在 XML 中的寫作方法是 android:onClick=”@{Object::EventHandler}”,但在 Java class 內的 onClick function 內語法太長,新版將加入 Lambda Expressions 支援讓開發者可以寫成 android:onClick=”@{(v)->presenter.save(v,item)}” 來讓 Presenter class 內不用撰寫針對特定 UI 元件而存在的 function,讓 Class 內的程式碼達到 zero Android code 僅保留最純粹的商業邏輯。
如果開發者想要在 event 上使用 binding 時可能會碰到某些 event 的參數是需要 context 的,直接在 XML 中使用 context 即可,編譯器會幫忙對應。
在一個新的專案導入 Data binding 很容易,但已有的龐大專案要導入 Data binding 並不容易,講者介紹了幾個導入的建議,在 XML 中若是 binding function 的 event handler function name 要直覺,例如 android:click=”@{webservice::sendMoneyAsync}” 應該叫 android:click=”@{presenter::onSendClick}”,若在 XML 中加入判斷邏輯應該愈簡單愈好,例如 android:src=”@{user.age > 18 ? @drawable/adult : @drawable/kid}” 而不要寫 android:text=”@{user.age > 18 ? user.name.substring(…..) + user.lastName}” 這類邏輯。
這篇在說明 App 的開發者可以從遊戲開發商學習什麼。
一般來說遊戲比一般 App 容易賺錢,遊戲可以開發虛擬貨幣、寶物吸引使用者購買;但兩者對於商業分析是一樣的,「CPI < LTV」 表示開發商從各種渠道花錢吸引單一用戶的平均成本必須小於平均每位用戶所帶來的收入,唯此才能從中獲利。
而其中最大的關鍵是你的 App 能否保留住用戶,如果你想瞭解,可以透過 Google 的 Firebase Analytics 追蹤使用者從第一次安裝到是否持續使用 App 的分析圖表,幫助你優化需改善的部份。
這裡提出了三個建議,一是關注用戶參與度的懸崖曲線,從下圖可以看到,用戶流失最大的降幅在安裝後的七天內,無論再成功的應用皆是如此,所以盡量讓使用者在一開始就留下好的印象。
對遊戲 App 來說,他們嘗試的方法是讓用戶漸進式的嚐到甜頭,在初期提供簡單的任務,讓玩家獲得成就感,並漸進引導探索遊戲內容,吸引用戶留下。
第二個建議是面對你的 App 有各種特性的人在使用,提供給他們不同的訂閱方案,比如早期就會購買的重度用戶提供 VIP 的方案、絕不輕易購買的輕度玩家給予更優惠的小額方案等等等。這部分可以利用 Firebase 的 Remote Config 功能,針對不同的對象給予不同的結果。
第三個建議是在使用者需要的時候才向他兜售,初期可以提供免費使用額度,等到額度快用完時再跳出付費提醒,使用者會更願意購買。
Google 為了推廣 family App,在過去的 12 個月裡持續更新與推廣 family app 的服務,例如在 Google play home 上新增 family catrgory link,並在受歡迎的 family app 上新增 character painted page,在 character painted page 上可以看到跟 app 相關的其他服務,如電影、影集、遊戲、書籍與音樂。我們可以在 play store 上透過 search 或是 featuring 來找到相關的 character painted page。
不過除了上述方法之外,如何提供家庭用戶更專業的服務?Google play music 就提出了家庭方案,原價 1 個人 15 美元現在 6 個人無限暢聽只要 14.99 美元,家庭方案的用戶還可以享有 youtube ads free 的服務。
由於大部分的青少年都沒有信用卡,所以 Google 提供了 family payment method,不管是 paid app、in-app purchases 都可以透過 family payment method 來購買,對於 in-app purchases,家長可以透過 family mamager 來監督小孩的消費行為。
Family app 主要的客群可以分為兩種,一是專門針對小孩做開發,二是不管大人或是小孩都可以使用。Google 提供相關的 api 來幫助 developer 開發 family-friendly app,
由於要滿 13 歲才能申請 Google account,如果你的 app 是專門針對小孩做開發,就不要使用 Google play game service 自動登入的功能,反之則可以為你的 app 新增一個自動登入選項。
大部分的 kids app 都是 voice-based app,使用 Android speech api 可以提供聲音搜尋的功能,不過因為 audio recording 對於 kids -app 也是屬於相對敏感的私領域,所以也可以在 speech api 透過 tag 設定讓聲音搜尋的結果更謹慎一點。要如何提供 family friendly 的商業模式?
根據統計 family app 60% 的消費行為都是來自於平板,所以提供平板最佳化設計是一件很重要的事。
根據長時間觀察的結果發現,當用戶給予低評價,少部分的用戶會因為有回覆而將評價提升至少 0.75 顆星星,由於提升評價跟增加營收有正相關的關係,所以每一個開發者都應該要重視評價與回覆。
提供訂閱或是 freemium 的相關商業模式也可以增加營收。
本篇說明如何在 Google Play 賺錢,Google Play 是一個巨大的數位化商場,目前有 10 億逼近 20 億的使用者,開發商如何能從中獲得更好的營收?交易機制扮演著關鍵因素,以下說明幾個改善交易機制進而提升 ARPU 的方法
付款形式在地化:
Google Play 提供超過 140 個國家與地區購買服務,而事實上有許多國家地區並不通行使用信用卡,所以必須要有其他的付費方案更加便利的機制,帶來更多的消費,例如 DCB 機制在印尼提升了 4x 以上的交易量,據統計目前甚至有超過 600 萬檯裝置是經由 DCB 機制進行交易
Play Gift Card 是另一種很棒的機制,它能夠提供你任何一種付費方式 (主要是現金),舉例來說,在東京的 7-11 或是在印尼的一些小商店你可以用在地通用的任何付款方式購買到 Play Gift Card 然後儲值點數
優化購買體驗:我們每個月都在持續改進 Google Play 的購物流程,每週都在升級或每日升級部分後端系統,持續優化讓購買的流程更快一點,購買體驗更好一點
我們可以把影響消費的要素分為兩種,阻力/推力,像是遊戲可以去冒險得到升級,刺激用戶購買就是推力,用戶購買時找不到自己能用的付費機制,很明顯就是阻力,另外像是太繁瑣的流程,網路連線問題都會造成購買率降低
App 應該設計能提供足夠的資訊,讓用戶在認知上得到信任,順利完成交易的經驗,可以促使下一次交易的產生,另外請注意,商品價格往往是最大的購買阻力
除了 Google 對於自身的優化,開發者也應該優化商業模式流程,以統計數據來看有許多使用者只到 app 起始畫面就停止,進一步分析原因,在於起始畫面顯示太多不必要的資訊,像是一開始就建議使用者付費或是一開啟就看到廣告
最後提供幾個獲利的成功開發案例
Scopely:
RPG 遊戲採用 30day-pass 鼓勵使用者持續每天進入遊戲獲得獎勵,使得未曾付費的玩家與新玩家持續增加,這樣的好處是可以維持 RPG 遊戲多玩家的互動環境,再配合購買機制就可以持續獲得營收
Divmob:
採取超低價格 (低於 1 美元) 購買或升級遊戲的方式,在越南、菲律賓與印尼等國家,成功提高 3x 付費使用者與 300% 交易量
新使用者也因此增加 17%
Animoca:採用低價格就可購買遊戲包的方式(例如 100 顆遊戲寶石 + 5,000 遊戲金幣),結果購買遊戲包有 90% 都是初次付費的使用者,並且確認這當中有 50% 的使用者會再次付費,而且購買的是未特價的全額商品
SGN:提供在地化的金額格式並且轉換為整數,在一些先進國家像是義大利和瑞士 RPU 因此提升了 78% 像是挪威和南韓 ARPU 增加了 30%
使用者已經習慣與電視互動,在設計 TV apps 時需記得兩個原則,一是電視沒有觸控螢幕,二是使用者通常離電視有點距離,因此需要為 TV apps 設計不同的導覽方式。
Leanback 提供了各種基本的 UI 元件,像是 Card, Row, List of Rows, Actions, Grid 與 Fragment。
Leanback 提供了一個直覺且簡單操作的方式讓你顯示你的 Content,叫做 BrowseFrgamer,它包含了三個部分,在左邊有 HeadersFragment,裡面包含了垂直排列的 Navigation Menu;在上方有 Title View;右方則是 RowsFragment,以橫向方式來呈現你的內容。BrowserFragment 會幫你處理三者之間的問題,像是 Transition、HeadersFragment 與RowsFragment 之間的溝通、以及 TitleView 是否在適當的時機出現。
最新版的 Leanback Library 提供兩種新的 Rows,SectionRow 與 DividerRow 用來對 HeadersFragment 做分組,SectionRow 的作用是各分組的 Title,會出現在各分組的最前面,DividerRow 則是在各組的最後面。Leanback 將邏輯與 Style 分開,你可以繼承 Style 去設計你自己的樣式。
最新版的 Leanback Library 支援 Custom TitleView,需要實作自己的 TitleView,再將這個 TitleView 加到 Layout 中,最後需要實作 TitleViewAdapter,提供一個介面給 BrowseFragment 與其他 Fragment 做溝通,像是要顯示或隱藏 Custom TitleView。
Leanback 提供 PageRow 讓你可以在 BrowseFragment 放 Custom Frgament。
BrowseFragment 在內部會幫你 Mapping 每個 Row Type 到對應的 Factory。
如果你想要對 Header Item 與 PageRow 做配對,要使用 BrowseFragment 註冊你的 FragmentFactory,當 BrowseFragment 看到 PageRow 時,他就會用你註冊的 Factory 去 instantiaite 你的 Fragment
由於 BrowseFragment 會跟 Fragment 拿 MainFragmentAdapter,Fragment 必需實作 MainFragmentAdapterProvider。其中 MainFragmentAdapter 是 BrwoseFragment 與你的 Fragment 間溝通的橋樑,例如通知 Fragment開始播動畫,或是正在播動畫,或動畫結束。
另外也可以一併實作 MainFragmentRowsAdapterProvider (只有在 RowsFragment 時才需要),這是 BrowseFragment 用來傳遞row-based events,所以可以跟 HeadersFragment 與 RowsFragment 之間作同步。
上述兩個 Class 是 BrowseFragment 用來跟你的 Fragment 溝通的方法,反過來,若你的 Fragment 需要與 BrowseFragment 做溝通,則可以使用 FragmentHost。
ImageCardView 是 Leanback 的一個主要的類別,他包含 Image Area 與 Info Area 兩塊,其中 Image Area 是負責在 ImageCardView 的上方顯示圖片,Info Area 則在下方,他包含了 Title 與 Content
以及一個選擇性使用的圖示,Cards 也可以有不同的型態,可以藉由 Style 來改變他的樣式,其中有個屬性叫做 lbImageCardViewType,
這用來控制 Card 的內容要如何呈現,它包含了 Title, Content, Icon Right, Icon Left
(Right/Left 為互斥,擇一使用)。另一個屬性叫做 cardType,包含 infoUnder/infoOver/mainOnly,他用來控制 Info Area 與 Image Area 的相對位置。
若建立了自己的 style,還需要多對自己的 Custom Cards 多做兩件事情
1. 建立 theme 並且 override ImageCardViewStyle
2. 使用你剛剛建立的 theme 來建立你的 Custom Cards
如果 ImageCardView 沒有提供你需要的東西,可繼承 BaseCardView 進行改寫。
BrowseFragment 通常在你的第一個 Activity 裡面,他需要花一點時間去讀取資料。BrowseFragment 提供 Entrance Transition,他用來在讀取資料時給予使用者視覺上的回饋。資料讀取中時會出現 Progress Spinner,讀取完後 Header 與 Content 會從兩邊滑入畫面。
GuidedStepFragment 是專門設計給坐在十呎外觀看電視的使用者,它包含了左方的 Guidance Area,他是一個唯讀的區域,告訴使用者你在這個畫面可以做些什麼,右方則是 Guide Actions 列表,是使用者與你的介面互動的部分。
Andriod N 重新設計了 Android TV Settings App,他目前長的看起來像是躺在其他 Fragment 的上方,位於畫面右方的位置,可以用 LeanbackSettingsFragment 來使用它,它包含了 HeaderView,Preference List,每個 Preference Object 有 Icon, Title 與 Summary,Preference 也可以有 Embedded Widget 在裡面,像是 Switch。
Leanback 在 Android N 提供了 PlaybackOverlayControlFragment 來播放音樂,這個 Fragment 在上方有個 PlaybackControlsRow,用來控制播放行為,同時這部分的元件可以透過 Theme 與 Style 進行客制,下方則有 Media Item Row 來顯示歌曲清單。在 Media Item Row 裡面包含兩個部分,左方是 Media Item Details,用來顯示第幾首歌、歌曲名稱、歌手名稱、時間長度等等,右方則是 MultiAction,可放置你想要的 Action 列表。
要使用這個 feature,你必須繼承 AbstractMediaItemPresenter,他是用來 render Media Item,如果要用 MultiActions,則必須實作 MultiActionsProvider,他可以讓你放置 Actions 在 Media Item Details 的右方。
Android Notification 每一年都會改變,今年將是變化最多的一年,將帶來更多的 metirail design 讓訊息更易掃描新 Style 大致的重點如下
視覺樣式上更清爽、更多的 metirail、更不雜亂,左上的 icon 以及 App Name,可清楚的分辨是哪個 App 發出的通知,Action button 拿掉了 icon 為了更多的空間去顯示各種語言的文字,這次改善了可收展的通知,多了 Expansion widget,讓你知道此 App 是否有更多的通知內容以及點擊去讀取更多的內容。
這次通知 UI 的改版舊有的各項元素都還保留著,單純只是根據重要性有了不同的排列,並加上了些新的元素,雖然 Expansion icon 很小,但點擊範圍卻很大(App Name 那欄整條),假設你在過去使用 Notification Builder 去建立你的 Notification,恭喜你,你的程式碼不需要做任何的改變,但假如你自製 Custom View ,那可能有許多工作要做了,需要改為新版 Api 來套用新式 Notification Style。
這個版本有個重要的變化就是改善 Group 的概念,在手機上可以展開所有 Group 起來的通知,Wear 在過去的版本中你只能看被 Group 起來的數量,新版則每個 Group 起來的通知變成一張小卡方便你掃瞄每個訊息的重點。
在 Android N 有個強大的新功能就是 Direct reply,你需要使用 RemoteInput Class 去幫助你建立、使用這個功能,當回覆訊息時別馬上讓通知消失,而是讓通知回到最上面和使用 RemoteInputHistory 讓用戶顯示對話紀錄讓用戶可以來回的交談,比較符合使用者情境。
Wear 也套用了新式 MessagingStyle 以及 RemoteInput,想要在 Wear 上能夠有好的 Notification 體驗以下有幾點建議,必須確保 Notification 方便於快速閱讀,簡單來說就是專注於文字,為了完整展現 Expanded Notification 好處,使用 extra content pages 和 wearableExtender 幫助你建立各個 blocks,提升用戶體驗,於 Wear 2.0 應使用暗色背景,而在 1.x 則使用亮色背景確保使用 NotificationCompat 和 MessagingStyle 這樣就不用寫 Wear App 即可擁有 Wear Notification 功能。
2012 年 Google IO時,有人果斷說無法得知用戶是否封鎖 App 的推播 (笑),2016 年的今天,由於 Runtime Permission 的機制,我們可以檢查 Notification 權限,只要用簡單的 API : NotificationManager.areNotificationsEnabled()我們就可以知道使用者是否 封鎖了我們 App 的推播通知了,並且可以提醒用戶目前通知已被封鎖,讓用戶知道不是因為 bug 而收不到推播。
關於通知的優先權,大家都想要讓自己的 app 通知讓使用者看見,不過對於用戶來說,太多的雜訊反而是困擾,因此,新版提供了 Api addPerson 讓你設置 contact uri 或 phone 或 email,讓系統比對你的聯絡資訊判斷該人是不是你的朋友、重要程度,藉此判斷此通知的重要性。
最後,改版的新功能實在太多了,請下載 Demo Code 以及詳閱 Document 去實做