Google Assistant ও মিডিয়া অ্যাপ

Google Assistant-এর সাহায্যে আপনি ভয়েস কমান্ড ব্যবহার করে অনেক ডিভাইস কন্ট্রোল করতে পারবেন, যেমন Google Home, আপনার ফোন এবং আরও অনেক কিছু। এতে মিডিয়া কমান্ড ("Beyoncé-র কিছু চালাও") বোঝার বিল্ট-ইন ক্ষমতা আছে এবং এটি মিডিয়া কন্ট্রোল (যেমন পজ, এড়িয়ে যাওয়া, ফাস্ট ফরওয়ার্ড, থাম্বস-আপ) সাপোর্ট করে।

Assistant মিডিয়া সেশন ব্যবহার করে Android মিডিয়া অ্যাপের সাথে যোগাযোগ করে। এটি আপনার অ্যাপ চালু করতে এবং প্লেব্যাক শুরু করতে ইনটেন্ট বা পরিষেবা ব্যবহার করতে পারে। সেরা ফলাফলের জন্য, আপনার অ্যাপে এই পৃষ্ঠায় বর্ণনা করা সব ফিচার প্রয়োগ করা উচিত।

মিডিয়া সেশন ব্যবহার করা

প্রতিটি অডিও এবং ভিডিও অ্যাপে অবশ্যই একটি মিডিয়া সেশন চালু করতে হবে যাতে প্লেব্যাক শুরু হওয়ার পরে Assistant ট্রান্সপোর্ট কন্ট্রোল অপারেট করতে পারে।

মনে রাখবেন, Assistant শুধুমাত্র এই বিভাগে তালিকাভুক্ত অ্যাকশন ব্যবহার করলেও, অন্যান্য অ্যাপ্লিকেশনের সাথে মানানসই কিনা তা নিশ্চিত করার জন্য সমস্ত প্রস্তুতি এবং প্লেব্যাক API প্রয়োগ করা সবচেয়ে ভালো পদ্ধতি। আপনি সমর্থন করেন না এমন কোনও অ্যাকশনের জন্য, মিডিয়া সেশন কলব্যাকগুলি কেবল ERROR_CODE_NOT_SUPPORTED ব্যবহার করে একটি ত্রুটি ফেরত দিতে পারে।

আপনার অ্যাপের MediaSession অবজেক্টে এইসব ফ্ল্যাগ সেট করে মিডিয়া ও ট্রান্সপোর্ট কন্ট্রোল চালু করুন:

Kotlin

session.setFlags(
        MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS or
        MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS
)

জাভা

session.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS |
    MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);

আপনার অ্যাপের মিডিয়া সেশনকে অবশ্যই এটি যেসব অ্যাকশন সাপোর্ট করে তা ঘোষণা করতে হবে এবং সংশ্লিষ্ট মিডিয়া সেশন কলব্যাক প্রয়োগ করতে হবে। setActions()-এ আপনার কাজ করে এমন অ্যাকশন ঘোষণা করুন।

Universal Android Music Player স্যাম্পেল প্রোজেক্ট হল মিডিয়া সেশন সেট-আপ করার একটি ভালো উদাহরণ।

প্লেব্যাক অ্যাকশন

কোনও পরিষেবা থেকে প্লেব্যাক শুরু করতে, মিডিয়া সেশনে অবশ্যই এইসব PLAY অ্যাকশন ও তাদের কলব্যাক থাকতে হবে:

অ্যাকশন কলব্যাক
ACTION_PLAY onPlay()
ACTION_PLAY_FROM_SEARCH onPlayFromSearch()
ACTION_PLAY_FROM_URI (*) onPlayFromUri()

এছাড়াও, আপনার সেশনকে এইসব PREPARE অ্যাকশন ও তাদের কলব্যাক প্রয়োগ করতে হবে:

অ্যাকশন কলব্যাক
ACTION_PREPARE onPrepare()
ACTION_PREPARE_FROM_SEARCH onPrepareFromSearch()
ACTION_PREPARE_FROM_URI (*) onPrepareFromUri()

(*) Google Assistant URI-ভিত্তিক অ্যাকশন শুধুমাত্র সেইসব কোম্পানির জন্য কাজ করে যারা Google-কে URI প্রদান করে। Google-এ আপনার মিডিয়া কন্টেন্ট বর্ণনা করার ব্যাপারে আরও জানতে মিডিয়া অ্যাকশন দেখুন।

