গুগল সহকারী এবং মিডিয়া অ্যাপ

Google সহকারী আপনাকে অনেক ডিভাইস যেমন Google হোম, আপনার ফোন এবং আরও অনেক কিছু নিয়ন্ত্রণ করতে ভয়েস কমান্ড ব্যবহার করতে দেয়। এটিতে মিডিয়া কমান্ডগুলি বোঝার জন্য একটি অন্তর্নির্মিত ক্ষমতা রয়েছে ("বেয়ন্সের দ্বারা কিছু খেলুন") এবং মিডিয়া নিয়ন্ত্রণগুলিকে সমর্থন করে (যেমন পজ, স্কিপ, ফাস্ট ফরওয়ার্ড, থাম্বস আপ)।

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

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

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

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

আপনার অ্যাপের MediaSession অবজেক্টে এই ফ্ল্যাগগুলি সেট করে মিডিয়া এবং পরিবহন নিয়ন্ত্রণগুলি সক্ষম করুন:

কোটলিন

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() এ আপনার সমর্থিত ক্রিয়াগুলি ঘোষণা করুন।

ইউনিভার্সাল অ্যান্ড্রয়েড মিউজিক প্লেয়ার নমুনা প্রকল্প একটি মিডিয়া সেশন কিভাবে সেট আপ করতে হয় তার একটি ভাল উদাহরণ।

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

একটি পরিষেবা থেকে প্লেব্যাক শুরু করার জন্য, একটি মিডিয়া সেশনে এই 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 সহকারী URI-ভিত্তিক অ্যাকশনগুলি শুধুমাত্র সেই কোম্পানিগুলির জন্য কাজ করে যারা Google-কে URI প্রদান করে। Google-এ আপনার মিডিয়া বিষয়বস্তু বর্ণনা করার বিষয়ে আরও জানতে মিডিয়া অ্যাকশন দেখুন।

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

অনুসন্ধান প্রশ্ন পার্স করুন

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

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

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

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

নিম্নলিখিত অতিরিক্তগুলি Android Automotive OS এবং Android Auto-এ সমর্থিত:

নিচের কোড স্নিপেটটি দেখায় কিভাবে আপনার MediaSession.CallbackonPlayFromSearch() পদ্ধতিকে ওভাররাইড করতে হয়। ভয়েস সার্চ ক্যোয়ারী পার্স করতে এবং প্লেব্যাক শুরু করতে কলব্যাক বাস্তবায়ন:

কোটলিন

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
    }
}

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

খালি প্রশ্নগুলি পরিচালনা করুন

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

যখন একজন ব্যবহারকারী বলেন “[আপনার অ্যাপের নাম]-এ সঙ্গীত চালান” , তখন 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>

পরিবহন নিয়ন্ত্রণ

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

অ্যাকশন কলব্যাক বর্ণনা
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() 30 সেকেন্ড রিওয়াইন্ড করুন
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 এ সেট করা উচিত।

আপনি যে ভয়েস অ্যাকশনগুলি সমর্থন করেন তা সম্ভবত বিষয়বস্তুর প্রকার অনুসারে পরিবর্তিত হবে।

বিষয়বস্তুর প্রকার প্রয়োজনীয় ক্রিয়াকলাপ
সঙ্গীত

সমর্থন করতে হবে : খেলুন, বিরতি দিন, থামুন, পরবর্তীতে এড়িয়ে যান এবং পূর্ববর্তীতে এড়িয়ে যান

দৃঢ়ভাবে জন্য সমর্থন সুপারিশ : অনুসন্ধান করুন

পডকাস্ট

সমর্থন করতে হবে : খেলুন, বিরতি দিন, থামুন এবং সন্ধান করুন৷

এর জন্য সমর্থন সুপারিশ করুন : পরবর্তীতে এড়িয়ে যান এবং পূর্ববর্তীতে এড়িয়ে যান

অডিওবুক সমর্থন করতে হবে : খেলুন, বিরতি দিন, থামুন এবং সন্ধান করুন৷
রেডিও সমর্থন করতে হবে : খেলুন, বিরতি দিন এবং থামুন
খবর সমর্থন করতে হবে : খেলুন, বিরতি দিন, থামুন, পরবর্তীতে এড়িয়ে যান এবং পূর্ববর্তীতে এড়িয়ে যান
ভিডিও

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

