SlideShare a Scribd company logo
FIRST MEET WITH
ANDROID AUTO
Johnny Sung
2016.05.28 Android Taipei @ Yahoo!
Slides URL: http://goo.gl/EasR9V
MOBILE DEVICES DEVELOPER
Johnny Sung
https://fb.com/j796160836
https://plus.google.com/+JohnnySung
http://about.me/j796160836
http://www.pioneerelectronics.com/androidauto/
FEATURES &
LIMITATIONS
INTRODUCING ANDROID AUTO
http://www.pioneerelectronics.com/androidauto/
DEMO
http://www.greenbot.com/article/2931099/android-auto-review-the-best-way-to-get-google-maps-in-your-car.html
Navigation Tab
Phone Tab
Notification Tab
Music Tab
Vehicle info Tab
Vehicle info detail
***The Android Auto app is currently available in the following countries:
Ecuador
France
Germany
Guatemala
India
Ireland
Italy
Mexico
New Zealand
Panama
Argentina
Australia
Austria
Bolivia
Brazil
Canada
Chile
Colombia
Costa Rica
Dominican Republic
Paraguay
Peru
Puerto Rico
Russia
Spain
Switzerland
United Kingdom
United States
Uruguay
Venezuela
https://www.android.com/auto/
SETUP &
INSTALLATION
EMULATOR SETUP
1. Install Auto Desktop Head Unit emulator from
the SDK Manager
2. Install Android Auto app on phone
A. Tapping the Android Auto toolbar title 10
times to enable developer mode
B. Select Start head unit server from the
Android Auto menu.
1. Install Auto Desktop Head Unit emulator from the
SDK Manager
https://play.google.com/store/apps/details?id=com.google.android.projection.gearhead
2. Install Android Auto app on phone
A. enable developer mode
B. Select Start head unit server from menu.
#!/bin/bash
adb forward tcp:5277 tcp:5277
$ANDROID_HOME/extras/google/auto/desktop-head-unit
EMULATOR SETUP
3. Connect your phone to computer via USB.
4. Run scripts
StartAndroidAutoDesktopHeadUnit.sh
https://developer.android.com/training/auto/start/index.html
3. Connect your phone to computer via USB.
4. Run scripts
Mac
Android phone
Emulator Commands
▸ day
▸ night
▸ daynight
Day mode
Night mode
For safety reasons,
TOUCHES4
operation is limited within
Limited Operations
▸ 11 items per page
▸ 3 level depth
AUDIO
APPS
MAKING
FOR ANDROID AUTO
Create MediaBrowserService
<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package=“my.package.name">

<application>
<!-- ... -->
<meta-data

android:name="com.google.android.gms.car.application"

android:resource="@xml/automotive_app_desc"/>

<service

android:name=".MyMediaBrowserService"

android:exported="true">

<intent-filter>

<action android:name="android.media.browse.MediaBrowserService"/>

</intent-filter>

</service>



</application>

</manifest>
AndroidManifest.xml
(1/3)
Create MediaBrowserService
<?xml version="1.0" encoding="utf-8"?>

<automotiveApp>

<uses name="media"/>

</automotiveApp>
automotive_app_desc.xml
(2/3)
Create MediaBrowserService
@TargetApi(Build.VERSION_CODES.LOLLIPOP)

public class MyMediaBrowserService extends MediaBrowserService {

@Nullable

@Override

public BrowserRoot onGetRoot(String packageName, int uid, Bundle root) {

return new BrowserRoot(Const.MEDIA_ID_ROOT, null);

}



@Override

public void onLoadChildren(String parentId,
Result<List<MediaBrowser.MediaItem>> result) {

// ...

}

}
MyMediaBrowserService.java
(3/3)
Working with MediaSession
public class MyMediaBrowserService extends MediaBrowserService {



private MediaSession mSession;



@Override

public void onCreate() {

super.onCreate();

mSession = new MediaSession(this, "MyMediaBrowserService");

setSessionToken(mSession.getSessionToken());

mSession.setCallback(new MediaSessionCallback());

mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |

MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);

}



@Override

public void onDestroy() {

mSession.release();

}



private final class MediaSessionCallback extends MediaSession.Callback {

// ...

}

}
MyMediaBrowserService.java
private final class MediaSessionCallback extends MediaSession.Callback {

@Override

public void onPlay() {

}

@Override

public void onPause() {

}



@Override

public void onStop() {

}



@Override

public void onSeekTo(long position) {

}



@Override

public void onSkipToNext() {

}



@Override

public void onSkipToPrevious() {

}


// ...

}
private final class MediaSessionCallback extends MediaSession.Callback {
// ...

@Override

public void onPlayFromMediaId(String mediaId, Bundle extras) {

}



@Override

public void onSkipToQueueItem(long queueId) {

}



@Override

public void onCustomAction(String action, Bundle extras) {

}



@Override

public void onPlayFromSearch(final String query, final Bundle extras) {

}

}
Validate caller package
@Override

public BrowserRoot onGetRoot(String packageName, int uid, Bundle rootHints) {

LogHelper.d(TAG, "OnGetRoot: clientPackageName=" + packageName,

"; clientUid=" + uid + " ; rootHints=", rootHints);

// To ensure you are not allowing any arbitrary app to browse your app's
contents, you need to check the origin:

if (!mPackageValidator.isCallerAllowed(this, packageName, uid)) {

// If the request comes from an untrusted package, return null.

LogHelper.w(TAG, "OnGetRoot: IGNORING request from untrusted package "

+ packageName);

return null;

}



return new BrowserRoot(Const.MEDIA_ID_ROOT, null);

}
MyMediaBrowserService.java
Create Sliding Menus
@Override