প্রস্তুতি API প্রয়োগ করে, ভয়েস কমান্ডের পরে প্লেব্যাক লেটেন্সি কমানো যেতে পারে। যেসব মিডিয়া অ্যাপ প্লেব্যাক লেটেন্সি উন্নত করতে চায়, সেগুলি কন্টেন্ট ক্যাশে করা এবং মিডিয়া প্লেব্যাক প্রস্তুত করার জন্য অতিরিক্ত সময় ব্যবহার করতে পারে।

সার্চ কোয়েরি পার্স করুন

কোনও ব্যবহারকারী নির্দিষ্ট মিডিয়া আইটেম সার্চ করলে, যেমন “ [আপনার অ্যাপের নাম]-এ জ্যাজ মিউজিক চালাও” অথবা “[গানের নাম] শোনো”, onPrepareFromSearch() অথবা onPlayFromSearch() কলব্যাক পদ্ধতি একটি কোয়েরি প্যারামিটার ও অতিরিক্ত বান্ডেল পায়।

আপনার অ্যাপের উচিত ভয়েস সার্চ কোয়েরি পার্স করা এবং এইসব ধাপ অনুসরণ করে প্লেব্যাক শুরু করা:

  1. ফলাফল ফিল্টার করতে, ভয়েস সার্চ থেকে পাওয়া অতিরিক্ত বান্ডেল ও সার্চ কোয়েরি স্ট্রিং ব্যবহার করুন।
  2. এইসব ফলাফলের ভিত্তিতে প্লেব্যাক সারি তৈরি করুন।
  3. ফলাফল থেকে সবচেয়ে প্রাসঙ্গিক মিডিয়া আইটেম চালান।

onPlayFromSearch() মেথড ভয়েস সার্চ থেকে আরও বিস্তারিত তথ্য সহ একটি অতিরিক্ত প্যারামিটার নেয়। এইসব এক্সট্রা আপনাকে অ্যাপে প্লেব্যাকের জন্য অডিও কন্টেন্ট খুঁজে পেতে সাহায্য করে। সার্চ ফলাফল এই ডেটা প্রদান করতে না পারলে, আপনি র সার্চ কোয়েরি পার্স করতে এবং কোয়েরির উপর ভিত্তি করে উপযুক্ত ট্র্যাক চালাতে লজিক প্রয়োগ করতে পারেন।

Android Automotive OS এবং Android Auto-তে নিম্নলিখিত অতিরিক্ত সুবিধা কাজ করে:

ভয়েস সার্চ কোয়েরি পার্স করতে এবং প্লেব্যাক শুরু করতে আপনার MediaSession.Callback ইমপ্লিমেন্টেশনে কীভাবে onPlayFromSearch() মেথড ওভাররাইড করতে হয় তা নিম্নলিখিত কোড স্নিপেট থেকে জানতে পারবেন:

Kotlin

override fun onPlayFromSearch(query: String?, extras: Bundle?) {
    if (query.isNullOrEmpty()) {
        // The user provided generic string e.g. 'Play music'
        // Build appropriate playlist queue
    } else {
        // Build a queue based on songs that match "query" or "extras" param
        val mediaFocus: String? = extras?.getString(MediaStore.EXTRA_MEDIA_FOCUS)
        if (mediaFocus == MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) {
            isArtistFocus = true
            artist = extras.getString(MediaStore.EXTRA_MEDIA_ARTIST)
        } else if (mediaFocus == MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) {
            isAlbumFocus = true
            album = extras.getString(MediaStore.EXTRA_MEDIA_ALBUM)
        }

        // Implement additional "extras" param filtering
    }

    // Implement your logic to retrieve the queue
    var result: String? = when {
        isArtistFocus -> artist?.also {
            searchMusicByArtist(it)
        }
        isAlbumFocus -> album?.also {
            searchMusicByAlbum(it)
        }
        else -> null
    }
    result = result ?: run {
        // No focus found, search by query for song title
        query?.also {
            searchMusicBySongTitle(it)
        }
    }

    if (result?.isNotEmpty() == true) {
        // Immediately start playing from the beginning of the search results
        // Implement your logic to start playing music
        playMusic(result)
    } else {
        // Handle no queue found. Stop playing if the app
        // is currently playing a song
    }
}

জাভা

