অ্যাপটি যখন ফোরগ্রাউন্ডে না থাকে তখন মিডিয়া চালানো প্রায়শই কাম্য। উদাহরণস্বরূপ, ব্যবহারকারী যখন তাদের ডিভাইস লক করে রাখেন বা অন্য কোনও অ্যাপ ব্যবহার করেন তখন একটি মিউজিক প্লেয়ার সাধারণত সঙ্গীত বাজাতে থাকে। Media3 লাইব্রেরি এমন কিছু ইন্টারফেস সরবরাহ করে যা আপনাকে ব্যাকগ্রাউন্ড প্লেব্যাক সমর্থন করার অনুমতি দেয়।
একটি মিডিয়াসেশন সার্ভিস ব্যবহার করুন
ব্যাকগ্রাউন্ড প্লেব্যাক সক্ষম করতে, আপনার Player এবং MediaSession একটি পৃথক পরিষেবার মধ্যে রাখা উচিত। এটি আপনার অ্যাপটি ফোরগ্রাউন্ডে না থাকা সত্ত্বেও ডিভাইসটিকে মিডিয়া পরিবেশন চালিয়ে যেতে দেয়।

MediaSessionService অ্যাপের কার্যকলাপ থেকে মিডিয়া সেশন আলাদাভাবে চালানোর অনুমতি দেয়। কোনও সার্ভিসের ভেতরে প্লেয়ার হোস্ট করার সময়, আপনার একটি MediaSessionService ব্যবহার করা উচিত। এটি করার জন্য, এমন একটি ক্লাস তৈরি করুন যা MediaSessionService প্রসারিত করে এবং এর ভেতরে আপনার মিডিয়া সেশন তৈরি করুন।
MediaSessionService ব্যবহারের ফলে Google Assistant, সিস্টেম মিডিয়া কন্ট্রোল, পেরিফেরাল ডিভাইসের মিডিয়া বোতাম, অথবা Wear OS এর মতো কম্প্যানিয়ন ডিভাইসের মতো বহিরাগত ক্লায়েন্টদের জন্য আপনার অ্যাপের UI অ্যাক্টিভিটি অ্যাক্সেস না করেই আপনার পরিষেবা আবিষ্কার করা, এর সাথে সংযোগ স্থাপন করা এবং প্লেব্যাক নিয়ন্ত্রণ করা সম্ভব হয়। আসলে, একই MediaSessionService সাথে একই সময়ে একাধিক ক্লায়েন্ট অ্যাপ সংযুক্ত থাকতে পারে, প্রতিটি অ্যাপের নিজস্ব MediaController থাকে।
পরিষেবা জীবনচক্র বাস্তবায়ন করুন
আপনার পরিষেবার দুটি জীবনচক্র পদ্ধতি বাস্তবায়ন করতে হবে:
- যখন প্রথম কন্ট্রোলারটি সংযোগ করতে থাকে এবং পরিষেবাটি চালু এবং চালু হয় তখন
onCreate()কল করা হয়। এটিPlayerএবংMediaSessionতৈরির জন্য সেরা জায়গা। - যখন পরিষেবাটি বন্ধ করা হচ্ছে তখন
onDestroy()কল করা হয়। প্লেয়ার এবং সেশন সহ সমস্ত রিসোর্স প্রকাশ করতে হবে।
ব্যবহারকারী যখন সাম্প্রতিক কাজগুলি থেকে অ্যাপটি বাতিল করে তখন কী ঘটে তা কাস্টমাইজ করার জন্য আপনি ঐচ্ছিকভাবে onTaskRemoved(Intent) ওভাররাইড করতে পারেন। ডিফল্টরূপে, প্লেব্যাক চলমান থাকলে পরিষেবাটি চালু থাকে এবং অন্যথায় বন্ধ হয়ে যায়।
কোটলিন
class PlaybackService : MediaSessionService() { private var mediaSession: MediaSession? = null // Create your player and media session in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaSession = MediaSession.Builder(this, player).build() } // Remember to release the player and media session in onDestroy override fun onDestroy() { mediaSession?.run { player.release() release() mediaSession = null } super.onDestroy() } }
জাভা
public class PlaybackService extends MediaSessionService { private MediaSession mediaSession = null; // Create your Player and MediaSession in the onCreate lifecycle event @Override public void onCreate() { super.onCreate(); ExoPlayer player = new ExoPlayer.Builder(this).build(); mediaSession = new MediaSession.Builder(this, player).build(); } // Remember to release the player and media session in onDestroy @Override public void onDestroy() { mediaSession.getPlayer().release(); mediaSession.release(); mediaSession = null; super.onDestroy(); } }
ব্যাকগ্রাউন্ডে প্লেব্যাক চালু রাখার বিকল্প হিসেবে, ব্যবহারকারী অ্যাপটি বন্ধ করলে আপনি যেকোনো পরিস্থিতিতে পরিষেবাটি বন্ধ করতে পারেন:
কোটলিন
override fun onTaskRemoved(rootIntent: Intent?) { pauseAllPlayersAndStopSelf() }
জাভা
@Override public void onTaskRemoved(@Nullable Intent rootIntent) { pauseAllPlayersAndStopSelf(); }
onTaskRemoved এর অন্য যেকোনো ম্যানুয়াল বাস্তবায়নের জন্য, আপনি isPlaybackOngoing() ব্যবহার করে প্লেব্যাকটি চলমান বলে বিবেচিত হচ্ছে কিনা এবং ফোরগ্রাউন্ড পরিষেবা শুরু হয়েছে কিনা তা পরীক্ষা করতে পারেন।
মিডিয়া সেশনে প্রবেশাধিকার প্রদান করুন
পরিষেবাটি তৈরির সময় তৈরি করা আপনার মিডিয়া সেশনে অন্যান্য ক্লায়েন্টদের অ্যাক্সেস দেওয়ার জন্য onGetSession() পদ্ধতিটি ওভাররাইড করুন।
কোটলিন
class PlaybackService : MediaSessionService() { private var mediaSession: MediaSession? = null // [...] lifecycle methods omitted override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? = mediaSession }
জাভা
public class PlaybackService extends MediaSessionService { private MediaSession mediaSession = null; // [...] lifecycle methods omitted @Override public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) { return mediaSession; } }
ম্যানিফেস্টে পরিষেবাটি ঘোষণা করুন
একটি অ্যাপের প্লেব্যাক ফোরগ্রাউন্ড পরিষেবা চালানোর জন্য FOREGROUND_SERVICE এবং FOREGROUND_SERVICE_MEDIA_PLAYBACK অনুমতি প্রয়োজন:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
আপনাকে ম্যানিফেস্টে MediaSessionService এর একটি ইন্টেন্ট ফিল্টার এবং mediaPlayback অন্তর্ভুক্ত একটি foregroundServiceType সহ আপনার Service ক্লাসটিও ঘোষণা করতে হবে।
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
MediaController ব্যবহার করে প্লেব্যাক নিয়ন্ত্রণ করুন
আপনার প্লেয়ার UI ধারণকারী Activity অথবা Fragment-এ, আপনি MediaController ব্যবহার করে UI এবং আপনার মিডিয়া সেশনের মধ্যে একটি লিঙ্ক স্থাপন করতে পারেন। আপনার UI আপনার UI থেকে সেশনের মধ্যে প্লেয়ারে কমান্ড পাঠাতে মিডিয়া কন্ট্রোলার ব্যবহার করে। MediaController তৈরি এবং ব্যবহার সম্পর্কে বিস্তারিত জানতে Create a MediaController নির্দেশিকাটি দেখুন।
MediaController কমান্ড পরিচালনা করুন
MediaSession তার MediaSession.Callback মাধ্যমে কন্ট্রোলার থেকে কমান্ড গ্রহণ করে। একটি MediaSession শুরু করলে MediaSession.Callback এর একটি ডিফল্ট বাস্তবায়ন তৈরি হয় যা আপনার প্লেয়ারে MediaController দ্বারা প্রেরিত সমস্ত কমান্ড স্বয়ংক্রিয়ভাবে পরিচালনা করে।
বিজ্ঞপ্তি
একটি MediaSessionService স্বয়ংক্রিয়ভাবে আপনার জন্য একটি MediaNotification তৈরি করে যা বেশিরভাগ ক্ষেত্রেই কাজ করবে। ডিফল্টরূপে, প্রকাশিত বিজ্ঞপ্তিটি একটি MediaStyle বিজ্ঞপ্তি যা আপনার মিডিয়া সেশনের সর্বশেষ তথ্যের সাথে আপডেট থাকে এবং প্লেব্যাক নিয়ন্ত্রণগুলি প্রদর্শন করে। MediaNotification আপনার সেশন সম্পর্কে সচেতন এবং একই সেশনের সাথে সংযুক্ত অন্য যেকোনো অ্যাপের প্লেব্যাক নিয়ন্ত্রণ করতে ব্যবহার করা যেতে পারে।
উদাহরণস্বরূপ, MediaSessionService ব্যবহার করে একটি মিউজিক স্ট্রিমিং অ্যাপ একটি MediaNotification তৈরি করবে যা আপনার MediaSession কনফিগারেশনের উপর ভিত্তি করে প্লেব্যাক নিয়ন্ত্রণের পাশাপাশি বর্তমান মিডিয়া আইটেমের শিরোনাম, শিল্পী এবং অ্যালবাম আর্ট প্রদর্শন করবে।
প্রয়োজনীয় মেটাডেটা মিডিয়াতে সরবরাহ করা যেতে পারে অথবা নিম্নলিখিত স্নিপেটের মতো মিডিয়া আইটেমের অংশ হিসাবে ঘোষণা করা যেতে পারে:
কোটলিন
val mediaItem = MediaItem.Builder() .setMediaId("media-1") .setUri(mediaUri) .setMediaMetadata( MediaMetadata.Builder() .setArtist("David Bowie") .setTitle("Heroes") .setArtworkUri(artworkUri) .build() ) .build() mediaController.setMediaItem(mediaItem) mediaController.prepare() mediaController.play()
জাভা
MediaItem mediaItem = new MediaItem.Builder() .setMediaId("media-1") .setUri(mediaUri) .setMediaMetadata( new MediaMetadata.Builder() .setArtist("David Bowie") .setTitle("Heroes") .setArtworkUri(artworkUri) .build()) .build(); mediaController.setMediaItem(mediaItem); mediaController.prepare(); mediaController.play();
বিজ্ঞপ্তির জীবনচক্র
Player প্লেলিস্টে MediaItem ইনস্ট্যান্স থাকা মাত্রই বিজ্ঞপ্তিটি তৈরি করা হয়।
Player এবং MediaSession অবস্থার উপর ভিত্তি করে সমস্ত বিজ্ঞপ্তি আপডেট স্বয়ংক্রিয়ভাবে ঘটে।
ফোরগ্রাউন্ড পরিষেবা চলাকালীন বিজ্ঞপ্তিটি সরানো যাবে না। বিজ্ঞপ্তিটি অবিলম্বে সরাতে, আপনাকে Player.release() এ কল করতে হবে অথবা Player.clearMediaItems() ব্যবহার করে প্লেলিস্টটি সাফ করতে হবে।
যদি প্লেয়ারটি ১০ মিনিটেরও বেশি সময় ধরে পজ, থামানো বা ব্যর্থ হয়, তবে ব্যবহারকারীর সাথে আরও কোনও ইন্টারঅ্যাকশন ছাড়াই পরিষেবাটি স্বয়ংক্রিয়ভাবে ফোরগ্রাউন্ড পরিষেবা অবস্থা থেকে বেরিয়ে আসে যাতে সিস্টেমটি এটি ধ্বংস করতে পারে। আপনি প্লেব্যাক পুনঃসূচনা বাস্তবায়ন করতে পারেন যাতে ব্যবহারকারী পরিষেবা জীবনচক্র পুনরায় চালু করতে পারেন এবং পরবর্তী সময়ে প্লেব্যাক পুনরায় শুরু করতে পারেন।
বিজ্ঞপ্তি কাস্টমাইজেশন
বর্তমানে চলমান আইটেমটির মেটাডেটা MediaItem.MediaMetadata পরিবর্তন করে কাস্টমাইজ করা যেতে পারে। যদি আপনি কোনও বিদ্যমান আইটেমের মেটাডেটা আপডেট করতে চান, তাহলে প্লেব্যাক ব্যাহত না করে মেটাডেটা আপডেট করতে Player.replaceMediaItem ব্যবহার করতে পারেন।
আপনি অ্যান্ড্রয়েড মিডিয়া নিয়ন্ত্রণের জন্য কাস্টম মিডিয়া বোতাম পছন্দগুলি সেট করে বিজ্ঞপ্তিতে দেখানো কিছু বোতাম কাস্টমাইজ করতে পারেন। অ্যান্ড্রয়েড মিডিয়া নিয়ন্ত্রণগুলি কাস্টমাইজ করার বিষয়ে আরও পড়ুন ।
বিজ্ঞপ্তিটি আরও কাস্টমাইজ করতে, DefaultMediaNotificationProvider.Builder দিয়ে একটি MediaNotification.Provider তৈরি করুন অথবা প্রোভাইডার ইন্টারফেসের একটি কাস্টম বাস্তবায়ন তৈরি করুন। setMediaNotificationProvider দিয়ে আপনার প্রোভাইডারকে আপনার MediaSessionService এ যুক্ত করুন।
প্লেব্যাক পুনঃসূচনা
MediaSessionService বন্ধ হয়ে যাওয়ার পরে, এবং ডিভাইসটি রিবুট করার পরেও, ব্যবহারকারীদের পরিষেবাটি পুনরায় চালু করতে এবং যেখানে ছেড়েছিলেন সেখানে প্লেব্যাক পুনরায় শুরু করতে প্লেব্যাক পুনঃসূচনা অফার করা সম্ভব। ডিফল্টরূপে, প্লেব্যাক পুনঃসূচনা বন্ধ থাকে। এর অর্থ হল আপনার পরিষেবাটি চালু না থাকলে ব্যবহারকারী প্লেব্যাক পুনরায় শুরু করতে পারবেন না। এই বৈশিষ্ট্যটি অপ্ট-ইন করতে, আপনাকে একটি মিডিয়া বোতাম রিসিভার ঘোষণা করতে হবে এবং onPlaybackResumption পদ্ধতিটি বাস্তবায়ন করতে হবে।
Media3 মিডিয়া বোতাম রিসিভার ঘোষণা করুন
আপনার ম্যানিফেস্টে MediaButtonReceiver ঘোষণা করে শুরু করুন:
<receiver android:name="androidx.media3.session.MediaButtonReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
প্লেব্যাক পুনঃসূচনা কলব্যাক বাস্তবায়ন করুন
যখন কোনও ব্লুটুথ ডিভাইস অথবা অ্যান্ড্রয়েড সিস্টেম UI রিজিউমেশন বৈশিষ্ট্য দ্বারা প্লেব্যাক পুনঃসূচনা অনুরোধ করা হয়, তখন onPlaybackResumption() কলব্যাক পদ্ধতিটি কল করা হয়।
কোটলিন
override fun onPlaybackResumption( mediaSession: MediaSession, controller: ControllerInfo ): ListenableFuture<MediaItemsWithStartPosition> { val settable = SettableFuture.create<MediaItemsWithStartPosition>() scope.launch { // Your app is responsible for storing the playlist, metadata (like title // and artwork) of the current item and the start position to use here. val resumptionPlaylist = restorePlaylist() settable.set(resumptionPlaylist) } return settable }
জাভা
@Override public ListenableFuture<MediaItemsWithStartPosition> onPlaybackResumption( MediaSession mediaSession, ControllerInfo controller ) { SettableFuture<MediaItemsWithStartPosition> settableFuture = SettableFuture.create(); settableFuture.addListener(() -> { // Your app is responsible for storing the playlist, metadata (like title // and artwork) of the current item and the start position to use here. MediaItemsWithStartPosition resumptionPlaylist = restorePlaylist(); settableFuture.set(resumptionPlaylist); }, MoreExecutors.directExecutor()); return settableFuture; }
যদি আপনি প্লেব্যাক স্পিড, রিপিট মোড, অথবা শাফেল মোডের মতো অন্যান্য প্যারামিটার সংরক্ষণ করে থাকেন, তাহলে onPlaybackResumption() হল মিডিয়া3 প্লেয়ার প্রস্তুত করার আগে এবং কলব্যাক সম্পূর্ণ হওয়ার পরে প্লেব্যাক শুরু করার আগে এই প্যারামিটারগুলি দিয়ে প্লেয়ার কনফিগার করার জন্য একটি ভাল জায়গা।
ডিভাইসটি রিবুট করার পরে অ্যান্ড্রয়েড সিস্টেম UI পুনঃসূচনা বিজ্ঞপ্তি তৈরি করার জন্য বুট করার সময় এই পদ্ধতিটি ব্যবহার করা হয়। একটি সমৃদ্ধ বিজ্ঞপ্তির জন্য, স্থানীয়ভাবে উপলব্ধ মান সহ বর্তমান আইটেমের title এবং artworkData বা artworkUri এর মতো MediaMetadata ক্ষেত্রগুলি পূরণ করার পরামর্শ দেওয়া হয়, কারণ নেটওয়ার্ক অ্যাক্সেস এখনও উপলব্ধ নাও হতে পারে। পুনঃসূচনা প্লেব্যাক অবস্থান নির্দেশ করতে আপনি MediaMetadata.extras এ MediaConstants.EXTRAS_KEY_COMPLETION_STATUS এবং MediaConstants.EXTRAS_KEY_COMPLETION_PERCENTAGE যোগ করতে পারেন।
উন্নত নিয়ামক কনফিগারেশন এবং পশ্চাদমুখী সামঞ্জস্যতা
একটি সাধারণ পরিস্থিতি হল প্লেব্যাক নিয়ন্ত্রণ এবং প্লেলিস্ট প্রদর্শনের জন্য অ্যাপ UI-তে একটি MediaController ব্যবহার করা। একই সময়ে, সেশনটি মোবাইল বা টিভিতে Android মিডিয়া কন্ট্রোল এবং Assistant, ঘড়ির জন্য Wear OS এবং গাড়িতে Android Auto-এর মতো বহিরাগত ক্লায়েন্টদের কাছে উন্মুক্ত করা হয়। Media3 সেশন ডেমো অ্যাপটি এমন একটি অ্যাপের উদাহরণ যা এই ধরনের পরিস্থিতি বাস্তবায়ন করে।
এই বহিরাগত ক্লায়েন্টরা লিগ্যাসি AndroidX লাইব্রেরির MediaControllerCompat বা Android প্ল্যাটফর্মের android.media.session.MediaController এর মতো API ব্যবহার করতে পারে। Media3 লিগ্যাসি লাইব্রেরির সাথে সম্পূর্ণরূপে ব্যাকওয়ার্ড সামঞ্জস্যপূর্ণ এবং অ্যান্ড্রয়েড প্ল্যাটফর্ম API এর সাথে আন্তঃকার্যক্ষমতা প্রদান করে।
মিডিয়া নোটিফিকেশন কন্ট্রোলার ব্যবহার করুন
এটা বোঝা গুরুত্বপূর্ণ যে এই লিগ্যাসি এবং প্ল্যাটফর্ম কন্ট্রোলারগুলির অবস্থা একই এবং দৃশ্যমানতা কন্ট্রোলার দ্বারা কাস্টমাইজ করা যায় না (উদাহরণস্বরূপ উপলব্ধ PlaybackState.getActions() এবং PlaybackState.getCustomActions() )। আপনি এই লিগ্যাসি এবং প্ল্যাটফর্ম কন্ট্রোলারগুলির সাথে সামঞ্জস্যের জন্য প্ল্যাটফর্ম মিডিয়া সেশনে স্টেট সেট কনফিগার করতে মিডিয়া নোটিফিকেশন কন্ট্রোলার ব্যবহার করতে পারেন।
উদাহরণস্বরূপ, একটি অ্যাপ প্ল্যাটফর্ম সেশনের জন্য বিশেষভাবে উপলব্ধ কমান্ড এবং মিডিয়া বোতাম পছন্দগুলি সেট করার জন্য MediaSession.Callback.onConnect() এর একটি বাস্তবায়ন প্রদান করতে পারে:
কোটলিন
override fun onConnect( session: MediaSession, controller: MediaSession.ControllerInfo ): ConnectionResult { if (session.isMediaNotificationController(controller)) { val sessionCommands = ConnectionResult.DEFAULT_SESSION_COMMANDS.buildUpon() .add(customCommandSeekBackward) .add(customCommandSeekForward) .build() val playerCommands = ConnectionResult.DEFAULT_PLAYER_COMMANDS.buildUpon() .remove(COMMAND_SEEK_TO_PREVIOUS) .remove(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM) .remove(COMMAND_SEEK_TO_NEXT) .remove(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM) .build() // Custom button preferences and commands to configure the platform session. return AcceptedResultBuilder(session) .setMediaButtonPreferences( ImmutableList.of( createSeekBackwardButton(customCommandSeekBackward), createSeekForwardButton(customCommandSeekForward)) ) .setAvailablePlayerCommands(playerCommands) .setAvailableSessionCommands(sessionCommands) .build() } // Default commands with default button preferences for all other controllers. return AcceptedResultBuilder(session).build() }
জাভা
@Override public ConnectionResult onConnect( MediaSession session, MediaSession.ControllerInfo controller) { if (session.isMediaNotificationController(controller)) { SessionCommands sessionCommands = ConnectionResult.DEFAULT_SESSION_COMMANDS .buildUpon() .add(customCommandSeekBackward) .add(customCommandSeekForward) .build(); Player.Commands playerCommands = ConnectionResult.DEFAULT_PLAYER_COMMANDS .buildUpon() .remove(COMMAND_SEEK_TO_PREVIOUS) .remove(COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM) .remove(COMMAND_SEEK_TO_NEXT) .remove(COMMAND_SEEK_TO_NEXT_MEDIA_ITEM) .build(); // Custom button preferences and commands to configure the platform session. return new AcceptedResultBuilder(session) .setMediaButtonPreferences( ImmutableList.of( createSeekBackwardButton(customCommandSeekBackward), createSeekForwardButton(customCommandSeekForward))) .setAvailablePlayerCommands(playerCommands) .setAvailableSessionCommands(sessionCommands) .build(); } // Default commands with default button preferences for all other controllers. return new AcceptedResultBuilder(session).build(); }
কাস্টম কমান্ড পাঠানোর জন্য Android Auto-কে অনুমোদন দিন
MediaLibraryService ব্যবহার করার সময় এবং মোবাইল অ্যাপের মাধ্যমে Android Auto সমর্থন করার জন্য, Android Auto কন্ট্রোলারের উপযুক্ত উপলব্ধ কমান্ডের প্রয়োজন হয়, অন্যথায় Media3 সেই কন্ট্রোলার থেকে আগত কাস্টম কমান্ডগুলিকে অস্বীকার করবে:
কোটলিন
override fun onConnect( session: MediaSession, controller: MediaSession.ControllerInfo ): ConnectionResult { val sessionCommands = ConnectionResult.DEFAULT_SESSION_AND_LIBRARY_COMMANDS.buildUpon() .add(customCommandSeekBackward) .add(customCommandSeekForward) .build() if (session.isMediaNotificationController(controller)) { // [...] See above. } else if (session.isAutoCompanionController(controller)) { // Available session commands to accept incoming custom commands from Auto. return AcceptedResultBuilder(session) .setAvailableSessionCommands(sessionCommands) .build() } // Default commands for all other controllers. return AcceptedResultBuilder(session).build() }
জাভা
@Override public ConnectionResult onConnect( MediaSession session, MediaSession.ControllerInfo controller) { SessionCommands sessionCommands = ConnectionResult.DEFAULT_SESSION_COMMANDS .buildUpon() .add(customCommandSeekBackward) .add(customCommandSeekForward) .build(); if (session.isMediaNotificationController(controller)) { // [...] See above. } else if (session.isAutoCompanionController(controller)) { // Available commands to accept incoming custom commands from Auto. return new AcceptedResultBuilder(session) .setAvailableSessionCommands(sessionCommands) .build(); } // Default commands for all other controllers. return new AcceptedResultBuilder(session).build(); }
সেশন ডেমো অ্যাপটিতে একটি অটোমোটিভ মডিউল রয়েছে, যা অটোমোটিভ অপারেটিং সিস্টেমের জন্য সমর্থন প্রদর্শন করে যার জন্য একটি পৃথক APK প্রয়োজন।