public void onLoadChildren(final String pId, final Result<List<MediaItem>> result) {

List<MediaItem> mediaItems = new ArrayList<>();

if ("__ROOT__".equals(pId)) {

mediaItems.add(new MediaItem(

new MediaDescription.Builder()

.setMediaId(Const.MEDIA_ID_ITEM1)

.setTitle("Item 01")

.setSubtitle("Some descriptions")

.setIconUri(Uri.parse(
"android.resource://my.package.name/drawable/icon"))

.build(), MediaItem.FLAG_BROWSABLE

));

mediaItems.add(new MediaItem(

new MediaDescription.Builder()

.setMediaId(Const.MEDIA_ID_ITEM2)

.setTitle("Item 02")

.setIconUri(Uri.parse(
"android.resource://my.package.name/drawable/icon"))

.build(), MediaItem.FLAG_PLAYABLE

));

result.sendResult(mediaItems);

}

}
MyMediaBrowserService.java
(1/2)
Create Sliding Menus
private final class MediaSessionCallback extends MediaSession.Callback {



@Override

public void onPlayFromMediaId(String mediaId, Bundle extras) {

if (Const.MEDIA_ID_ITEM2.equals(mediaId)) {
// ...

// Play media
// ...

}

}
// ...

}
MyMediaBrowserService.java
(2/2)
Create Sliding Menus (Async)
@Override

public void onLoadChildren(final String parentMediaId, final
Result<List<MediaItem>> result) {

result.detach();

mMusicProvider.retrieveMediaAsync(new MusicProvider.Callback() {

@Override

public void onMusicCatalogReady() {

List<MediaItem> mediaItems = new ArrayList<>();

// ...
// Prepare to create items
// ...

result.sendResult(mediaItems);

}

});

}
MyMediaBrowserService.java
Setting Playback State
PlaybackState.Builder stateBuilder = new PlaybackState.Builder();

int playbackState = PlaybackState.STATE_PLAYING;



long action = PlaybackState.ACTION_PAUSE;

action |= PlaybackState.ACTION_SKIP_TO_NEXT;

action |= PlaybackState.ACTION_SKIP_TO_PREVIOUS;

stateBuilder.setActions(action);



stateBuilder.setState(playbackState, -1, 1.0f);



mSession.setPlaybackState(stateBuilder.build());



MediaMetadata.Builder metaBuilder = new MediaMetadata.Builder();

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);

metaBuilder.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, bitmap);



metaBuilder.putString(MediaMetadata.METADATA_KEY_ARTIST, "Great Artist");

metaBuilder.putString(MediaMetadata.METADATA_KEY_TITLE, "Song 1");

mSession.setMetadata(metaBuilder.build());



mSession.setActive(true);
MyMediaBrowserService.java
Show Error Message
PlaybackState.Builder stateBuilder = new PlaybackState.Builder();

int playbackState = PlaybackState.STATE_ERROR;

stateBuilder.setState(playbackState, -1, 1.0f);

stateBuilder.setErrorMessage("Oh no! Something has gone wrong.");

mSession.setPlaybackState(stateBuilder.build());
MyMediaBrowserService.java
Playing Queue
ArrayList<MediaMetadata> mediaMetadatas = new ArrayList<>();

for (int i = 0; i < 5; i++) {

String coverUrl = "android.resource://my.package.name/drawable/icon";

MediaMetadata.Builder builder = new MediaMetadata.Builder();

builder.putString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, coverUrl);

builder.putString(MediaMetadata.METADATA_KEY_ARTIST, "Great artist");

builder.putString(MediaMetadata.METADATA_KEY_TITLE, "Song " + (i + 1));

MediaMetadata metadata = builder.build();

mediaMetadatas.add(metadata);

}
MyMediaBrowserService.java
(1/2)
Playing Queue
List<MediaSession.QueueItem> queue = convertToQueue(mediaMetadatas);

mSession.setQueue(queue);

mSession.setQueueTitle("Now Playing");
private static List<MediaSession.QueueItem> convertToQueue(

Iterable<MediaMetadata> tracks) {

List<MediaSession.QueueItem> queue = new ArrayList<>();

int count = 0;

for (MediaMetadata track : tracks) {



String hierarchyAwareMediaID = "";



MediaMetadata trackCopy = new MediaMetadata.Builder(track)

.putString(MediaMetadata.METADATA_KEY_MEDIA_ID, hierarchyAwareMediaID)

.build();



MediaSession.QueueItem item = new MediaSession.QueueItem(

trackCopy.getDescription(), count++);

queue.add(item);

}

return queue;

}
MyMediaBrowserService.java
(2/2)
VOICE
COMMAND
Ok Google,
Ok Google,
Listen Jazz music on <YourApp>
MediaSession Callback
private final class MediaSessionCallback extends MediaSession.Callback {


@Override

public void onPlayFromSearch(final String query, final Bundle extras) {
// Perform voice actions

}

}
MyMediaBrowserService.java
Semantic Analysis
GOOGLE
KNOWLEDGE
GRAPH
Play music from Lady Gaga.
Play Jazz music.
Play Starships 

from Nicki Minaj.
Artist Extras
Genre Extras
Song name Extras
Examples
▸ MediaBrowserService
▸ https://github.com/googlesamples/android-MediaBrowserService/
▸ UniversalMusicPlayer
▸ https://github.com/googlesamples/android-UniversalMusicPlayer
MESSAGING
APPS
MAKING
FOR ANDROID AUTO
Create MessageReceivers AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="my.package.name">



<application>

<!-- ... -->

<meta-data android:name="com.google.android.gms.car.application"

android:resource="@xml/automotive_app_desc"/>



<receiver

android:name=".MessageReadReceiver"

android:exported="false">

<intent-filter>

<action android:name="my.package.name.ACTION_MESSAGE_READ"/>

</intent-filter>

</receiver>



<receiver

android:name=".MessageReplyReceiver"

android:exported="false">

<intent-filter>

<action android:name="my.package.name.ACTION_MESSAGE_REPLY"/>

</intent-filter>

</receiver>

</application>

</manifest>
(1/2)
automotive_app_desc.xml
<?xml version="1.0" encoding="utf-8"?>

<automotiveApp>

<uses name="notification"/>

</automotiveApp>
Create MessageReceivers (2/2)
MessageReadReceiver
public class MessageReadReceiver extends BroadcastReceiver {



@Override

public void onReceive(Context context, Intent intent) {

int conversationId = intent.getIntExtra(Const.CONVERSATION_ID, -1);

if (conversationId != -1) {

// Actions with conversation was read

}

}

}
MessageReadReceiver.java
MessageReplyReceiver
public class MessageReplyReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