@Override
public void onPlayFromSearch(String query, Bundle extras) {
    if (TextUtils.isEmpty(query)) {
        // The user provided generic string e.g. 'Play music'
        // Build appropriate playlist queue
    } else {
        // Build a queue based on songs that match "query" or "extras" param
        String mediaFocus = extras.getString(MediaStore.EXTRA_MEDIA_FOCUS);
        if (TextUtils.equals(mediaFocus,
                MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE)) {
            isArtistFocus = true;
            artist = extras.getString(MediaStore.EXTRA_MEDIA_ARTIST);
        } else if (TextUtils.equals(mediaFocus,
                MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE)) {
            isAlbumFocus = true;
            album = extras.getString(MediaStore.EXTRA_MEDIA_ALBUM);
        }

        // Implement additional "extras" param filtering
    }

    // Implement your logic to retrieve the queue
    if (isArtistFocus) {
        result = searchMusicByArtist(artist);
    } else if (isAlbumFocus) {
        result = searchMusicByAlbum(album);
    }

    if (result == null) {
        // No focus found, search by query for song title
        result = searchMusicBySongTitle(query);
    }

    if (result != null && !result.isEmpty()) {
        // Immediately start playing from the beginning of the search results
        // Implement your logic to start playing music
        playMusic(result);
    } else {
        // Handle no queue found. Stop playing if the app
        // is currently playing a song
    }
}

আপনার অ্যাপে অডিও কন্টেন্ট চালানোর জন্য কীভাবে ভয়েস সার্চ প্রয়োগ করবেন সেই সম্পর্কে আরও বিস্তারিত উদাহরণের জন্য, Universal Android Music Player স্যাম্পেল দেখুন।

ফাঁকা কোয়েরি ম্যানেজ করা

সার্চ কোয়েরি ছাড়া onPrepare(), onPlay(), onPrepareFromSearch(), অথবা onPlayFromSearch() কল করা হলে, আপনার মিডিয়া অ্যাপের "বর্তমান" মিডিয়া চালানো উচিত। বর্তমানে কোনও মিডিয়া না থাকলে, অ্যাপের কিছু চালানোর চেষ্টা করা উচিত, যেমন সবচেয়ে সাম্প্রতিক প্লেলিস্ট বা র‍্যান্ডম সারি থেকে কোনও গান। কোনও ব্যবহারকারী অতিরিক্ত তথ্য ছাড়াই “[আপনার অ্যাপের নাম]-এ মিউজিক চালাও” বললে, Assistant এইসব API ব্যবহার করে।

কোনও ব্যবহারকারী “Play music on [your app name]” বললে, Android Automotive OS বা Android Auto আপনার অ্যাপের onPlayFromSearch() মেথড কল করে আপনার অ্যাপ চালু করার এবং অডিও চালানোর চেষ্টা করে। তবে, ব্যবহারকারী মিডিয়া আইটেমের নাম না বলায়, onPlayFromSearch() মেথড একটি খালি কোয়েরি প্যারামিটার পায়। এইসব ক্ষেত্রে, আপনার অ্যাপকে অবিলম্বে অডিও চালানোর মাধ্যমে উত্তর দিতে হবে, যেমন সাম্প্রতিকতম প্লেলিস্ট বা র‍্যান্ডম সারি থেকে কোনও গান।

ভয়েস অ্যাকশনের জন্য পুরনো সহায়তা ঘোষণা করুন

বেশিরভাগ ক্ষেত্রে, উপরে বর্ণিত প্লেব্যাক অ্যাকশন ম্যানেজ করলে আপনার অ্যাপে প্লেব্যাক সংক্রান্ত সব প্রয়োজনীয় কার্যকারিতা পাওয়া যায়। তবে, কিছু সিস্টেমে সার্চের জন্য আপনার অ্যাপে ইনটেন্ট ফিল্টার থাকতে হয়। আপনার অ্যাপের ম্যানিফেস্ট ফাইলে এই ইনটেন্ট ফিল্টারের জন্য আপনাকে সহায়তা ঘোষণা করতে হবে।

ফোন অ্যাপের জন্য ম্যানিফেস্ট ফাইলে এই কোড অন্তর্ভুক্ত করুন:

<activity>
    <intent-filter>
        <action android:name=
             "android.media.action.MEDIA_PLAY_FROM_SEARCH" />
        <category android:name=
             "android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

ট্রান্সপোর্ট কন্ট্রোল

আপনার অ্যাপের মিডিয়া সেশন অ্যাক্টিভ হওয়ার পরে, Assistant প্লেব্যাক নিয়ন্ত্রণ ও মিডিয়া মেটাডেটা আপডেট করার জন্য ভয়েস কমান্ড দিতে পারে। এটি কাজ করার জন্য, আপনার কোডকে নিম্নলিখিত অ্যাকশন চালু করতে হবে এবং সংশ্লিষ্ট কলব্যাক প্রয়োগ করতে হবে:

অ্যাকশন কলব্যাক বর্ণনা
ACTION_SKIP_TO_NEXT onSkipToNext() পরবর্তী ভিডিও
ACTION_SKIP_TO_PREVIOUS onSkipToPrevious() পূর্ববর্তী গান
ACTION_PAUSE, ACTION_PLAY_PAUSE onPause() পজ করুন
ACTION_STOP onStop() বন্ধ করুন
ACTION_PLAY onPlay() আবার শুরু করুন
ACTION_SEEK_TO onSeekTo() ৩০ সেকেন্ড রিওয়াইন্ড করুন
ACTION_SET_RATING onSetRating(android.support.v4.media.RatingCompat) লাইক/ডিসলাইক।
ACTION_SET_CAPTIONING_ENABLED onSetCaptioningEnabled(boolean) ক্যাপশন চালু/বন্ধ করুন।

দয়া করে মনে রাখবেন:

  • খোঁজার কমান্ড কাজ করার জন্য, PlaybackState-কে state, position, playback speed, and update time-এর সাথে আপ-টু-ডেট হতে হবে। স্ট্যাটাস পরিবর্তন হলে অ্যাপকে অবশ্যই setPlaybackState() কল করতে হবে।
  • এছাড়াও, মিডিয়া অ্যাপকে অবশ্যই মিডিয়া সেশন মেটাডেটা আপ-টু-ডেট রাখতে হবে। এটি "কোন গান চলছে?" এই ধরনের প্রশ্নের উত্তর দেয় প্রযোজ্য ফিল্ড (যেমন ট্র্যাকের শীর্ষক, আর্টিস্ট ও নাম) পরিবর্তন হলে অ্যাপকে অবশ্যই setMetadata() কল করতে হবে।
  • অ্যাপটি কোন ধরনের রেটিং সমর্থন করে তা নির্দেশ করার জন্য MediaSession.setRatingType() সেট করতে হবে এবং অ্যাপটিকে অবশ্যই onSetRating() প্রয়োগ করতে হবে। অ্যাপে রেটিং দেওয়ার সুবিধা না থাকলে, রেটিংয়ের ধরন RATING_NONE হিসেবে সেট করতে হবে।

আপনি যে ভয়েস অ্যাকশন সমর্থন করেন তা কন্টেন্টের ধরন অনুযায়ী আলাদা হতে পারে।

কন্টেন্টের ধরন প্রয়োজনীয় অ্যাকশন
মিউজিক

অবশ্যই কাজ করতে হবে: চালানো, পজ করা, বন্ধ করা, পরের আইটেমে যাওয়া এবং আগের আইটেমে যাওয়া

এর জন্য সহায়তা জোরালোভাবে সাজেস্ট করা হচ্ছে: Seek To

পডকাস্ট

অবশ্যই কাজ করতে হবে: প্লে, পজ, স্টপ এবং সিক টু

এগুলির জন্য সাজেস্ট করা সহায়তা: এড়িয়ে পরবর্তী ধাপে যান এবং এড়িয়ে আগের ধাপে যান

অডিওবুক অবশ্যই কাজ করতে হবে: প্লে, পজ, স্টপ ও সিক টু
রেডিও কাজ করতেই হবে: প্লে, পজ ও বন্ধ করা
খবর অবশ্যই কাজ করতে হবে: চালানো, পজ করা, বন্ধ করা, পরের আইটেমে যাওয়া এবং আগের আইটেমে যাওয়া
ভিডিও

অবশ্যই কাজ করতে হবে: প্লে, পজ, স্টপ, সিক টু, রিওয়াইন্ড ও ফাস্ট ফরওয়ার্ড

এগুলির জন্য সহায়তা বিশেষভাবে সাজেস্ট করা হয়: এড়িয়ে পরবর্তী ধাপে যান এবং এড়িয়ে আগের ধাপে যান

আপনার প্রোডাক্ট অফার যতগুলি অ্যাকশন করার অনুমতি দেয়, আপনাকে উপরে তালিকাভুক্ত ততগুলি অ্যাকশনই করতে হবে, তবে অন্য কোনও অ্যাকশনের ক্ষেত্রেও আপনাকে যথাযথভাবে উত্তর দিতে হবে। যেমন, শুধুমাত্র প্রিমিয়াম ব্যবহারকারীদের কাছে আগের আইটেমে ফিরে যাওয়ার সুবিধা থাকলে, ফ্রি টিয়ার ব্যবহারকারী Assistant-কে আগের আইটেমে ফিরে যাওয়ার অনুরোধ করলে, আপনি হয়ত কোনও সমস্যার কথা জানাবেন। আরও নির্দেশিকার জন্য সমস্যা সমাধান সংক্রান্ত বিভাগ দেখুন।

