一、Android Auto 概述
最近物聯網是比較熱門的話題,做為物聯網重要的一部份車聯網也被眾多汽車廠商越來越重視,紛紛推出自己的車聯網系統。谷歌也是看到了車聯網的重要性於2014年6月推出了Android Auto系統。它是谷歌生態系統的一個重要終端。說它是個系統其實並不完全准確,因為谷歌並沒有提供完整的操作系統,而是提供了一套Android Auto SDK給汽車廠商。汽車廠商需要把這套Android Auto SDK 集成到他們自己的車載操作系統中。當然你也可以用這個SDK集成到谷歌的Android系統中。為了構建Android Auto生態圈,谷歌與汽車廠商共同組建“開放汽車聯盟”(Open Automotive Alliance),已經有40多個汽車廠商加入。
Android Auto主要提供了語音,導航,IM,音樂,電話等幾大核心功能。提供開發接口的目前只有音樂,IM兩類應用。
二、Android Auto 使用方法
Android Auto是如何與手機連接並使用的呢?你必須使用Android 5.0以上手機並支持google api(原生系統),通過USB(最新版本支持Wifi)與支持Android Auto 的車機連接,當你在車機上選擇音樂時,在音樂界面里會列出手機上支持Android Auto 的音樂應用,你選擇連接某個應用。這樣就可以播放音樂了。如下圖:

三、Android Auto 連接方式及原理
Android Auto車機與手機連接,是同時通過USB(或者Wifi)及藍牙來實現。藍牙只用來通話作用,USB(或者Wifi)主要用來傳送應用圖像、車機的觸摸事件及音頻數據。所有的程序運行都在手機端,車機端只是用來顯示及回傳事件。具體原理如下圖:

上圖左邊是車機,右邊是手機。從這個圖我們可以看出來,手機這邊在Android 5.0及以上系統已經集成了Android Auto的SDK。車機側需要使用Android Auto的SDK集成到車機系統,比如:WinCE,QNX,Linux等。但通話還是通過標准的藍牙HFP來實現。
四、Android Auto應用開發
剛才已經說了,目前Android Auto支持開發的接口應用只有音樂和消息兩類應用。我這里主要講一下音樂的開發過程。
1.創建新應用支持Android Auto
以Android Studio為例,這個與創建普通應用差別不大,但有一個地方需要注意,如下圖:

在選擇你要運行的平台時,選擇支持Android Auto。

這里需要你選擇要開發的音樂應用還是消息應用,這里我們選擇音樂類。這樣就完成了支持Android Auto音樂功能應用的創建。
2.現有應用中加入Android Auto的支持
直接在現在項目中選擇File->New->Android Auto->Media service就可以了。注意此時你的項目最小SDK必須是21以上,否則Media service為灰色,你無法創建。具體如下圖:

3.支持Android Auto的應用配置
以上兩種方式無論你按那種方式完成,我們都會發現在你應用的XML目錄里新建一個xml,比如:automotive_app_desc.xml,打開XML有以下內容:
<?xml version="1.0" encoding="utf-8"?> <automotiveApp> <uses name="media"/> </automotiveApp>
這里標識了應用的類型,這里是media,表示是支持Android Auto的音樂應用。 在AndroidManifest.xml中加入以下內容來標識應用支持Android Auto功能:
<application> ... <meta-data android:name="com.google.android.gms.car.application" android:resource="@xml/automotive_app_desc"/> </application>
4.Android Auto的界面定制
先來看一下Android Auto音樂類的界面