এর জন্য দৃঢ়ভাবে সমর্থন সুপারিশ করুন : পরবর্তীতে এড়িয়ে যান এবং পূর্ববর্তীতে এড়িয়ে যান

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

চেষ্টা করার জন্য ভয়েস প্রশ্নের নমুনা

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

মিডিয়া সেশন কলব্যাক "Hey Google" শব্দগুচ্ছ ব্যবহার করতে হবে
onPlay()

"খেলুন।"

"পুনরায় শুরু করুন।"

onPlayFromSearch()
onPlayFromUri()
সঙ্গীত

" (অ্যাপের নাম) এ সঙ্গীত বা গান চালান।" এটি একটি খালি প্রশ্ন.

" (গান | শিল্পী | অ্যালবাম | জেনার

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

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

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

পডকাস্ট " (অ্যাপের নাম)(পডকাস্ট) চালান।"
onPause() "বিরতি।"
onStop() "থাম।"
onSkipToNext() "পরবর্তী (গান | পর্ব | ট্র্যাক) ।"
onSkipToPrevious() "আগের (গান | পর্ব | ট্র্যাক) ।"
onSeekTo()

"পুনরায় চালু করুন।"

" ## সেকেন্ড এড়িয়ে যান।"

" ## মিনিট পিছনে যান।"

N/A (আপনার MediaMetadata আপডেট রাখুন) "কি খেলছে?"

ত্রুটি

সহকারী মিডিয়া সেশনের ত্রুটিগুলি যখন সেগুলি ঘটে তখন সেগুলি পরিচালনা করে এবং সেগুলি ব্যবহারকারীদের কাছে রিপোর্ট করে৷ নিশ্চিত করুন যে আপনার মিডিয়া সেশনটি তার PlaybackState পরিবহন অবস্থা এবং ত্রুটি কোড সঠিকভাবে আপডেট করেছে, যেমনটি মিডিয়া সেশনের সাথে কাজ করাতে বর্ণিত হয়েছে। সহকারী 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 বাকি অংশটি যেমন আছে তেমনই ধরে রাখুন।
  • ব্যবহারকারী এমন সামগ্রীর অনুরোধ করে যেখানে একটি সঠিক মিল অনুপলব্ধ। উদাহরণস্বরূপ, একজন মুক্ত-স্তরের ব্যবহারকারী শুধুমাত্র প্রিমিয়াম-স্তরের ব্যবহারকারীদের জন্য উপলব্ধ সামগ্রীর জন্য জিজ্ঞাসা করছেন।
    • আমরা সুপারিশ করি যে আপনি একটি ত্রুটি ফেরত দেবেন না এবং পরিবর্তে খেলার মতো কিছু খুঁজে পাওয়াকে অগ্রাধিকার দেওয়া উচিত। প্লেব্যাক শুরু হওয়ার আগে অ্যাসিস্ট্যান্ট সবচেয়ে প্রাসঙ্গিক ভয়েস রেসপন্স বলতে পরিচালনা করবে।

একটি অভিপ্রায় সঙ্গে প্লেব্যাক

অ্যাসিস্ট্যান্ট একটি অডিও বা ভিডিও অ্যাপ চালু করতে পারে এবং একটি গভীর লিঙ্কের মাধ্যমে একটি অভিপ্রায় পাঠিয়ে প্লেব্যাক শুরু করতে পারে।

উদ্দেশ্য এবং এর গভীর লিঙ্ক বিভিন্ন উত্স থেকে আসতে পারে:

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

সহকারী আপনার অ্যাপে যে অভিপ্রায় পাঠায় তার মান true সহ অতিরিক্ত EXTRA_START_PLAYBACK যোগ করে। আপনার অ্যাপ্লিকেশানটি প্লেব্যাক শুরু করা উচিত যখন এটি EXTRA_START_PLAYBACK এর সাথে একটি অভিপ্রায় পায়৷

সক্রিয় থাকাকালীন উদ্দেশ্য পরিচালনা করা