ব্যবহার করে দেখার জন্য স্যাম্পেল ভয়েস কোয়েরি

নিম্নলিখিত সারণীতে কিছু নমুনা কোয়েরি দেওয়া হল যা আপনার প্রয়োগ পরীক্ষা করার সময় ব্যবহার করা উচিত:

MediaSession কলব্যাক ব্যবহার করার জন্য “Ok Google” বাক্যাংশ
onPlay()

“চালান।”

“আবার চালু করো।”

onPlayFromSearch()
onPlayFromUri()
মিউজিক

“(অ্যাপের নাম)-এ মিউজিক বা গান চালাও।” এটি একটি খালি কোয়েরি।

“(অ্যাপের নাম)-এ (গান | আর্টিস্ট | অ্যালবাম | জনরা | প্লেলিস্ট) চালাও।”

রেডিও (অ্যাপের নাম)-এ “(ফ্রিকোয়েন্সি | স্টেশন) চালাও।”
অডিওবুক

(অ্যাপের নাম)-এ আমার অডিওবুক পড়ো।"

“(অ্যাপের নাম)-এ (অডিওবুক) পড়ো।”

পডকাস্ট “(অ্যাপের নাম)-এ (পডকাস্ট) চালাও।”
onPause() “পজ করো।”
onStop() “বন্ধ করো।”
onSkipToNext() “পরের (গান | পর্ব | ট্র্যাক).”
onSkipToPrevious() “আগের (গান | পর্ব | ট্র্যাক)।”
onSeekTo()

“রিস্টার্ট করো।”

“## সেকেন্ড এগিয়ে যাও।”

“## মিনিট পিছনে যাও।”

প্রযোজ্য নয় (আপনার MediaMetadata আপডেট রাখুন) “কী চলছে?”

সমস্যা

মিডিয়া সেশনে কোনও সমস্যা হলে Assistant তা ম্যানেজ করে এবং ব্যবহারকারীকে সেই বিষয়ে জানায়। মিডিয়া সেশন নিয়ে কাজ করা-তে যেভাবে বর্ণনা করা হয়েছে, সেই অনুযায়ী আপনার মিডিয়া সেশন যেন ট্রান্সপোর্ট স্টেট এবং ত্রুটি কোড তার PlaybackState-এ সঠিকভাবে আপডেট করে তা নিশ্চিত করুন। Assistant getErrorCode()-এর পাঠানো সব ত্রুটি কোড শনাক্ত করে।

সাধারণত ভুলভাবে ম্যানেজ করা কেস

এখানে কিছু সমস্যার উদাহরণ দেওয়া হল যেগুলি আপনি সঠিকভাবে ম্যানেজ করছেন কিনা তা নিশ্চিত করতে হবে:

  • ব্যবহারকারীকে সাইন-ইন করতে হবে
    • PlaybackState ত্রুটি কোড ERROR_CODE_AUTHENTICATION_EXPIRED-এ সেট করুন।
    • PlaybackState সমস্যার মেসেজ সেট করুন।
    • প্লেব্যাকের জন্য প্রয়োজন হলে, PlaybackState-এর স্ট্যাটাস STATE_ERROR-এ সেট করুন, অন্যথায় বাকি PlaybackState যেমন আছে তেমনই রাখুন।
  • ব্যবহারকারী এমন অ্যাকশনের অনুরোধ করেছেন যা উপলভ্য নেই
    • PlaybackState ত্রুটি কোড সঠিকভাবে সেট করুন। যেমন, অ্যাকশন কাজ না করলে PlaybackState-কে ERROR_CODE_NOT_SUPPORTED-এ সেট করুন অথবা অ্যাকশন সাইন-ইন সুরক্ষিত হলে ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED-এ সেট করুন।
    • PlaybackState সমস্যার মেসেজ সেট করুন।
    • PlaybackState-এর বাকি অংশ যেমন আছে তেমনই রাখো।
  • ব্যবহারকারী এমন কন্টেন্টের অনুরোধ করেছেন যা অ্যাপে উপলভ্য নেই
    • PlaybackState ত্রুটি কোড সঠিকভাবে সেট করুন। যেমন, ERROR_CODE_NOT_AVAILABLE_IN_REGION ব্যবহার করুন।
    • PlaybackState সমস্যার মেসেজ সেট করুন।
    • প্লেব্যাক বন্ধ করতে PlaybackSate-এর স্ট্যাটাস STATE_ERROR-এ সেট করুন, অন্যথায় PlaybackState-এর বাকি অংশ যেমন আছে তেমনই রাখুন।
  • ব্যবহারকারী এমন কন্টেন্টের জন্য অনুরোধ করেন যার সম্পূর্ণ মিল উপলভ্য নেই। যেমন, কোনও ফ্রি-টিয়ার ব্যবহারকারী এমন কন্টেন্ট দেখতে চাইছেন যা শুধু প্রিমিয়াম-টিয়ার ব্যবহারকারীদের জন্য উপলভ্য।
    • আমরা সাজেস্ট করি যে আপনি কোনও সমস্যা রিটার্ন করবেন না এবং পরিবর্তে একই ধরনের কিছু চালানোর জন্য অগ্রাধিকার দেবেন। প্লেব্যাক শুরু হওয়ার আগে Assistant সবচেয়ে প্রাসঙ্গিক ভয়েস উত্তর দেওয়ার কাজটি ম্যানেজ করবে।