說是界面定制,實際上你除了換顏色其它什么都不能做了,如上圖,你只能改變1和2的顏色,他們分別對應到res->values->styles.xml里1-colorPrimaryDark 2-colorAccent的兩個值。
5.獲取連接上車機的廣播
IntentFilter filter = new IntentFilter("com.google.android.gms.car.media.STATUS"); BroadcastReceiver receiver = new BroadcastReceiver() { ... public void onReceive(Context context, Intent intent) { String status = intent.getStringExtra("media_connection_status"); boolean isConnectedToCar = "media_connected".equals(status); // adjust settings based on the connection status } };
通過接收com.google.android.gms.car.media.STATUS的廣播,來判斷當前應用是否已經連接上了車機。
6.判斷目前是否處於車機模式
public static booleanisCarUiMode(Context c) { UiModeManageruiModeManager=(UiModeManager)c.getSystemService(Context.UI_MODE_SERVICE); if (uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) { Log.d(TAG, "Running in Car mode"); return true; } else { Log.d(TAG, "Running on a non-Car mode"); return false; } }
7.繼承實現服務MediaBrowserService
MediaBrowserService也是繼承Servcie,這個服務中車機用來瀏覽及顯示歌曲列表的功能。和一般服務一樣,我們需要在AndroidManifest.xm聲明服務:
<application> ... <service android:name=".QQMusicAndroidAutoService" android:exported="true"> <intent-filter> <action android:name="android.media.browse.MediaBrowserService"/> </intent-filter> </service> ... <application>
這里需要注意:exproted必須為true,允許外部調用。與普通服務最大的不同就是必須要實現兩個接口:
public BrowserRooton GetRoot(String clientPackageName, intclientUid, Bundle rootHints); public void onLoadChildren(final String parentMediaId, final Result<List<MediaItem>> result);
我們就是通過上面兩個接口來獲取歌曲列表。onGetRoot這個接口是用來獲取歌曲列表根目錄。第一個參數是車機獲取根目錄的的應用的包名,你可以根據包名來判斷是否允許指定的車機應用來讀取根目錄信息。我們只要簡單返回
return new BrowserRoot("root", null);
就可以了。onLoadChildren這個接口是用來獲取歌曲列表子目錄。根據第一個參數parentMediaId來確認要獲取那個目錄的子目錄或者歌曲列表,第二參數result是要返回的子目錄或者歌曲列表。通過上面兩個接口的實現,我們就可以在車機上瀏覽歌曲列表了。
8.播放控制
要實現播放控制,就要使用Android5.0 的全新的MediaSession,它用於播放器與控制器之間進行交互,它取代之前的RemoteControlClient。 先來看一下如何創MediaSession,具體如下:
MediaSessionmSession = new MediaSession(this, "QQMusicAndroidAuto"); mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); mSession.setCallback(new MediaSessionCallback());
這里有兩個重要方法:setCallback和setFlags,我們分別來看一下。setFlags是來設置這個MediaSeccion的功能。 FLAG_HANDLES_MEDIA_BUTTONS 設置此標志可以處理媒體按鈕事件。 FLAG_HANDLES_TRANSPORT_CONTROLS 設置此標志以可以處理傳輸控制命令 setCallback是用來設置車機操作的回調,這個回調是MediaSession的內部接口Callback,需要我們實現,比較重要的幾個接口如下:
private final class MediaSessionCallback extends MediaSession.Callback { @Override public void onPlay(){}; @Override public void onSeekTo(long position){}; @Override public void onPlayFromMediaId(String mediaId, Bundle extras){}; @Override public void onPause(){}; @Override public void onSkipToNext(){}; @Override public void onSkipToPrevious(){}; @Override public void onCustomAction(String action, Bundle extras){}; @Override public void onPlayFromSearch(final String query, final Bundle extras){}; } onPlay:播放暫停后恢復播放調用 onSeekTo:跳轉到某個時間點播放 onPlayFromMediaId:用戶選定某個歌曲播放 onPause:暫停播放 onSkipToNext:播放下一首 onSkipToPrevious:播放上一首 onCustomAction:自定命令 onPlayFromSearch:搜索命令
以上各自分別實現就可以了。最后MediaBrowserServicer通過
setSessionToken(mSession.getSessionToken());
來設置MediaSession到服務。
五、Android Auto開發總結
總的來說,開發還是相對簡單,只要實現幾個接口就可以了,界面用戶可以不用關心。對開發者來說,只要提供數據就可以了。這大大減輕了開發者的工作,快速實現功能,但這也是缺點,無法實現自己定義的界面,界面單一。
參考文檔:
- 谷歌Android Auto開發官網: https://developer.android.com/training/auto/index.html