if (Const.REPLY_ACTION.equals(intent.getAction())) {

int conversationId = intent.getIntExtra(Const.CONVERSATION_ID, -1);



Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);

CharSequence reply = "";

if (remoteInput != null) {

reply = remoteInput.getCharSequence(

Const.EXTRA_REMOTE_REPLY);

}

if (conversationId != -1) {

// Actions for receive reply message

}

}

}

}
MessageReplyReceiver.java
Prepare PendingIntent
int conversationId = 1;

String name = "Johnny";

String message = "Hello, World!";
// A pending Intent for reads

Intent readIntent = new Intent()

.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)

.setAction(Const.READ_ACTION)

.putExtra(Const.CONVERSATION_ID, conversationId);



PendingIntent readPendingIntent = PendingIntent.getBroadcast(this,

conversationId,

readIntent,

PendingIntent.FLAG_UPDATE_CURRENT);
MainActivity.java
(1/2)
Prepare PendingIntent
// Build a RemoteInput for receiving voice input in a Car Notification

RemoteInput remoteInput = new RemoteInput.Builder(Const.EXTRA_REMOTE_REPLY)

.setLabel(getString(R.string.reply))

.build();



// Building a Pending Intent for the reply action to trigger

Intent replyIntent = new Intent()

.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)

.setAction(Const.REPLY_ACTION)

.putExtra(Const.CONVERSATION_ID, conversationId);



PendingIntent replyPendingIntent = PendingIntent.getBroadcast(this,

conversationId,

replyIntent,

PendingIntent.FLAG_UPDATE_CURRENT);
MainActivity.java
(2/2)
Build CarExtender & UnreadConversion
// Create the UnreadConversation and populate it with the participant name,

// read and reply intents.

NotificationCompat.CarExtender.UnreadConversation.Builder unreadConvBuilder =

new NotificationCompat.CarExtender.UnreadConversation.Builder(name)

.setLatestTimestamp(System.currentTimeMillis())

.setReadPendingIntent(readPendingIntent)

.setReplyAction(replyPendingIntent, remoteInput)

.addMessage(message);



NotificationCompat.CarExtender carExtender =
new NotificationCompat.CarExtender()

.setUnreadConversation(unreadConvBuilder.build());
MainActivity.java
Make a Notification
NotificationCompat.Action replyAction =
new NotificationCompat.Action.Builder(

R.drawable.icon, getString(R.string.reply), replyPendingIntent)

.addRemoteInput(remoteInput)

.build();
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)

.setSmallIcon(R.drawable.icon)

.setLargeIcon(BitmapFactory.decodeResource(

getResources(), R.drawable.icon_big))

.setContentText(message)

.setWhen(System.currentTimeMillis())

.setContentTitle(name)

.setContentIntent(readPendingIntent)

.extend(carExtender)

.addAction(replyAction);



NotificationManagerCompat manager = NotificationManagerCompat.from(this);

manager.notify(conversationId, builder.build());
MainActivity.java
Examples
▸ MessagingService
▸ https://github.com/googlesamples/android-MessagingService
DEMO
Q & A

More Related Content

Viewers also liked

A Quick look at ANCS (Apple Notification Center Service)
A Quick look at ANCS (Apple Notification Center Service)A Quick look at ANCS (Apple Notification Center Service)
A Quick look at ANCS (Apple Notification Center Service)
Johnny Sung
 
Android Auto instrumentation
Android Auto instrumentationAndroid Auto instrumentation
Android Auto instrumentation
Przemek Jakubczyk
 
How One Article Changed the Way we Create our Product Roadmap
How One Article Changed the Way we Create our Product RoadmapHow One Article Changed the Way we Create our Product Roadmap
How One Article Changed the Way we Create our Product Roadmap
Nick Peasant
 
Android Auto Talk at #DroidConFR !
Android Auto Talk at #DroidConFR !Android Auto Talk at #DroidConFR !
Android Auto Talk at #DroidConFR !
Damien Cavaillès
 
Android Auto: Multi-Lanaguge Voice Messaging
Android Auto: Multi-Lanaguge Voice MessagingAndroid Auto: Multi-Lanaguge Voice Messaging
Android Auto: Multi-Lanaguge Voice Messaging
Chintan Parikh
 
Google I/O 2016: What to expect from Android N to virtual reality?
Google I/O 2016: What to expect from Android N to virtual reality?Google I/O 2016: What to expect from Android N to virtual reality?
Google I/O 2016: What to expect from Android N to virtual reality?
ChromeInfo Technologies
 
[MOPCON 2015] 談談行動裝置的 Accessibility
[MOPCON 2015] 談談行動裝置的 Accessibility[MOPCON 2015] 談談行動裝置的 Accessibility
[MOPCON 2015] 談談行動裝置的 Accessibility
Johnny Sung
 
英國脫歐會怎樣
英國脫歐會怎樣英國脫歐會怎樣
英國脫歐會怎樣
琛為 黃
 
How will the internet of things
How will the internet of thingsHow will the internet of things
How will the internet of things
Wei-Ting SHIH
 
兩分鐘作好粉絲專頁聊天機器人
兩分鐘作好粉絲專頁聊天機器人兩分鐘作好粉絲專頁聊天機器人
兩分鐘作好粉絲專頁聊天機器人
琛為 黃
 
Facebook messenger botの作り方と作ってみた
Facebook messenger botの作り方と作ってみたFacebook messenger botの作り方と作ってみた
Facebook messenger botの作り方と作ってみた
Takaaki Kusumoto
 
Android Auto
Android AutoAndroid Auto
Android Auto
Godfrey Nolan
 
Android auto
Android autoAndroid auto
Android auto
dhiraj007
 
Intro to android auto
Intro to android autoIntro to android auto
Intro to android auto
Thomas Krueger
 
Introductions of Messaging bot 做聊天機器人
Introductions of Messaging bot 做聊天機器人Introductions of Messaging bot 做聊天機器人
Introductions of Messaging bot 做聊天機器人
Johnny Sung
 
Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01
Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01
Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01Tekblink Jeeten
 