উদ্দেশ্য সহ প্লেব্যাক

Assistant, ডিপ লিঙ্ক সহ ইনটেন্ট পাঠিয়ে অডিও বা ভিডিও অ্যাপ চালু করতে এবং প্লেব্যাক শুরু করতে পারে।

ইনটেন্ট ও তার ডিপ লিঙ্ক বিভিন্ন সোর্স থেকে আসতে পারে:

  • Assistant কোনও মোবাইল অ্যাপ চালু করার সময়, Google Search ব্যবহার করে মার্ক-আপ করা কন্টেন্ট খুঁজে নিতে পারে, যা লিঙ্ক সহ দেখার অ্যাকশন প্রদান করে।
  • Assistant যখন কোনও টিভি অ্যাপ চালু করে, তখন মিডিয়া কন্টেন্টের URI দেখানোর জন্য আপনার অ্যাপে TV সার্চ পরিষেবা প্রদানকারী অন্তর্ভুক্ত থাকতে হবে। Assistant কন্টেন্ট প্রদানকারীকে একটি কোয়েরি পাঠায়, যা ডিপ লিঙ্কের জন্য URI এবং একটি ঐচ্ছিক অ্যাকশন সহ ইনটেন্ট রিটার্ন করে। কোয়েরি যদি ইনটেন্টে কোনও অ্যাকশন রিটার্ন করে, তাহলে Assistant সেই অ্যাকশন এবং URI আপনার অ্যাপে ফেরত পাঠায়। প্রদানকারী কোনও অ্যাকশন নির্দিষ্ট না করলে, Assistant ইনটেন্টে ACTION_VIEW যোগ করবে।

Assistant আপনার অ্যাপে পাঠানো ইনটেন্টে true ভ্যালু সহ অতিরিক্ত EXTRA_START_PLAYBACK যোগ করে। আপনার অ্যাপ EXTRA_START_PLAYBACK সহ ইনটেন্ট পেলে প্লেব্যাক শুরু করা উচিত।

অ্যাক্টিভ থাকাকালীন ইনটেন্ট ম্যানেজ করা

আপনার অ্যাপে আগের অনুরোধের কন্টেন্ট চলাকালীন ব্যবহারকারী Assistant-কে অন্য কিছু চালাতে বলতে পারেন। এর অর্থ হল, আপনার অ্যাপের প্লেব্যাক অ্যাক্টিভিটি আগে থেকেই চালু ও অ্যাক্টিভ থাকলেও, প্লেব্যাক শুরু করার জন্য এটি নতুন ইনটেন্ট পেতে পারে।

ডিপ লিঙ্কের মাধ্যমে ইনটেন্টকে সাপোর্ট করে এমন অ্যাক্টিভিটি, নতুন অনুরোধ ম্যানেজ করার জন্য onNewIntent() ওভাররাইড করা উচিত।

প্লেব্যাক শুরু করার সময়, Assistant আপনার অ্যাপে পাঠানো ইনটেন্টে অতিরিক্ত ফ্ল্যাগ যোগ করতে পারে। বিশেষ করে, এটি FLAG_ACTIVITY_CLEAR_TOP বা FLAG_ACTIVITY_NEW_TASK অথবা দুটিই যোগ করতে পারে। আপনার কোডকে এইসব ফ্ল্যাগ ম্যানেজ করতে না হলেও, Android সিস্টেম এগুলির উত্তর দেয়। আগের URI এখনও প্লে হওয়ার সময় নতুন URI সহ দ্বিতীয় প্লেব্যাক অনুরোধ এলে, এটি আপনার অ্যাপের আচরণকে প্রভাবিত করতে পারে। এই ক্ষেত্রে আপনার অ্যাপ কীভাবে কাজ করে তা পরীক্ষা করে দেখা ভাল। পরিস্থিতি সিমুলেট করতে আপনি adb কমান্ড লাইন টুল ব্যবহার করতে পারেন (কনস্ট্যান্ট 0x14000000 হল দুটি ফ্ল্যাগের বুলিয়ান বিটওয়াইজ OR):