ব্যবহারকারীরা অ্যাসিস্ট্যান্টকে কিছু চালাতে বলতে পারেন যখন আপনার অ্যাপটি আগের অনুরোধ থেকে কন্টেন্ট চালাচ্ছে। এর মানে হল আপনার অ্যাপ প্লেব্যাক শুরু করার জন্য নতুন ইন্টেন্ট পেতে পারে যখন এর প্লেব্যাক কার্যকলাপ ইতিমধ্যেই চালু এবং সক্রিয় থাকে।

যে কার্যকলাপগুলি গভীর লিঙ্কগুলির সাথে ইন্টেন্টগুলিকে সমর্থন করে সেগুলিকে নতুন অনুরোধগুলি পরিচালনা করতে onNewIntent() ওভাররাইড করা উচিত৷

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

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 থাকে যা সহকারী থেকে সংযোগের অনুমতি দেয়, তাহলে সহকারী পরিষেবাটির media session সাথে যোগাযোগ করে অ্যাপটি শুরু করতে পারে। মিডিয়া ব্রাউজার পরিষেবা কখনই একটি কার্যকলাপ চালু করা উচিত নয়। আপনি setSessionActivity() দিয়ে সংজ্ঞায়িত PendingIntent উপর ভিত্তি করে Assistant আপনার কার্যকলাপ চালু করবে।

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

একটি পরিষেবা থেকে শুরু করতে, সহকারী মিডিয়া ব্রাউজার ক্লায়েন্ট APIগুলি প্রয়োগ করে৷ এটি ট্রান্সপোর্ট কন্ট্রোল কলগুলি সম্পাদন করে যা আপনার অ্যাপের মিডিয়া সেশনে প্লে অ্যাকশন কলব্যাকগুলিকে ট্রিগার করে৷

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

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

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

যদি আপনার অ্যাপ ACTION_PREPARE_* অ্যাকশন সমর্থন করে, তাহলে অ্যাসিস্ট্যান্ট ঘোষণা শুরু করার আগে PREPARE অ্যাকশনকে কল করে।

একটি MediaBrowserService সাথে সংযোগ করা হচ্ছে

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

  • সমস্ত সংযোগ অনুরোধ গ্রহণ করুন
  • শুধুমাত্র সহকারী অ্যাপ থেকে সংযোগের অনুরোধগুলি গ্রহণ করুন

সমস্ত সংযোগ অনুরোধ গ্রহণ করুন

সহকারীকে আপনার মিডিয়া সেশনে কমান্ড পাঠাতে অনুমতি দেওয়ার জন্য আপনাকে অবশ্যই একটি BrowserRot ফেরত দিতে হবে। সবচেয়ে সহজ উপায় হল সমস্ত MediaBrowser অ্যাপকে আপনার MediaBrowserService এর সাথে সংযোগ করার অনুমতি দেওয়া। আপনাকে অবশ্যই একটি নন-নাল ব্রাউজাররুট ফেরত দিতে হবে। এখানে ইউনিভার্সাল মিউজিক প্লেয়ার থেকে প্রযোজ্য কোড আছে:

কোটলিন

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...
}

সহকারী অ্যাপ প্যাকেজ এবং স্বাক্ষর গ্রহণ করুন

আপনি স্পষ্টভাবে অ্যাসিস্ট্যান্টকে তার প্যাকেজের নাম এবং স্বাক্ষর চেক করে আপনার মিডিয়া ব্রাউজার পরিষেবার সাথে সংযোগ করার অনুমতি দিতে পারেন। আপনার অ্যাপটি আপনার MediaBrowserService-এর onGetRoot পদ্ধতিতে প্যাকেজের নাম পাবে। সহকারীকে আপনার মিডিয়া সেশনে কমান্ড পাঠাতে অনুমতি দেওয়ার জন্য আপনাকে অবশ্যই একটি BrowserRot ফেরত দিতে হবে। ইউনিভার্সাল মিউজিক প্লেয়ার নমুনা পরিচিত প্যাকেজের নাম এবং স্বাক্ষরের একটি তালিকা বজায় রাখে। নীচে প্যাকেজের নাম এবং স্বাক্ষর রয়েছে যা Google সহকারী দ্বারা ব্যবহৃত হয়৷

<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>