Gcp intro-20160721
Gcp intro-20160721Gcp intro-20160721
Gcp intro-20160721
Haeseung Lee
 
Alibaba YunOS platum china report
Alibaba YunOS platum china reportAlibaba YunOS platum china report
Alibaba YunOS platum china report
Platum
 
Introduction of Android Auto
Introduction of Android AutoIntroduction of Android Auto
Introduction of Android Auto
Zaicheng Qi
 

Viewers also liked (20)

A Quick look at ANCS (Apple Notification Center Service)
A Quick look at ANCS (Apple Notification Center Service)A Quick look at ANCS (Apple Notification Center Service)
A Quick look at ANCS (Apple Notification Center Service)
 
Android Auto instrumentation
Android Auto instrumentationAndroid Auto instrumentation
Android Auto instrumentation
 
How One Article Changed the Way we Create our Product Roadmap
How One Article Changed the Way we Create our Product RoadmapHow One Article Changed the Way we Create our Product Roadmap
How One Article Changed the Way we Create our Product Roadmap
 
Android Auto Talk at #DroidConFR !
Android Auto Talk at #DroidConFR !Android Auto Talk at #DroidConFR !
Android Auto Talk at #DroidConFR !
 
Android Auto: Multi-Lanaguge Voice Messaging
Android Auto: Multi-Lanaguge Voice MessagingAndroid Auto: Multi-Lanaguge Voice Messaging
Android Auto: Multi-Lanaguge Voice Messaging
 
Google I/O 2016: What to expect from Android N to virtual reality?
Google I/O 2016: What to expect from Android N to virtual reality?Google I/O 2016: What to expect from Android N to virtual reality?
Google I/O 2016: What to expect from Android N to virtual reality?
 
[MOPCON 2015] 談談行動裝置的 Accessibility
[MOPCON 2015] 談談行動裝置的 Accessibility[MOPCON 2015] 談談行動裝置的 Accessibility
[MOPCON 2015] 談談行動裝置的 Accessibility
 
英國脫歐會怎樣
英國脫歐會怎樣英國脫歐會怎樣
英國脫歐會怎樣
 
How will the internet of things
How will the internet of thingsHow will the internet of things
How will the internet of things
 
兩分鐘作好粉絲專頁聊天機器人
兩分鐘作好粉絲專頁聊天機器人兩分鐘作好粉絲專頁聊天機器人
兩分鐘作好粉絲專頁聊天機器人
 
Facebook messenger botの作り方と作ってみた
Facebook messenger botの作り方と作ってみたFacebook messenger botの作り方と作ってみた
Facebook messenger botの作り方と作ってみた
 
Android Auto
Android AutoAndroid Auto
Android Auto
 
Android auto
Android autoAndroid auto
Android auto
 
Intro to android auto
Intro to android autoIntro to android auto
Intro to android auto
 
Introductions of Messaging bot 做聊天機器人
Introductions of Messaging bot 做聊天機器人Introductions of Messaging bot 做聊天機器人
Introductions of Messaging bot 做聊天機器人
 
Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01
Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01
Top 100-php-interview-questions-and-answers-are-below-120816023558-phpapp01
 
SH Product Roadmap
SH Product RoadmapSH Product Roadmap
SH Product Roadmap
 
Gcp intro-20160721
Gcp intro-20160721Gcp intro-20160721
Gcp intro-20160721
 
Alibaba YunOS platum china report
Alibaba YunOS platum china reportAlibaba YunOS platum china report
Alibaba YunOS platum china report
 
Introduction of Android Auto
Introduction of Android AutoIntroduction of Android Auto
Introduction of Android Auto
 

Similar to First meet with Android Auto

IMPLEMENTING VOICE CONTROL WITH THE ANDROID MEDIA SESSION API ON AMAZON FIRE ...
IMPLEMENTING VOICE CONTROL WITH THE ANDROID MEDIA SESSION API ON AMAZON FIRE ...IMPLEMENTING VOICE CONTROL WITH THE ANDROID MEDIA SESSION API ON AMAZON FIRE ...
IMPLEMENTING VOICE CONTROL WITH THE ANDROID MEDIA SESSION API ON AMAZON FIRE ...
Amazon Appstore Developers
 
Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)
Alfredo Morresi
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basicsAnton Narusberg
 
Android Froyo
Android FroyoAndroid Froyo
Android Froyo
Robert Cooper
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of usOSCON Byrum
 
망고100 보드로 놀아보자 18
망고100 보드로 놀아보자 18망고100 보드로 놀아보자 18
망고100 보드로 놀아보자 18종인 전
 
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is FineCocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
Chris Adamson
 
The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]
Nilhcem
 
Android best practices
Android best practicesAndroid best practices
Android best practices
Jose Manuel Ortega Candel
 
Vaadin7
Vaadin7Vaadin7
Android For All The Things
Android For All The ThingsAndroid For All The Things
Android For All The Things
Paul Trebilcox-Ruiz
 
Mobile Software Engineering Crash Course - C06 WindowsPhone
Mobile Software Engineering Crash Course - C06 WindowsPhoneMobile Software Engineering Crash Course - C06 WindowsPhone
Mobile Software Engineering Crash Course - C06 WindowsPhoneMohammad Shaker
 
Android
AndroidAndroid
Android
Pranav Ashok
 
Gradle for Android Developers
Gradle for Android DevelopersGradle for Android Developers
Gradle for Android Developers
Josiah Renaudin
 
Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015 Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015
Mario Jorge Pereira
 
Popup view on Mortar
Popup view on MortarPopup view on Mortar
Popup view on Mortar
Keishin Yokomaku
 
Android App Development - 14 location, media and notifications
Android App Development - 14 location, media and notificationsAndroid App Development - 14 location, media and notifications
Android App Development - 14 location, media and notifications
Diego Grancini
 
Integrando sua app Android com Chromecast
Integrando sua app Android com ChromecastIntegrando sua app Android com Chromecast
Integrando sua app Android com Chromecast
Athila Henrique dos Santos
 
Implementing cast in android
Implementing cast in androidImplementing cast in android
Implementing cast in android
Angelo Rüggeberg
 

Similar to First meet with Android Auto (20)