adb shell 'am start -a android.intent.action.VIEW --ez android.intent.extra.START_PLAYBACK true -d "<first_uri>"' -f 0x14000000
adb shell 'am start -a android.intent.action.VIEW --ez android.intent.extra.START_PLAYBACK true -d "<second_uri>"' -f 0x14000000

কোনও পরিষেবা থেকে প্লেব্যাক করা

আপনার অ্যাপে যদি এমন কোনও media browser service থাকে যা Assistant-এর সাথে কানেকশনের অনুমতি দেয়, তাহলে Assistant পরিষেবার media session-এর সাথে যোগাযোগ করে অ্যাপটি চালু করতে পারে। মিডিয়া ব্রাউজার পরিষেবার কখনই কোনও অ্যাক্টিভিটি লঞ্চ করা উচিত নয়। setSessionActivity()-এর মাধ্যমে আপনার উল্লেখ করা PendingIntent-এর উপর ভিত্তি করে Assistant আপনার অ্যাক্টিভিটি লঞ্চ করবে।

আপনি মিডিয়া ব্রাউজার পরিষেবা শুরু করার সময় MediaSession.Token সেট করতে ভুলবেন না। মনে রাখবেন, শুরু করার সময় সহ সব সময় কাজ করে এমন প্লেব্যাক অ্যাকশন সেট করতে হবে। অ্যাসিস্ট্যান্ট প্রথম প্লেব্যাক কমান্ড পাঠানোর আগে, আপনার মিডিয়া অ্যাপ প্লেব্যাক অ্যাকশন সেট করবে বলে অ্যাসিস্ট্যান্ট আশা করে।

কোনও পরিষেবা থেকে শুরু করতে, Assistant মিডিয়া ব্রাউজার ক্লায়েন্ট API প্রয়োগ করে। এটি TransportControls কল পারফর্ম করে যা আপনার অ্যাপের মিডিয়া সেশনে PLAY অ্যাকশন কলব্যাক ট্রিগার করে।

নিচের ডায়াগ্রামে Assistant-এর মাধ্যমে জেনারেট করা কলের ক্রম এবং মিডিয়া সেশন কলব্যাকের সংশ্লিষ্ট ক্রম দেখানো হয়েছে। (প্রস্তুত কলব্যাক শুধুমাত্র তখনই পাঠানো হয় যদি আপনার অ্যাপ সেগুলি সাপোর্ট করে।) সব কল অ্যাসিঙ্ক্রোনাস। Assistant আপনার অ্যাপ থেকে কোনও উত্তরের জন্য অপেক্ষা করে না।

মিডিয়া সেশনের মাধ্যমে প্লেব্যাক শুরু করা হচ্ছে

ব্যবহারকারী কোনও কিছু চালানোর জন্য ভয়েস কমান্ড দিলে, Assistant একটি ছোট ঘোষণা করে উত্তর দেয়। ঘোষণা সম্পূর্ণ হওয়ার সাথে সাথেই Assistant, 'চালান' অ্যাকশন ইস্যু করে। এটি কোনও নির্দিষ্ট প্লেব্যাক স্ট্যাটাসের জন্য অপেক্ষা করে না।

আপনার অ্যাপ ACTION_PREPARE_* অ্যাকশন সাপোর্ট করলে, ঘোষণা শুরু করার আগে Assistant PREPARE অ্যাকশন কল করে।

MediaBrowserService-এ কানেক্ট করা হচ্ছে

আপনার অ্যাপ চালু করার জন্য কোনও পরিষেবা ব্যবহার করতে, Assistant-কে অবশ্যই অ্যাপের MediaBrowserService-এর সাথে কানেক্ট করতে এবং এর MediaSession.Token ফিরিয়ে আনতে সক্ষম হতে হবে। পরিষেবার onGetRoot() পদ্ধতিতে কানেকশন সংক্রান্ত অনুরোধ ম্যানেজ করা হয়। অনুরোধ ম্যানেজ করার দুটি উপায় আছে:

  • কানেকশনের সব অনুরোধ গ্রহণ করুন
  • শুধুমাত্র Assistant অ্যাপ থেকে কানেকশনের অনুরোধ গ্রহণ করুন