IMPLEMENTING VOICE CONTROL WITH THE ANDROID MEDIA SESSION API ON AMAZON FIRE ...
IMPLEMENTING VOICE CONTROL WITH THE ANDROID MEDIA SESSION API ON AMAZON FIRE ...IMPLEMENTING VOICE CONTROL WITH THE ANDROID MEDIA SESSION API ON AMAZON FIRE ...
IMPLEMENTING VOICE CONTROL WITH THE ANDROID MEDIA SESSION API ON AMAZON FIRE ...
 
Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)Slightly Advanced Android Wear ;)
Slightly Advanced Android Wear ;)
 
Android app development basics
Android app development basicsAndroid app development basics
Android app development basics
 
Android Froyo
Android FroyoAndroid Froyo
Android Froyo
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
 
망고100 보드로 놀아보자 18
망고100 보드로 놀아보자 18망고100 보드로 놀아보자 18
망고100 보드로 놀아보자 18
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is FineCocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
CocoaConf Chicago 2017: Media Frameworks and Swift: This Is Fine
 
The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]The 2016 Android Developer Toolbox [MOBILIZATION]
The 2016 Android Developer Toolbox [MOBILIZATION]
 
Android best practices
Android best practicesAndroid best practices
Android best practices
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Android For All The Things
Android For All The ThingsAndroid For All The Things
Android For All The Things
 
Mobile Software Engineering Crash Course - C06 WindowsPhone
Mobile Software Engineering Crash Course - C06 WindowsPhoneMobile Software Engineering Crash Course - C06 WindowsPhone
Mobile Software Engineering Crash Course - C06 WindowsPhone
 
Android
AndroidAndroid
Android
 
Gradle for Android Developers
Gradle for Android DevelopersGradle for Android Developers
Gradle for Android Developers
 
Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015 Android por onde começar? Mini Curso Erbase 2015
Android por onde começar? Mini Curso Erbase 2015
 
Popup view on Mortar
Popup view on MortarPopup view on Mortar
Popup view on Mortar
 
Android App Development - 14 location, media and notifications
Android App Development - 14 location, media and notificationsAndroid App Development - 14 location, media and notifications
Android App Development - 14 location, media and notifications
 
Integrando sua app Android com Chromecast
Integrando sua app Android com ChromecastIntegrando sua app Android com Chromecast
Integrando sua app Android com Chromecast
 
Implementing cast in android
Implementing cast in androidImplementing cast in android
Implementing cast in android
 

More from Johnny Sung

[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023
[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023
[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023
Johnny Sung
 
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
Johnny Sung
 
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang) [Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
Johnny Sung
 
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
Johnny Sung
 
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
Johnny Sung
 
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Johnny Sung
 
談談 Android constraint layout
談談 Android constraint layout談談 Android constraint layout
談談 Android constraint layout
Johnny Sung
 
炎炎夏日學 Android 課程 - Part3: Android app 實作
炎炎夏日學 Android 課程 - Part3: Android app 實作炎炎夏日學 Android 課程 - Part3: Android app 實作
炎炎夏日學 Android 課程 - Part3: Android app 實作
Johnny Sung
 
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
Johnny Sung
 
炎炎夏日學 Android 課程 - Part2: Android 元件介紹
炎炎夏日學 Android 課程 - Part2: Android 元件介紹炎炎夏日學 Android 課程 - Part2: Android 元件介紹
炎炎夏日學 Android 課程 - Part2: Android 元件介紹
Johnny Sung
 
炎炎夏日學 Android 課程 - Part 0: 環境搭建
炎炎夏日學 Android 課程 - Part 0: 環境搭建炎炎夏日學 Android 課程 - Part 0: 環境搭建
炎炎夏日學 Android 課程 - Part 0: 環境搭建
Johnny Sung
 
About Mobile Accessibility
About Mobile AccessibilityAbout Mobile Accessibility
About Mobile Accessibility
Johnny Sung
 
Everything About Bluetooth (淺談藍牙 4.0) - Central 篇
Everything About Bluetooth (淺談藍牙 4.0) - Central 篇Everything About Bluetooth (淺談藍牙 4.0) - Central 篇
Everything About Bluetooth (淺談藍牙 4.0) - Central 篇
Johnny Sung
 
uPresenter, the story.
uPresenter, the story.uPresenter, the story.
uPresenter, the story.
Johnny Sung
 
Android Wear Development
Android Wear DevelopmentAndroid Wear Development
Android Wear DevelopmentJohnny Sung
 
Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101
Johnny Sung
 
Android workshop - 01. Getting started on android phone
Android workshop - 01. Getting started on android phoneAndroid workshop - 01. Getting started on android phone
Android workshop - 01. Getting started on android phone
Johnny Sung
 
Good!愛點兒 - 雲端電子點餐系統
Good!愛點兒 - 雲端電子點餐系統Good!愛點兒 - 雲端電子點餐系統
Good!愛點兒 - 雲端電子點餐系統
Johnny Sung
 
[MOPCON 2014] Google Glass 開發經驗分享
[MOPCON 2014] Google Glass 開發經驗分享[MOPCON 2014] Google Glass 開發經驗分享
[MOPCON 2014] Google Glass 開發經驗分享
Johnny Sung
 
製作 Unity Plugin for Android
製作 Unity Plugin for Android製作 Unity Plugin for Android
製作 Unity Plugin for Android
Johnny Sung
 

More from Johnny Sung (20)

[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023
[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023
[AI / ML] 用 LLM (Large language model) 來整理您的知識庫 @Devfest Taipei 2023
 
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
[Flutter] Flutter Provider 看似簡單卻又不簡單的狀態管理工具 @ Devfest Kaohsiung 2023
 
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang) [Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
[Golang] 以 Mobile App 工程師視角,帶你進入 Golang 的世界 (Introduction of GoLang)
 
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
[Flutter] 來體驗 bloc 小方塊的神奇魔法 @Devfest 2022
 
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
與 Sign in with Apple 的愛恨情仇 @ iPlayground2020
 
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
Flutter 是什麼?用 Flutter 會省到時間嗎? @ GDG Devfest2020
 
談談 Android constraint layout
談談 Android constraint layout談談 Android constraint layout
談談 Android constraint layout
 
炎炎夏日學 Android 課程 - Part3: Android app 實作
炎炎夏日學 Android 課程 - Part3: Android app 實作炎炎夏日學 Android 課程 - Part3: Android app 實作
炎炎夏日學 Android 課程 - Part3: Android app 實作
 
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹炎炎夏日學 Android 課程 -  Part1: Kotlin 語法介紹
炎炎夏日學 Android 課程 - Part1: Kotlin 語法介紹
 
炎炎夏日學 Android 課程 - Part2: Android 元件介紹
炎炎夏日學 Android 課程 - Part2: Android 元件介紹炎炎夏日學 Android 課程 - Part2: Android 元件介紹
炎炎夏日學 Android 課程 - Part2: Android 元件介紹
 
炎炎夏日學 Android 課程 - Part 0: 環境搭建
炎炎夏日學 Android 課程 - Part 0: 環境搭建炎炎夏日學 Android 課程 - Part 0: 環境搭建
炎炎夏日學 Android 課程 - Part 0: 環境搭建
 
About Mobile Accessibility
About Mobile AccessibilityAbout Mobile Accessibility
About Mobile Accessibility
 
Everything About Bluetooth (淺談藍牙 4.0) - Central 篇
Everything About Bluetooth (淺談藍牙 4.0) - Central 篇Everything About Bluetooth (淺談藍牙 4.0) - Central 篇
Everything About Bluetooth (淺談藍牙 4.0) - Central 篇
 
uPresenter, the story.
uPresenter, the story.uPresenter, the story.
uPresenter, the story.
 
Android Wear Development
Android Wear DevelopmentAndroid Wear Development
Android Wear Development
 
Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101Android workshop - 02. Glass development 101
Android workshop - 02. Glass development 101
 
Android workshop - 01. Getting started on android phone
Android workshop - 01. Getting started on android phoneAndroid workshop - 01. Getting started on android phone
Android workshop - 01. Getting started on android phone
 
Good!愛點兒 - 雲端電子點餐系統
Good!愛點兒 - 雲端電子點餐系統Good!愛點兒 - 雲端電子點餐系統
Good!愛點兒 - 雲端電子點餐系統
 
[MOPCON 2014] Google Glass 開發經驗分享
[MOPCON 2014] Google Glass 開發經驗分享[MOPCON 2014] Google Glass 開發經驗分享
[MOPCON 2014] Google Glass 開發經驗分享
 
製作 Unity Plugin for Android
製作 Unity Plugin for Android製作 Unity Plugin for Android
製作 Unity Plugin for Android
 

Recently uploaded

"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 

Recently uploaded (20)

"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 

First meet with Android Auto

  • 1. FIRST MEET WITH ANDROID AUTO Johnny Sung 2016.05.28 Android Taipei @ Yahoo! Slides URL: http://goo.gl/EasR9V
  • 2. MOBILE DEVICES DEVELOPER Johnny Sung https://fb.com/j796160836 https://plus.google.com/+JohnnySung http://about.me/j796160836
  • 3.
  • 4.
  • 5.
  • 6.
  • 10. DEMO
  • 17. ***The Android Auto app is currently available in the following countries: Ecuador France Germany Guatemala India Ireland Italy Mexico New Zealand Panama Argentina Australia Austria Bolivia Brazil Canada Chile Colombia Costa Rica Dominican Republic Paraguay Peru Puerto Rico Russia Spain Switzerland United Kingdom United States Uruguay Venezuela https://www.android.com/auto/
  • 19. EMULATOR SETUP 1. Install Auto Desktop Head Unit emulator from the SDK Manager 2. Install Android Auto app on phone A. Tapping the Android Auto toolbar title 10 times to enable developer mode B. Select Start head unit server from the Android Auto menu.
  • 20. 1. Install Auto Desktop Head Unit emulator from the SDK Manager
  • 22. A. enable developer mode B. Select Start head unit server from menu.
  • 23. #!/bin/bash adb forward tcp:5277 tcp:5277 $ANDROID_HOME/extras/google/auto/desktop-head-unit EMULATOR SETUP 3. Connect your phone to computer via USB. 4. Run scripts StartAndroidAutoDesktopHeadUnit.sh https://developer.android.com/training/auto/start/index.html
  • 24. 3. Connect your phone to computer via USB. 4. Run scripts
  • 26. Emulator Commands ▸ day ▸ night ▸ daynight
  • 29. Limited Operations ▸ 11 items per page ▸ 3 level depth
  • 30.
  • 32.
  • 33. Create MediaBrowserService <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package=“my.package.name">
 <application> <!-- ... --> <meta-data
 android:name="com.google.android.gms.car.application"
 android:resource="@xml/automotive_app_desc"/>
 <service
 android:name=".MyMediaBrowserService"
 android:exported="true">
 <intent-filter>
 <action android:name="android.media.browse.MediaBrowserService"/>
 </intent-filter>
 </service>
 
 </application>
 </manifest> AndroidManifest.xml (1/3)
  • 34. Create MediaBrowserService <?xml version="1.0" encoding="utf-8"?>
 <automotiveApp>
 <uses name="media"/>
 </automotiveApp> automotive_app_desc.xml (2/3)
  • 35. Create MediaBrowserService @TargetApi(Build.VERSION_CODES.LOLLIPOP)
 public class MyMediaBrowserService extends MediaBrowserService {
 @Nullable
 @Override
 public BrowserRoot onGetRoot(String packageName, int uid, Bundle root) {
 return new BrowserRoot(Const.MEDIA_ID_ROOT, null);
 }
 
 @Override
 public void onLoadChildren(String parentId, Result<List<MediaBrowser.MediaItem>> result) {
 // ...
 }
 } MyMediaBrowserService.java (3/3)
  • 36. Working with MediaSession public class MyMediaBrowserService extends MediaBrowserService {
 
 private MediaSession mSession;
 
 @Override
 public void onCreate() {
 super.onCreate();
 mSession = new MediaSession(this, "MyMediaBrowserService");
 setSessionToken(mSession.getSessionToken());
 mSession.setCallback(new MediaSessionCallback());
 mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS |
 MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS);
 }
 
 @Override
 public void onDestroy() {
 mSession.release();
 }
 
 private final class MediaSessionCallback extends MediaSession.Callback {
 // ...
 }
 } MyMediaBrowserService.java
  • 37. private final class MediaSessionCallback extends MediaSession.Callback {
 @Override
 public void onPlay() {
 }
 @Override
 public void onPause() {
 }
 
 @Override
 public void onStop() {
 }
 
 @Override
 public void onSeekTo(long position) {
 }
 
 @Override
 public void onSkipToNext() {
 }
 
 @Override
 public void onSkipToPrevious() {
 } 
 // ...
 }
  • 38. private final class MediaSessionCallback extends MediaSession.Callback { // ...
 @Override
 public void onPlayFromMediaId(String mediaId, Bundle extras) {
 }
 
 @Override
 public void onSkipToQueueItem(long queueId) {
 }
 
 @Override
 public void onCustomAction(String action, Bundle extras) {
 }
 
 @Override
 public void onPlayFromSearch(final String query, final Bundle extras) {
 }
 }
  • 39. Validate caller package @Override
 public BrowserRoot onGetRoot(String packageName, int uid, Bundle rootHints) {
 LogHelper.d(TAG, "OnGetRoot: clientPackageName=" + packageName,
 "; clientUid=" + uid + " ; rootHints=", rootHints);
 // To ensure you are not allowing any arbitrary app to browse your app's contents, you need to check the origin:
 if (!mPackageValidator.isCallerAllowed(this, packageName, uid)) {
 // If the request comes from an untrusted package, return null.
 LogHelper.w(TAG, "OnGetRoot: IGNORING request from untrusted package "
 + packageName);
 return null;
 }
 
 return new BrowserRoot(Const.MEDIA_ID_ROOT, null);
 } MyMediaBrowserService.java
  • 40. Create Sliding Menus @Override
 public void onLoadChildren(final String pId, final Result<List<MediaItem>> result) {
 List<MediaItem> mediaItems = new ArrayList<>();
 if ("__ROOT__".equals(pId)) {
 mediaItems.add(new MediaItem(
 new MediaDescription.Builder()
 .setMediaId(Const.MEDIA_ID_ITEM1)
 .setTitle("Item 01")
 .setSubtitle("Some descriptions")
 .setIconUri(Uri.parse( "android.resource://my.package.name/drawable/icon"))
 .build(), MediaItem.FLAG_BROWSABLE
 ));
 mediaItems.add(new MediaItem(
 new MediaDescription.Builder()
 .setMediaId(Const.MEDIA_ID_ITEM2)
 .setTitle("Item 02")
 .setIconUri(Uri.parse( "android.resource://my.package.name/drawable/icon"))
 .build(), MediaItem.FLAG_PLAYABLE
 ));
 result.sendResult(mediaItems);
 }
 } MyMediaBrowserService.java (1/2)
  • 41. Create Sliding Menus private final class MediaSessionCallback extends MediaSession.Callback {
 
 @Override
 public void onPlayFromMediaId(String mediaId, Bundle extras) {
 if (Const.MEDIA_ID_ITEM2.equals(mediaId)) { // ...
 // Play media // ...
 }
 } // ...
 } MyMediaBrowserService.java (2/2)
  • 42.
  • 43. Create Sliding Menus (Async) @Override
 public void onLoadChildren(final String parentMediaId, final Result<List<MediaItem>> result) {
 result.detach();
 mMusicProvider.retrieveMediaAsync(new MusicProvider.Callback() {
 @Override
 public void onMusicCatalogReady() {
 List<MediaItem> mediaItems = new ArrayList<>();
 // ... // Prepare to create items // ...
 result.sendResult(mediaItems);
 }
 });
 } MyMediaBrowserService.java
  • 44. Setting Playback State PlaybackState.Builder stateBuilder = new PlaybackState.Builder();
 int playbackState = PlaybackState.STATE_PLAYING;
 
 long action = PlaybackState.ACTION_PAUSE;
 action |= PlaybackState.ACTION_SKIP_TO_NEXT;
 action |= PlaybackState.ACTION_SKIP_TO_PREVIOUS;
 stateBuilder.setActions(action);
 
 stateBuilder.setState(playbackState, -1, 1.0f);
 
 mSession.setPlaybackState(stateBuilder.build());
 
 MediaMetadata.Builder metaBuilder = new MediaMetadata.Builder();
 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
 metaBuilder.putBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART, bitmap);
 
 metaBuilder.putString(MediaMetadata.METADATA_KEY_ARTIST, "Great Artist");
 metaBuilder.putString(MediaMetadata.METADATA_KEY_TITLE, "Song 1");
 mSession.setMetadata(metaBuilder.build());
 
 mSession.setActive(true); MyMediaBrowserService.java
  • 45.
  • 46. Show Error Message PlaybackState.Builder stateBuilder = new PlaybackState.Builder();
 int playbackState = PlaybackState.STATE_ERROR;
 stateBuilder.setState(playbackState, -1, 1.0f);
 stateBuilder.setErrorMessage("Oh no! Something has gone wrong.");
 mSession.setPlaybackState(stateBuilder.build()); MyMediaBrowserService.java
  • 47. Playing Queue ArrayList<MediaMetadata> mediaMetadatas = new ArrayList<>();
 for (int i = 0; i < 5; i++) {
 String coverUrl = "android.resource://my.package.name/drawable/icon";
 MediaMetadata.Builder builder = new MediaMetadata.Builder();
 builder.putString(MediaMetadata.METADATA_KEY_ALBUM_ART_URI, coverUrl);
 builder.putString(MediaMetadata.METADATA_KEY_ARTIST, "Great artist");
 builder.putString(MediaMetadata.METADATA_KEY_TITLE, "Song " + (i + 1));
 MediaMetadata metadata = builder.build();
 mediaMetadatas.add(metadata);
 } MyMediaBrowserService.java (1/2)
  • 48. Playing Queue List<MediaSession.QueueItem> queue = convertToQueue(mediaMetadatas);
 mSession.setQueue(queue);
 mSession.setQueueTitle("Now Playing"); private static List<MediaSession.QueueItem> convertToQueue(
 Iterable<MediaMetadata> tracks) {
 List<MediaSession.QueueItem> queue = new ArrayList<>();
 int count = 0;
 for (MediaMetadata track : tracks) {
 
 String hierarchyAwareMediaID = "";
 
 MediaMetadata trackCopy = new MediaMetadata.Builder(track)
 .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, hierarchyAwareMediaID)
 .build();
 
 MediaSession.QueueItem item = new MediaSession.QueueItem(
 trackCopy.getDescription(), count++);
 queue.add(item);
 }
 return queue;
 } MyMediaBrowserService.java (2/2)
  • 49.
  • 51.
  • 53.
  • 54. Ok Google, Listen Jazz music on <YourApp>
  • 55. MediaSession Callback private final class MediaSessionCallback extends MediaSession.Callback { 
 @Override
 public void onPlayFromSearch(final String query, final Bundle extras) { // Perform voice actions
 }
 } MyMediaBrowserService.java
  • 56. Semantic Analysis GOOGLE KNOWLEDGE GRAPH Play music from Lady Gaga. Play Jazz music. Play Starships 
 from Nicki Minaj. Artist Extras Genre Extras Song name Extras
  • 57. Examples ▸ MediaBrowserService ▸ https://github.com/googlesamples/android-MediaBrowserService/ ▸ UniversalMusicPlayer ▸ https://github.com/googlesamples/android-UniversalMusicPlayer
  • 59.
  • 60. Create MessageReceivers AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="my.package.name">
 
 <application>
 <!-- ... -->
 <meta-data android:name="com.google.android.gms.car.application"
 android:resource="@xml/automotive_app_desc"/>
 
 <receiver
 android:name=".MessageReadReceiver"
 android:exported="false">
 <intent-filter>
 <action android:name="my.package.name.ACTION_MESSAGE_READ"/>
 </intent-filter>
 </receiver>
 
 <receiver
 android:name=".MessageReplyReceiver"
 android:exported="false">
 <intent-filter>
 <action android:name="my.package.name.ACTION_MESSAGE_REPLY"/>
 </intent-filter>
 </receiver>
 </application>
 </manifest> (1/2)
  • 61. automotive_app_desc.xml <?xml version="1.0" encoding="utf-8"?>
 <automotiveApp>
 <uses name="notification"/>
 </automotiveApp> Create MessageReceivers (2/2)
  • 62. MessageReadReceiver public class MessageReadReceiver extends BroadcastReceiver {
 
 @Override
 public void onReceive(Context context, Intent intent) {
 int conversationId = intent.getIntExtra(Const.CONVERSATION_ID, -1);
 if (conversationId != -1) {
 // Actions with conversation was read
 }
 }
 } MessageReadReceiver.java
  • 63. MessageReplyReceiver public class MessageReplyReceiver extends BroadcastReceiver {
 @Override
 public void onReceive(Context context, Intent intent) {
 if (Const.REPLY_ACTION.equals(intent.getAction())) {
 int conversationId = intent.getIntExtra(Const.CONVERSATION_ID, -1);
 
 Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
 CharSequence reply = "";
 if (remoteInput != null) {
 reply = remoteInput.getCharSequence(
 Const.EXTRA_REMOTE_REPLY);
 }
 if (conversationId != -1) {
 // Actions for receive reply message
 }
 }
 }
 } MessageReplyReceiver.java
  • 64. Prepare PendingIntent int conversationId = 1;
 String name = "Johnny";
 String message = "Hello, World!"; // A pending Intent for reads
 Intent readIntent = new Intent()
 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
 .setAction(Const.READ_ACTION)
 .putExtra(Const.CONVERSATION_ID, conversationId);
 
 PendingIntent readPendingIntent = PendingIntent.getBroadcast(this,
 conversationId,
 readIntent,
 PendingIntent.FLAG_UPDATE_CURRENT); MainActivity.java (1/2)
  • 65. Prepare PendingIntent // Build a RemoteInput for receiving voice input in a Car Notification
 RemoteInput remoteInput = new RemoteInput.Builder(Const.EXTRA_REMOTE_REPLY)
 .setLabel(getString(R.string.reply))
 .build();
 
 // Building a Pending Intent for the reply action to trigger
 Intent replyIntent = new Intent()
 .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
 .setAction(Const.REPLY_ACTION)
 .putExtra(Const.CONVERSATION_ID, conversationId);
 
 PendingIntent replyPendingIntent = PendingIntent.getBroadcast(this,
 conversationId,
 replyIntent,
 PendingIntent.FLAG_UPDATE_CURRENT); MainActivity.java (2/2)
  • 66. Build CarExtender & UnreadConversion // Create the UnreadConversation and populate it with the participant name,
 // read and reply intents.
 NotificationCompat.CarExtender.UnreadConversation.Builder unreadConvBuilder =
 new NotificationCompat.CarExtender.UnreadConversation.Builder(name)
 .setLatestTimestamp(System.currentTimeMillis())
 .setReadPendingIntent(readPendingIntent)
 .setReplyAction(replyPendingIntent, remoteInput)
 .addMessage(message);
 
 NotificationCompat.CarExtender carExtender = new NotificationCompat.CarExtender()
 .setUnreadConversation(unreadConvBuilder.build()); MainActivity.java
  • 67. Make a Notification NotificationCompat.Action replyAction = new NotificationCompat.Action.Builder(
 R.drawable.icon, getString(R.string.reply), replyPendingIntent)
 .addRemoteInput(remoteInput)
 .build(); NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
 .setSmallIcon(R.drawable.icon)
 .setLargeIcon(BitmapFactory.decodeResource(
 getResources(), R.drawable.icon_big))
 .setContentText(message)
 .setWhen(System.currentTimeMillis())
 .setContentTitle(name)
 .setContentIntent(readPendingIntent)
 .extend(carExtender)
 .addAction(replyAction);
 
 NotificationManagerCompat manager = NotificationManagerCompat.from(this);
 manager.notify(conversationId, builder.build()); MainActivity.java
  • 69. DEMO
  • 70. Q & A