কানেকশনের সব অনুরোধ গ্রহণ করুন

Assistant-কে আপনার মিডিয়া সেশনে কমান্ড পাঠানোর অনুমতি দিতে আপনাকে অবশ্যই BrowserRoot ফিরিয়ে দিতে হবে। সবচেয়ে সহজ উপায় হল, সব MediaBrowser অ্যাপকে আপনার MediaBrowserService-এর সাথে কানেক্ট করার অনুমতি দেওয়া। আপনাকে অবশ্যই একটি নন-নাল BrowserRoot ফেরত দিতে হবে। Universal Music Player থেকে প্রযোজ্য কোড এখানে দেওয়া হল:

Kotlin

override fun onGetRoot(
        clientPackageName: String,
        clientUid: Int,
        rootHints: Bundle?
): BrowserRoot? {

    // To ensure you are not allowing any arbitrary app to browse your app's contents, you
    // need to check the origin:
    if (!packageValidator.isCallerAllowed(this, clientPackageName, clientUid)) {
        // If the request comes from an untrusted package, return an empty browser root.
        // If you return null, then the media browser will not be able to connect and
        // no further calls will be made to other media browsing methods.
        Log.i(TAG, "OnGetRoot: Browsing NOT ALLOWED for unknown caller. Returning empty "
                + "browser root so all apps can use MediaController. $clientPackageName")
        return MediaBrowserServiceCompat.BrowserRoot(MEDIA_ID_EMPTY_ROOT, null)
    }

    // Return browser roots for browsing...
}

জাভা

@Override
public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid,
                             Bundle rootHints) {

    // To ensure you are not allowing any arbitrary app to browse your app's contents, you
    // need to check the origin:
    if (!packageValidator.isCallerAllowed(this, clientPackageName, clientUid)) {
        // If the request comes from an untrusted package, return an empty browser root.
        // If you return null, then the media browser will not be able to connect and
        // no further calls will be made to other media browsing methods.
        LogHelper.i(TAG, "OnGetRoot: Browsing NOT ALLOWED for unknown caller. "
                + "Returning empty browser root so all apps can use MediaController."
                + clientPackageName);
        return new MediaBrowserServiceCompat.BrowserRoot(MEDIA_ID_EMPTY_ROOT, null);
    }

    // Return browser roots for browsing...
}

Assistant অ্যাপ প্যাকেজ ও স্বাক্ষরে সম্মতি দিন

আপনি Assistant-কে আপনার মিডিয়া ব্রাউজার পরিষেবার সাথে কানেক্ট করার জন্য স্পষ্টভাবে অনুমতি দিতে পারেন, এর জন্য আপনাকে প্যাকেজের নাম ও স্বাক্ষর চেক করতে হবে। আপনার অ্যাপ MediaBrowserService-এর onGetRoot পদ্ধতিতে প্যাকেজের নাম পাবে। Assistant-কে আপনার মিডিয়া সেশনে কমান্ড পাঠানোর অনুমতি দিতে আপনাকে অবশ্যই BrowserRoot ফিরিয়ে দিতে হবে। Universal Music Player স্যাম্পেল পরিচিত প্যাকেজের নাম ও স্বাক্ষরের তালিকা বজায় রাখে। Google Assistant-এর ব্যবহার করা প্যাকেজের নাম ও স্বাক্ষর নিচে দেওয়া হল।

<signature name="Google" package="com.google.android.googlequicksearchbox">
    <key release="false">19:75:b2:f1:71:77:bc:89:a5:df:f3:1f:9e:64:a6:ca:e2:81:a5:3d:c1:d1:d5:9b:1d:14:7f:e1:c8:2a:fa:00</key>
    <key release="true">f0:fd:6c:5b:41:0f:25:cb:25:c3:b5:33:46:c8:97:2f:ae:30:f8:ee:74:11:df:91:04:80:ad:6b:2d:60:db:83</key>
</signature>

<signature name="Google Assistant on Android Automotive OS" package="com.google.android.carassistant">
    <key release="false">17:E2:81:11:06:2F:97:A8:60:79:7A:83:70:5B:F8:2C:7C:C0:29:35:56:6D:46:22:BC:4E:CF:EE:1B:EB:F8:15</key>
    <key release="true">74:B6:FB:F7:10:E8:D9:0D:44:D3:40:12:58:89:B4:23:06:A6:2C:43:79:D0:E5:A6:62:20:E3:A6:8A:BF:90:E2</key>
</signature>