গাড়ির জন্য মিডিয়া অ্যাপস তৈরি করুন

Android Auto এবং Android Automotive OS আপনাকে তাদের গাড়িতে থাকা ব্যবহারকারীদের কাছে আপনার মিডিয়া অ্যাপের সামগ্রী আনতে সাহায্য করে। গাড়ির জন্য একটি মিডিয়া অ্যাপকে অবশ্যই একটি মিডিয়া ব্রাউজার পরিষেবা প্রদান করতে হবে যাতে Android Auto এবং Android Automotive OS বা মিডিয়া ব্রাউজার সহ অন্য কোনও অ্যাপ আপনার সামগ্রী আবিষ্কার করতে এবং প্রদর্শন করতে পারে৷

এই নির্দেশিকাটি অনুমান করে যে আপনার কাছে ইতিমধ্যেই একটি মিডিয়া অ্যাপ রয়েছে যা ফোনে অডিও চালায় এবং আপনার মিডিয়া অ্যাপটি Android মিডিয়া অ্যাপ আর্কিটেকচারের সাথে সামঞ্জস্যপূর্ণ।

এই নির্দেশিকাটি একটি MediaBrowserService এবং MediaSession এর প্রয়োজনীয় উপাদানগুলি বর্ণনা করে যা আপনার অ্যাপের Android Auto বা Android Automotive OS-এ কাজ করার জন্য প্রয়োজন৷ আপনি মূল মিডিয়া পরিকাঠামো সম্পন্ন করার পরে, আপনি Android Auto-এর জন্য সমর্থন যোগ করতে পারেন এবং আপনার মিডিয়া অ্যাপে Android Automotive OS-এর জন্য সমর্থন যোগ করতে পারেন

আপনি শুরু করার আগে

  1. অ্যান্ড্রয়েড মিডিয়া API ডকুমেন্টেশন পর্যালোচনা করুন।
  2. ডিজাইন গাইডেন্সের জন্য মিডিয়া অ্যাপ তৈরি করুন পর্যালোচনা করুন।
  3. এই বিভাগে তালিকাভুক্ত মূল শর্তাবলী এবং ধারণাগুলি পর্যালোচনা করুন।

মূল শর্তাবলী এবং ধারণা

মিডিয়া ব্রাউজার পরিষেবা
আপনার মিডিয়া অ্যাপ দ্বারা বাস্তবায়িত একটি Android পরিষেবা যা MediaBrowserServiceCompat API-এর সাথে সম্মতি দেয়। আপনার অ্যাপ এর বিষয়বস্তু প্রকাশ করতে এই পরিষেবাটি ব্যবহার করে।
মিডিয়া ব্রাউজার
মিডিয়া ব্রাউজার পরিষেবাগুলি আবিষ্কার করতে এবং তাদের সামগ্রী প্রদর্শন করতে মিডিয়া অ্যাপগুলি দ্বারা ব্যবহৃত একটি API৷ Android Auto এবং Android Automotive OS আপনার অ্যাপের মিডিয়া ব্রাউজার পরিষেবা খুঁজে পেতে একটি মিডিয়া ব্রাউজার ব্যবহার করে।
মিডিয়া আইটেম

মিডিয়া ব্রাউজার MediaItem অবজেক্টের একটি ট্রিতে এর বিষয়বস্তু সংগঠিত করে। একটি মিডিয়া আইটেমে নিম্নলিখিত পতাকাগুলির মধ্যে একটি বা উভয়ই থাকতে পারে:

  • FLAG_PLAYABLE : নির্দেশ করে যে আইটেমটি বিষয়বস্তুর গাছের একটি পাতা। আইটেমটি একটি একক সাউন্ড স্ট্রিম প্রতিনিধিত্ব করে, যেমন একটি অ্যালবামের একটি গান, একটি অডিও বইয়ের একটি অধ্যায়, বা একটি পডকাস্টের একটি পর্ব৷
  • FLAG_BROWSABLE : নির্দেশ করে যে আইটেমটি বিষয়বস্তু গাছের একটি নোড এবং এতে শিশু রয়েছে৷ উদাহরণস্বরূপ, আইটেমটি একটি অ্যালবামের প্রতিনিধিত্ব করে এবং এর বাচ্চারা অ্যালবামের গান।

একটি মিডিয়া আইটেম যা ব্রাউজ করা যায় এবং খেলার যোগ্য উভয়ই একটি প্লেলিস্টের মতো কাজ করে৷ আপনি আইটেমটি নিজেই এর সমস্ত বাচ্চাদের খেলার জন্য নির্বাচন করতে পারেন, অথবা আপনি এর বাচ্চাদের ব্রাউজ করতে পারেন।

যানবাহন-অপ্টিমাইজড

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

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

আপনাকে অ্যান্ড্রয়েড অটোর জন্য ক্রিয়াকলাপ ডিজাইন করার দরকার নেই, কারণ অ্যান্ড্রয়েড অটো আপনার মিডিয়া ব্রাউজার পরিষেবা থেকে তথ্য ব্যবহার করে নিজস্ব গাড়ি-অপ্টিমাইজ করা ইন্টারফেস আঁকে৷

আপনার অ্যাপের ম্যানিফেস্ট ফাইল কনফিগার করুন

আপনি আপনার মিডিয়া ব্রাউজার পরিষেবা তৈরি করার আগে, আপনাকে আপনার অ্যাপের ম্যানিফেস্ট ফাইলগুলি কনফিগার করতে হবে৷

আপনার মিডিয়া ব্রাউজার পরিষেবা ঘোষণা করুন

Android Auto এবং Android Automotive OS উভয়ই মিডিয়া আইটেমগুলি ব্রাউজ করতে আপনার মিডিয়া ব্রাউজার পরিষেবার মাধ্যমে আপনার অ্যাপের সাথে সংযুক্ত হয়। Android Auto এবং Android Automotive OS কে পরিষেবাটি আবিষ্কার করতে এবং আপনার অ্যাপের সাথে সংযোগ করতে আপনার ম্যানিফেস্টে আপনার মিডিয়া ব্রাউজার পরিষেবা ঘোষণা করুন৷

নিম্নলিখিত কোড স্নিপেট দেখায় কিভাবে আপনার ম্যানিফেস্টে আপনার মিডিয়া ব্রাউজার পরিষেবা ঘোষণা করবেন। আপনার Android Automotive OS মডিউলের জন্য ম্যানিফেস্ট ফাইলে এবং আপনার ফোন অ্যাপের ম্যানিফেস্ট ফাইলে এই কোডটি অন্তর্ভুক্ত করুন।

<application>
    ...
    <service android:name=".MyMediaBrowserService"
             android:exported="true">
        <intent-filter>
            <action android:name="android.media.browse.MediaBrowserService"/>
        </intent-filter>
    </service>
    ...
</application>

অ্যাপ আইকন নির্দিষ্ট করুন

আপনাকে এমন অ্যাপ আইকন নির্দিষ্ট করতে হবে যা Android Auto এবং Android Automotive OS সিস্টেম UI-তে আপনার অ্যাপকে উপস্থাপন করতে ব্যবহার করতে পারে। দুটি আইকন প্রকার প্রয়োজন:

  • লঞ্চার আইকন
  • অ্যাট্রিবিউশন আইকন

লঞ্চার আইকন

লঞ্চার আইকনটি আপনার অ্যাপটিকে সিস্টেম UI-তে উপস্থাপন করে, যেমন লঞ্চারে এবং আইকনগুলির ট্রেতে। আপনি উল্লেখ করতে পারেন যে আপনি নিম্নলিখিত ম্যানিফেস্ট ঘোষণা ব্যবহার করে আপনার গাড়ি মিডিয়া অ্যাপের প্রতিনিধিত্ব করতে আপনার মোবাইল অ্যাপ থেকে আইকনটি ব্যবহার করতে চান:

<application
    ...
    android:icon="@mipmap/ic_launcher"
    ...
/>

আপনার মোবাইল অ্যাপের থেকে আলাদা আইকন ব্যবহার করতে, ম্যানিফেস্টে আপনার মিডিয়া ব্রাউজার পরিষেবার <service> উপাদানে android:icon বৈশিষ্ট্য সেট করুন:

<application>
    ...
    <service
        ...
        android:icon="@mipmap/auto_launcher"
        ...
    />
</application>

অ্যাট্রিবিউশন আইকন

চিত্র 1. মিডিয়া কার্ডে অ্যাট্রিবিউশন আইকন।

অ্যাট্রিবিউশন আইকনটি এমন জায়গায় ব্যবহার করা হয় যেখানে মিডিয়া বিষয়বস্তু প্রাধান্য পায়, যেমন মিডিয়া কার্ডে। বিজ্ঞপ্তিগুলির জন্য ব্যবহৃত ছোট আইকনটি পুনরায় ব্যবহার করার কথা বিবেচনা করুন৷ এই আইকনটি একরঙা হতে হবে। আপনি নিম্নলিখিত ম্যানিফেস্ট ঘোষণা ব্যবহার করে আপনার অ্যাপের প্রতিনিধিত্ব করতে ব্যবহৃত একটি আইকন নির্দিষ্ট করতে পারেন:

<application>
    ...
    <meta-data
        android:name="androidx.car.app.TintableAttributionIcon"
        android:resource="@drawable/ic_status_icon" />
    ...
</application>

আপনার মিডিয়া ব্রাউজার পরিষেবা তৈরি করুন

আপনি MediaBrowserServiceCompat ক্লাস প্রসারিত করে একটি মিডিয়া ব্রাউজার পরিষেবা তৈরি করুন৷ অ্যান্ড্রয়েড অটো এবং অ্যান্ড্রয়েড অটোমোটিভ ওএস উভয়ই নিম্নলিখিতগুলি করতে আপনার পরিষেবা ব্যবহার করতে পারে:

  • ব্যবহারকারীর কাছে একটি মেনু উপস্থাপন করতে আপনার অ্যাপের বিষয়বস্তু অনুক্রম ব্রাউজ করুন।
  • অডিও প্লেব্যাক নিয়ন্ত্রণ করতে আপনার অ্যাপের MediaSessionCompat অবজেক্টের জন্য টোকেন পান।

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

মিডিয়া ব্রাউজার সার্ভিস ওয়ার্কফ্লো

এই বিভাগটি বর্ণনা করে যে কীভাবে Android Automotive OS এবং Android Auto একটি সাধারণ ব্যবহারকারীর কর্মপ্রবাহের সময় আপনার মিডিয়া ব্রাউজার পরিষেবার সাথে ইন্টারঅ্যাক্ট করে।

  1. ব্যবহারকারী আপনার অ্যাপটি Android Automotive OS বা Android Auto-এ চালু করেন।
  2. Android Automotive OS বা Android Auto onCreate() পদ্ধতি ব্যবহার করে আপনার অ্যাপের মিডিয়া ব্রাউজার পরিষেবার সাথে যোগাযোগ করে। আপনার onCreate() পদ্ধতির বাস্তবায়নে, আপনাকে অবশ্যই একটি MediaSessionCompat অবজেক্ট এবং এর কলব্যাক অবজেক্ট তৈরি এবং নিবন্ধন করতে হবে।
  3. Android Automotive OS বা Android Auto আপনার বিষয়বস্তু অনুক্রমের রুট মিডিয়া আইটেম পেতে আপনার পরিষেবার onGetRoot() পদ্ধতিতে কল করে। রুট মিডিয়া আইটেম প্রদর্শিত হয় না; পরিবর্তে, এটি আপনার অ্যাপ থেকে আরও সামগ্রী পুনরুদ্ধার করতে ব্যবহৃত হয়।
  4. Android Automotive OS বা Android Auto আপনার পরিষেবার onLoadChildren() পদ্ধতিতে রুট মিডিয়া আইটেমের বাচ্চা পেতে কল করে। অ্যান্ড্রয়েড অটোমোটিভ ওএস এবং অ্যান্ড্রয়েড অটো এই মিডিয়া আইটেমগুলিকে বিষয়বস্তুর আইটেমগুলির শীর্ষ স্তর হিসাবে প্রদর্শন করে৷ সিস্টেম এই স্তরে কি আশা করে সে সম্পর্কে আরও তথ্যের জন্য এই পৃষ্ঠায় রুট মেনু গঠন দেখুন।
  5. ব্যবহারকারী যদি একটি ব্রাউজযোগ্য মিডিয়া আইটেম নির্বাচন করে, তাহলে নির্বাচিত মেনু আইটেমের বাচ্চাদের পুনরুদ্ধার করতে আপনার পরিষেবার onLoadChildren() পদ্ধতিটি আবার কল করা হবে।
  6. যদি ব্যবহারকারী একটি প্লেযোগ্য মিডিয়া আইটেম নির্বাচন করে, তাহলে Android Automotive OS বা Android Auto সেই ক্রিয়া সম্পাদনের জন্য উপযুক্ত মিডিয়া সেশন কলব্যাক পদ্ধতিতে কল করে।
  7. আপনার অ্যাপ দ্বারা সমর্থিত হলে, ব্যবহারকারী আপনার সামগ্রী অনুসন্ধান করতে পারেন। এই ক্ষেত্রে, Android Automotive OS বা Android Auto আপনার পরিষেবার onSearch() পদ্ধতিতে কল করুন৷

আপনার বিষয়বস্তু অনুক্রম তৈরি করুন

অ্যান্ড্রয়েড অটো এবং অ্যান্ড্রয়েড অটোমোটিভ ওএস আপনার অ্যাপের মিডিয়া ব্রাউজার পরিষেবাতে কল করে কোন সামগ্রী উপলব্ধ তা খুঁজে বের করতে। এটি সমর্থন করার জন্য আপনাকে আপনার মিডিয়া ব্রাউজার পরিষেবাতে দুটি পদ্ধতি প্রয়োগ করতে হবে: onGetRoot() এবং onLoadChildren()

গেটরুট প্রয়োগ করুন

আপনার পরিষেবার onGetRoot() পদ্ধতি আপনার বিষয়বস্তু অনুক্রমের রুট নোড সম্পর্কে তথ্য প্রদান করে। Android Auto এবং Android Automotive OS onLoadChildren() পদ্ধতি ব্যবহার করে আপনার বাকি সামগ্রীর অনুরোধ করতে এই রুট নোড ব্যবহার করে।

নিম্নলিখিত কোড স্নিপেট onGetRoot() পদ্ধতির একটি সহজ বাস্তবায়ন দেখায়:

কোটলিন

override fun onGetRoot(
    clientPackageName: String,
    clientUid: Int,
    rootHints: Bundle?
): BrowserRoot? =
    // Verify that the specified package is allowed to access your
    // content. You'll need to write your own logic to do this.
    if (!isValid(clientPackageName, clientUid)) {
        // If the request comes from an untrusted package, return null.
        // No further calls will be made to other media browsing methods.

        null
    } else MediaBrowserServiceCompat.BrowserRoot(MY_MEDIA_ROOT_ID, null)

জাভা

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

    // Verify that the specified package is allowed to access your
    // content. You'll need to write your own logic to do this.
    if (!isValid(clientPackageName, clientUid)) {
        // If the request comes from an untrusted package, return null.
        // No further calls will be made to other media browsing methods.

        return null;
    }

    return new MediaBrowserServiceCompat.BrowserRoot(MY_MEDIA_ROOT_ID, null);
}

এই পদ্ধতির আরও বিস্তারিত উদাহরণের জন্য, GitHub-এ ইউনিভার্সাল অ্যান্ড্রয়েড মিউজিক প্লেয়ার নমুনা অ্যাপে onGetRoot() পদ্ধতিটি দেখুন।

onGetRoot() এর জন্য প্যাকেজ বৈধতা যোগ করুন

যখন আপনার পরিষেবার onGetRoot() পদ্ধতিতে একটি কল করা হয়, কলিং প্যাকেজটি আপনার পরিষেবাতে সনাক্তকারী তথ্য প্রেরণ করে৷ আপনার পরিষেবা এই তথ্যটি ব্যবহার করে সিদ্ধান্ত নিতে পারে যে প্যাকেজটি আপনার সামগ্রী অ্যাক্সেস করতে পারে কিনা৷ উদাহরণ স্বরূপ, আপনি clientPackageName আপনার অনুমোদিত তালিকার সাথে তুলনা করে এবং প্যাকেজের APK সাইন করার জন্য ব্যবহৃত শংসাপত্র যাচাই করে অনুমোদিত প্যাকেজের তালিকায় আপনার অ্যাপের সামগ্রীতে অ্যাক্সেস সীমাবদ্ধ করতে পারেন। যদি প্যাকেজটি যাচাই করা না যায়, তাহলে আপনার সামগ্রীতে অ্যাক্সেস অস্বীকার করতে null ফেরত দিন।

আপনার সামগ্রীতে অ্যাক্সেস সহ Android Auto এবং Android Automotive OS-এর মতো সিস্টেম অ্যাপগুলি প্রদান করতে, এই সিস্টেম অ্যাপগুলি onGetRoot() পদ্ধতিতে কল করলে আপনার পরিষেবাকে অবশ্যই একটি নন-নাল BrowserRoot ফেরত দিতে হবে। Android Automotive OS সিস্টেম অ্যাপের স্বাক্ষর গাড়ির মেক এবং মডেলের উপর নির্ভর করে পরিবর্তিত হতে পারে, তাই আপনাকে Android Automotive OS কে শক্তিশালীভাবে সমর্থন করার জন্য সমস্ত সিস্টেম অ্যাপ থেকে সংযোগের অনুমতি দিতে হবে।

নিম্নলিখিত কোড স্নিপেট দেখায় যে কীভাবে আপনার পরিষেবা কলিং প্যাকেজটি একটি সিস্টেম অ্যাপ তা যাচাই করতে পারে:

fun isKnownCaller(
    callingPackage: String,
    callingUid: Int
): Boolean {
    ...
    val isCallerKnown = when {
       // If the system is making the call, allow it.
       callingUid == Process.SYSTEM_UID -> true
       // If the app was signed by the same certificate as the platform
       // itself, also allow it.
       callerSignature == platformSignature -> true
       // ... more cases
    }
    return isCallerKnown
}

এই কোড স্নিপেটটি GitHub-এ ইউনিভার্সাল অ্যান্ড্রয়েড মিউজিক প্লেয়ার নমুনা অ্যাপের PackageValidator ক্লাসের একটি অংশ। আপনার পরিষেবার onGetRoot() পদ্ধতির জন্য প্যাকেজ বৈধতা কীভাবে প্রয়োগ করবেন তার আরও বিশদ উদাহরণের জন্য সেই ক্লাসটি দেখুন।

সিস্টেম অ্যাপ্লিকেশানগুলিকে অনুমতি দেওয়ার পাশাপাশি, আপনাকে অবশ্যই Google সহকারীকে আপনার MediaBrowserService এর সাথে সংযোগ করতে দিতে হবে৷ মনে রাখবেন যে Google সহকারীর ফোনের জন্য আলাদা প্যাকেজের নাম রয়েছে, যার মধ্যে Android Auto এবং Android Automotive OS-এর জন্য রয়েছে।

LoadChildren() এর উপর প্রয়োগ করুন

আপনার রুট নোড অবজেক্ট পাওয়ার পর, Android Auto এবং Android Automotive OS এর বাচ্চাদের পেতে রুট নোড অবজেক্টে onLoadChildren() কল করে একটি শীর্ষ-স্তরের মেনু তৈরি করে। ক্লায়েন্ট অ্যাপগুলি চাইল্ড নোড অবজেক্ট ব্যবহার করে একই পদ্ধতিতে কল করে সাবমেনু তৈরি করে।

আপনার বিষয়বস্তু অনুক্রমের প্রতিটি নোড একটি MediaBrowserCompat.MediaItem অবজেক্ট দ্বারা প্রতিনিধিত্ব করা হয়। এই মিডিয়া আইটেমগুলির প্রতিটি একটি অনন্য আইডি স্ট্রিং দ্বারা চিহ্নিত করা হয়। ক্লায়েন্ট অ্যাপগুলি এই আইডি স্ট্রিংগুলিকে অস্বচ্ছ টোকেন হিসাবে বিবেচনা করে৷ যখন একটি ক্লায়েন্ট অ্যাপ একটি সাবমেনুতে ব্রাউজ করতে চায়, বা একটি মিডিয়া আইটেম চালাতে চায়, তখন এটি টোকেন পাস করে। আপনার অ্যাপ উপযুক্ত মিডিয়া আইটেমের সাথে টোকেন সংযুক্ত করার জন্য দায়ী।

নিম্নলিখিত কোড স্নিপেট onLoadChildren() পদ্ধতির একটি সহজ বাস্তবায়ন দেখায়:

কোটলিন

override fun onLoadChildren(
    parentMediaId: String,
    result: Result<List<MediaBrowserCompat.MediaItem>>
) {
    // Assume for example that the music catalog is already loaded/cached.

    val mediaItems: MutableList<MediaBrowserCompat.MediaItem> = mutableListOf()

    // Check whether this is the root menu:
    if (MY_MEDIA_ROOT_ID == parentMediaId) {

        // Build the MediaItem objects for the top level
        // and put them in the mediaItems list.
    } else {

        // Examine the passed parentMediaId to see which submenu we're at
        // and put the children of that menu in the mediaItems list.
    }
    result.sendResult(mediaItems)
}

জাভা

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

    // Assume for example that the music catalog is already loaded/cached.

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

    // Check whether this is the root menu:
    if (MY_MEDIA_ROOT_ID.equals(parentMediaId)) {

        // Build the MediaItem objects for the top level
        // and put them in the mediaItems list.
    } else {

        // Examine the passed parentMediaId to see which submenu we're at
        // and put the children of that menu in the mediaItems list.
    }
    result.sendResult(mediaItems);
}

এই পদ্ধতির একটি সম্পূর্ণ উদাহরণের জন্য, GitHub-এ ইউনিভার্সাল অ্যান্ড্রয়েড মিউজিক প্লেয়ার নমুনা অ্যাপে onLoadChildren() পদ্ধতিটি দেখুন।

রুট মেনু গঠন করুন

চিত্র 2. রুট বিষয়বস্তু নেভিগেশনাল ট্যাব হিসাবে প্রদর্শিত হয়।

অ্যান্ড্রয়েড অটো এবং অ্যান্ড্রয়েড অটোমোটিভ ওএস-এর রুট মেনুর গঠন সম্পর্কে নির্দিষ্ট সীমাবদ্ধতা রয়েছে। এগুলি রুট ইঙ্গিতগুলির মাধ্যমে MediaBrowserService সাথে যোগাযোগ করা হয়, যা onGetRoot() এ পাস করা Bundle আর্গুমেন্টের মাধ্যমে পড়া যেতে পারে। এই ইঙ্গিতগুলি অনুসরণ করলে সিস্টেমটি ন্যাভিগেশনাল ট্যাব হিসাবে সর্বোত্তমভাবে রুট বিষয়বস্তু প্রদর্শন করতে দেয়। আপনি যদি এই ইঙ্গিতগুলি অনুসরণ না করেন, তাহলে সিস্টেমের দ্বারা কিছু রুট সামগ্রী বাদ দেওয়া বা কম আবিষ্কারযোগ্য করা হতে পারে৷ দুটি ইঙ্গিত পাঠানো হয়:

প্রাসঙ্গিক রুট ইঙ্গিত পড়তে নিম্নলিখিত কোড ব্যবহার করুন:

কোটলিন

import androidx.media.utils.MediaConstants

// Later, in your MediaBrowserServiceCompat.
override fun onGetRoot(
    clientPackageName: String,
    clientUid: Int,
    rootHints: Bundle
): BrowserRoot {

  val maximumRootChildLimit = rootHints.getInt(
      MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_LIMIT,
      /* defaultValue= */ 4)
  val supportedRootChildFlags = rootHints.getInt(
      MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS,
      /* defaultValue= */ MediaItem.FLAG_BROWSABLE)

  // Rest of method...
}

জাভা

import androidx.media.utils.MediaConstants;

// Later, in your MediaBrowserServiceCompat.
@Override
public BrowserRoot onGetRoot(
    String clientPackageName, int clientUid, Bundle rootHints) {

    int maximumRootChildLimit = rootHints.getInt(
        MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_LIMIT,
        /* defaultValue= */ 4);
    int supportedRootChildFlags = rootHints.getInt(
        MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS,
        /* defaultValue= */ MediaItem.FLAG_BROWSABLE);

    // Rest of method...
}

আপনি এই ইঙ্গিতগুলির মানগুলির উপর ভিত্তি করে আপনার বিষয়বস্তু অনুক্রমের কাঠামোর জন্য যুক্তির শাখা বেছে নিতে পারেন, বিশেষ করে যদি আপনার অনুক্রমটি Android Auto এবং Android Automotive OS এর বাইরে MediaBrowser ইন্টিগ্রেশনের মধ্যে পরিবর্তিত হয়। উদাহরণস্বরূপ, যদি আপনি সাধারণত একটি রুট খেলার যোগ্য আইটেম দেখান, তাহলে সমর্থিত পতাকা ইঙ্গিতের মানের কারণে আপনি এটিকে একটি রুট ব্রাউজযোগ্য আইটেমের অধীনে নেস্ট করতে চাইতে পারেন।

রুট ইঙ্গিতগুলি ছাড়াও, ট্যাবগুলি সর্বোত্তমভাবে রেন্ডার করতে সহায়তা করার জন্য অনুসরণ করার জন্য কয়েকটি অতিরিক্ত নির্দেশিকা রয়েছে:

  • প্রতিটি ট্যাব আইটেমের জন্য একরঙা, বিশেষত সাদা, আইকন সরবরাহ করুন।
  • প্রতিটি ট্যাব আইটেমের জন্য সংক্ষিপ্ত কিন্তু অর্থপূর্ণ লেবেল সরবরাহ করুন। লেবেলগুলি ছোট রাখলে স্ট্রিংগুলি কেটে যাওয়ার সম্ভাবনা কমে যায়৷

মিডিয়া আর্টওয়ার্ক প্রদর্শন করুন

মিডিয়া আইটেমগুলির জন্য আর্টওয়ার্ক অবশ্যই একটি স্থানীয় URI হিসাবে ContentResolver.SCHEME_CONTENT বা ContentResolver.SCHEME_ANDROID_RESOURCE ব্যবহার করে পাস করতে হবে। এই স্থানীয় ইউআরআইকে অবশ্যই একটি বিটম্যাপ বা অ্যাপ্লিকেশনের সংস্থানগুলিতে আঁকাযোগ্য ভেক্টরের সমাধান করতে হবে। MediaDescriptionCompat বস্তুর জন্য বিষয়বস্তু অনুক্রমের আইটেম প্রতিনিধিত্ব করে, setIconUri() মাধ্যমে URI পাস করুন। MediaMetadataCompat বস্তুর জন্য যা বর্তমানে বাজানো আইটেমের প্রতিনিধিত্ব করে, নিচের যে কোনো একটি ব্যবহার করে putString() মাধ্যমে URI পাস করুন:

নিম্নলিখিত ধাপগুলি বর্ণনা করে কিভাবে একটি ওয়েব URI থেকে আর্ট ডাউনলোড করতে হয় এবং একটি স্থানীয় URI-এর মাধ্যমে এটিকে প্রকাশ করতে হয়। আরও সম্পূর্ণ উদাহরণের জন্য, ইউনিভার্সাল অ্যান্ড্রয়েড মিউজিক প্লেয়ার নমুনা অ্যাপে openFile() এর বাস্তবায়ন এবং আশেপাশের পদ্ধতিগুলি দেখুন।

  1. ওয়েব ইউআরআই-এর সাথে সম্পর্কিত একটি content:// URI তৈরি করুন। মিডিয়া ব্রাউজার পরিষেবা এবং মিডিয়া সেশন এই কন্টেন্ট URIকে Android Auto এবং Android Automotive OS-এ পাস করে।

    কোটলিন

    fun Uri.asAlbumArtContentURI(): Uri {
      return Uri.Builder()
        .scheme(ContentResolver.SCHEME_CONTENT)
        .authority(CONTENT_PROVIDER_AUTHORITY)
        .appendPath(this.getPath()) // Make sure you trust the URI
        .build()
    }

    জাভা

    public static Uri asAlbumArtContentURI(Uri webUri) {
      return new Uri.Builder()
        .scheme(ContentResolver.SCHEME_CONTENT)
        .authority(CONTENT_PROVIDER_AUTHORITY)
        .appendPath(webUri.getPath()) // Make sure you trust the URI!
        .build();
    }
  2. আপনার ContentProvider.openFile() এর বাস্তবায়নে, সংশ্লিষ্ট URI-এর জন্য একটি ফাইল বিদ্যমান কিনা তা পরীক্ষা করুন। যদি না হয়, ডাউনলোড করুন এবং ইমেজ ফাইল ক্যাশে. নিম্নলিখিত কোড স্নিপেট গ্লাইড ব্যবহার করে।

    কোটলিন

    override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? {
      val context = this.context ?: return null
      val file = File(context.cacheDir, uri.path)
      if (!file.exists()) {
        val remoteUri = Uri.Builder()
            .scheme("https")
            .authority("my-image-site")
            .appendPath(uri.path)
            .build()
        val cacheFile = Glide.with(context)
            .asFile()
            .load(remoteUri)
            .submit()
            .get(DOWNLOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS)
    
        cacheFile.renameTo(file)
        file = cacheFile
      }
      return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
    }

    জাভা

    @Nullable
    @Override
    public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode)
        throws FileNotFoundException {
      Context context = this.getContext();
      File file = new File(context.getCacheDir(), uri.getPath());
      if (!file.exists()) {
        Uri remoteUri = new Uri.Builder()
            .scheme("https")
            .authority("my-image-site")
            .appendPath(uri.getPath())
            .build();
        File cacheFile = Glide.with(context)
            .asFile()
            .load(remoteUri)
            .submit()
            .get(DOWNLOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS);
    
        cacheFile.renameTo(file);
        file = cacheFile;
      }
      return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
    }

বিষয়বস্তু প্রদানকারীদের সম্পর্কে আরো বিস্তারিত জানার জন্য, একটি বিষয়বস্তু প্রদানকারী তৈরি করা দেখুন।

বিষয়বস্তুর শৈলী প্রয়োগ করুন

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

আপনি নিম্নলিখিত বিষয়বস্তু শৈলী ব্যবহার করতে পারেন:

তালিকা আইটেম

এই বিষয়বস্তুর শৈলীটি ছবির উপর শিরোনাম এবং মেটাডেটাকে অগ্রাধিকার দেয়।

গ্রিড আইটেম

এই বিষয়বস্তু শৈলী শিরোনাম এবং মেটাডেটার চেয়ে চিত্রগুলিকে অগ্রাধিকার দেয়৷

ডিফল্ট সামগ্রী শৈলী সেট করুন

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

নিম্নলিখিত অতিরিক্তগুলি বান্ডেলে কী হিসাবে ব্যবহার করা যেতে পারে:

  • DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE : ব্রাউজ ট্রির মধ্যে সমস্ত ব্রাউজযোগ্য আইটেমের জন্য একটি উপস্থাপনা ইঙ্গিত নির্দেশ করে৷
  • DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE : ব্রাউজ ট্রির মধ্যে সমস্ত প্লেযোগ্য আইটেমের জন্য একটি উপস্থাপনা ইঙ্গিত নির্দেশ করে৷

এই আইটেমগুলির উপস্থাপনাকে প্রভাবিত করতে কীগুলি নিম্নলিখিত পূর্ণসংখ্যার ধ্রুবক মানগুলিকে মানচিত্র করতে পারে:

  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM : সংশ্লিষ্ট আইটেমগুলিকে তালিকা আইটেম হিসাবে উপস্থাপন করা হয়েছে৷
  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM : সংশ্লিষ্ট আইটেমগুলি গ্রিড আইটেম হিসাবে উপস্থাপিত হয়৷
  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM : সংশ্লিষ্ট আইটেমগুলিকে "বিভাগ" তালিকা আইটেম হিসাবে উপস্থাপন করা হয়েছে৷ এগুলি সাধারণ তালিকার আইটেমগুলির মতোই তবে আইটেমগুলির আইকনগুলির চারপাশে মার্জিন প্রয়োগ করা হয়, যেহেতু আইকনগুলি ছোট হলে আরও ভাল দেখায়৷ আইকনগুলি অবশ্যই টিন্টেবল ভেক্টর অঙ্কনযোগ্য হতে হবে। এই ইঙ্গিতটি শুধুমাত্র ব্রাউজযোগ্য আইটেমগুলির জন্য প্রদান করা হবে বলে আশা করা হচ্ছে।
  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_GRID_ITEM : সংশ্লিষ্ট আইটেমগুলিকে "বিভাগ" গ্রিড আইটেম হিসাবে উপস্থাপন করা হয়েছে৷ এগুলি সাধারণ গ্রিড আইটেমগুলির মতোই, আইটেমগুলির আইকনগুলির চারপাশে মার্জিন প্রয়োগ করা ব্যতীত, যেহেতু আইকনগুলি ছোট হলে আরও ভাল দেখায়৷ আইকনগুলি অবশ্যই টিন্টেবল ভেক্টর অঙ্কনযোগ্য হতে হবে। এই ইঙ্গিতটি শুধুমাত্র ব্রাউজযোগ্য আইটেমগুলির জন্য প্রদান করা হবে বলে আশা করা হচ্ছে।

নিম্নলিখিত কোড স্নিপেটটি দেখায় কিভাবে ব্রাউজযোগ্য আইটেমগুলির জন্য গ্রিডগুলিতে এবং প্লেযোগ্য আইটেমগুলিকে তালিকার জন্য ডিফল্ট সামগ্রী শৈলী সেট করতে হয়:

কোটলিন

import androidx.media.utils.MediaConstants

@Nullable
override fun onGetRoot(
    @NonNull clientPackageName: String,
    clientUid: Int,
    @Nullable rootHints: Bundle
): BrowserRoot {
    val extras = Bundle()
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM)
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM)
    return BrowserRoot(ROOT_ID, extras)
}

জাভা

import androidx.media.utils.MediaConstants;

@Nullable
@Override
public BrowserRoot onGetRoot(
    @NonNull String clientPackageName,
    int clientUid,
    @Nullable Bundle rootHints) {
    Bundle extras = new Bundle();
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM);
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM);
    return new BrowserRoot(ROOT_ID, extras);
}

প্রতি আইটেম বিষয়বস্তু শৈলী সেট করুন

বিষয়বস্তু শৈলী API আপনাকে যেকোনো ব্রাউজযোগ্য মিডিয়া আইটেমের বাচ্চাদের জন্য ডিফল্ট সামগ্রী শৈলীকে ওভাররাইড করতে দেয়, সেইসাথে যেকোনো মিডিয়া আইটেম নিজেই।

একটি ব্রাউজযোগ্য মিডিয়া আইটেমের বাচ্চাদের জন্য ডিফল্ট ওভাররাইড করতে, মিডিয়া আইটেমের MediaDescription এ একটি অতিরিক্ত বান্ডিল তৈরি করুন এবং একই পূর্বে উল্লেখিত ইঙ্গিত যোগ করুন। DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE সেই আইটেমটির খেলার যোগ্য শিশুদের জন্য প্রযোজ্য, যখন DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE সেই আইটেমটির ব্রাউজযোগ্য শিশুদের জন্য প্রযোজ্য৷

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

নিম্নলিখিত কোড স্নিপেট দেখায় কিভাবে একটি ব্রাউজযোগ্য MediaItem তৈরি করতে হয় যা নিজের এবং তার বাচ্চাদের উভয়ের জন্য ডিফল্ট সামগ্রী শৈলীকে ওভাররাইড করে। এটি নিজেকে একটি বিভাগ তালিকা আইটেম হিসাবে শৈলী করে, এটির ব্রাউজযোগ্য শিশুদের তালিকা আইটেম হিসাবে এবং এটির খেলার যোগ্য শিশুদের গ্রিড আইটেম হিসাবে:

কোটলিন

import androidx.media.utils.MediaConstants

private fun createBrowsableMediaItem(
    mediaId: String,
    folderName: String,
    iconUri: Uri
): MediaBrowser.MediaItem {
    val mediaDescriptionBuilder = MediaDescription.Builder()
    mediaDescriptionBuilder.setMediaId(mediaId)
    mediaDescriptionBuilder.setTitle(folderName)
    mediaDescriptionBuilder.setIconUri(iconUri)
    val extras = Bundle()
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM)
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM)
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM)
    mediaDescriptionBuilder.setExtras(extras)
    return MediaBrowser.MediaItem(
        mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE)
}

জাভা

import androidx.media.utils.MediaConstants;

private MediaBrowser.MediaItem createBrowsableMediaItem(
    String mediaId,
    String folderName,
    Uri iconUri) {
    MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder();
    mediaDescriptionBuilder.setMediaId(mediaId);
    mediaDescriptionBuilder.setTitle(folderName);
    mediaDescriptionBuilder.setIconUri(iconUri);
    Bundle extras = new Bundle();
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM);
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM);
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM);
    mediaDescriptionBuilder.setExtras(extras);
    return new MediaBrowser.MediaItem(
        mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE);
}

শিরোনাম ইঙ্গিত ব্যবহার করে গ্রুপ আইটেম

সম্পর্কিত মিডিয়া আইটেমগুলিকে একত্রিত করতে, আপনি প্রতি-আইটেম ইঙ্গিত ব্যবহার করেন। একটি গ্রুপের প্রতিটি মিডিয়া আইটেমকে তাদের MediaDescription এ একটি অতিরিক্ত বান্ডিল ঘোষণা করতে হবে যাতে DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE কী এবং একটি অভিন্ন স্ট্রিং মান সহ একটি ম্যাপিং অন্তর্ভুক্ত থাকে। এই স্ট্রিংটি স্থানীয়করণ করুন, যা গ্রুপের শিরোনাম হিসাবে ব্যবহৃত হয়।

নিম্নলিখিত কোড স্নিপেট দেখায় কিভাবে "Songs" এর একটি উপগোষ্ঠী শিরোনাম সহ একটি MediaItem তৈরি করতে হয়:

কোটলিন

import androidx.media.utils.MediaConstants

private fun createMediaItem(
    mediaId: String,
    folderName: String,
    iconUri: Uri
): MediaBrowser.MediaItem {
    val mediaDescriptionBuilder = MediaDescription.Builder()
    mediaDescriptionBuilder.setMediaId(mediaId)
    mediaDescriptionBuilder.setTitle(folderName)
    mediaDescriptionBuilder.setIconUri(iconUri)
    val extras = Bundle()
    extras.putString(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
        "Songs")
    mediaDescriptionBuilder.setExtras(extras)
    return MediaBrowser.MediaItem(
        mediaDescriptionBuilder.build(), /* playable or browsable flag*/)
}

জাভা

import androidx.media.utils.MediaConstants;

private MediaBrowser.MediaItem createMediaItem(String mediaId, String folderName, Uri iconUri) {
   MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder();
   mediaDescriptionBuilder.setMediaId(mediaId);
   mediaDescriptionBuilder.setTitle(folderName);
   mediaDescriptionBuilder.setIconUri(iconUri);
   Bundle extras = new Bundle();
   extras.putString(
       MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
       "Songs");
   mediaDescriptionBuilder.setExtras(extras);
   return new MediaBrowser.MediaItem(
       mediaDescriptionBuilder.build(), /* playable or browsable flag*/);
}

আপনার অ্যাপকে অবশ্যই সমস্ত মিডিয়া আইটেমগুলি পাস করতে হবে যা আপনি একটি সংলগ্ন ব্লক হিসাবে একসাথে গ্রুপ করতে চান৷ উদাহরণস্বরূপ, ধরুন আপনি মিডিয়া আইটেমগুলির দুটি গ্রুপ প্রদর্শন করতে চান, "গান" এবং "অ্যালবাম" সেই ক্রমে, এবং আপনার অ্যাপটি নিম্নলিখিত ক্রমে পাঁচটি মিডিয়া আইটেম পাস করে:

  1. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs" ) সহ মিডিয়া আইটেম A
  2. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums" ) সহ মিডিয়া আইটেম B
  3. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs" ) সহ মিডিয়া আইটেম C
  4. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs" ) সহ মিডিয়া আইটেম D
  5. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums" ) সহ মিডিয়া আইটেম E

যেহেতু "গান" গ্রুপ এবং "অ্যালবাম" গোষ্ঠীর মিডিয়া আইটেমগুলি সংলগ্ন ব্লকগুলিতে একসাথে রাখা হয় না, তাই Android Auto এবং Android Automotive OS এটিকে নিম্নলিখিত চারটি গ্রুপ হিসাবে ব্যাখ্যা করে:

  • গ্রুপ 1 মিডিয়া আইটেম A ধারণকারী "গান" বলা হয়
  • গ্রুপ 2 মিডিয়া আইটেম B ধারণকারী "অ্যালবাম" বলে
  • গ্রুপ 3 মিডিয়া আইটেম C এবং D ধারণকারী "গান" বলা হয়
  • গ্রুপ 4 মিডিয়া আইটেম E ধারণকারী "অ্যালবাম" বলা হয়

দুটি গ্রুপে এই আইটেমগুলি প্রদর্শন করতে, আপনার অ্যাপটিকে অবশ্যই মিডিয়া আইটেমগুলিকে নিম্নলিখিত ক্রমে পাস করতে হবে:

  1. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs" ) সহ মিডিয়া আইটেম A
  2. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs" ) সহ মিডিয়া আইটেম C
  3. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs" ) সহ মিডিয়া আইটেম D
  4. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums" ) সহ মিডিয়া আইটেম B
  5. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums" ) সহ মিডিয়া আইটেম E

অতিরিক্ত মেটাডেটা সূচক প্রদর্শন করুন

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

চিত্র 3. গান এবং শিল্পী সনাক্তকারী মেটাডেটা সহ প্লেব্যাক ভিউ পাশাপাশি একটি আইকন যা স্পষ্ট বিষয়বস্তু নির্দেশ করে৷

চিত্র 4. প্রথম আইটেমটিতে প্লে না করা বিষয়বস্তুর জন্য একটি বিন্দু এবং দ্বিতীয় আইটেমের আংশিকভাবে খেলা সামগ্রীর জন্য একটি অগ্রগতি বার সহ ভিউ ব্রাউজ করুন৷

নিম্নলিখিত ধ্রুবকগুলি MediaItem বিবরণ অতিরিক্ত এবং MediaMetadata অতিরিক্ত উভয় ক্ষেত্রেই ব্যবহার করা যেতে পারে:

  • EXTRA_DOWNLOAD_STATUS : একটি আইটেমের ডাউনলোড স্থিতি নির্দেশ করে৷ এই ধ্রুবকটিকে কী হিসাবে ব্যবহার করুন; নিম্নলিখিত দীর্ঘ ধ্রুবকগুলি সম্ভাব্য মান:
    • STATUS_DOWNLOADED : আইটেমটি সম্পূর্ণরূপে ডাউনলোড করা হয়েছে৷
    • STATUS_DOWNLOADING : আইটেমটি ডাউনলোড করা হচ্ছে৷
    • STATUS_NOT_DOWNLOADED : আইটেমটি ডাউনলোড করা হয়নি৷
  • METADATA_KEY_IS_EXPLICIT : আইটেমটিতে স্পষ্ট বিষয়বস্তু আছে কিনা তা নির্দেশ করে। একটি আইটেম সুস্পষ্ট নির্দেশ করতে, কী হিসাবে এই ধ্রুবকটি এবং মান হিসাবে দীর্ঘ METADATA_VALUE_ATTRIBUTE_PRESENT ব্যবহার করুন৷

নিম্নলিখিত ধ্রুবক শুধুমাত্র MediaItem বিবরণ অতিরিক্ত ব্যবহার করা যেতে পারে:

  • DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS : পডকাস্ট পর্ব বা অডিওবুকের মতো দীর্ঘ-ফর্মের সামগ্রীর সমাপ্তির অবস্থা নির্দেশ করে। এই ধ্রুবকটিকে কী হিসাবে ব্যবহার করুন; নিম্নলিখিত পূর্ণসংখ্যা ধ্রুবকগুলি সম্ভাব্য মান:
  • DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE : 0.0 এবং 1.0 এর মধ্যে দ্বিগুণ হিসাবে দীর্ঘ-ফর্ম সামগ্রীতে সমাপ্তির অগ্রগতির পরিমাণ নির্দেশ করে, অন্তর্ভুক্ত। এই অতিরিক্তটি PARTIALLY_PLAYING অবস্থা সম্পর্কে আরও তথ্য প্রদান করে যাতে Android Auto বা Android Automotive OS একটি আরও অর্থপূর্ণ অগ্রগতি সূচক প্রদর্শন করে, যেমন একটি অগ্রগতি বার৷ আপনি যদি এটি অতিরিক্ত ব্যবহার করেন, তাহলে এই নির্দেশিকায় প্রাথমিক ইম্প্রেশনের পরে কীভাবে এই সূচকটিকে আপ টু ডেট রাখতে হয় তা জানতে ব্রাউজ ভিউতে প্রগ্রেস বার আপডেট করার বিষয়ে বিভাগটি দেখুন।

ব্যবহারকারী মিডিয়া ব্রাউজ ট্রি ব্রাউজ করার সময় প্রদর্শিত সূচকগুলি প্রদর্শন করতে, একটি অতিরিক্ত বান্ডিল তৈরি করুন যাতে এই ধ্রুবকগুলির এক বা একাধিক অন্তর্ভুক্ত থাকে এবং সেই বান্ডিলটিকে MediaDescription.Builder.setExtras() পদ্ধতিতে পাস করুন৷

নিম্নলিখিত কোড স্নিপেট দেখায় কিভাবে একটি সুস্পষ্ট মিডিয়া আইটেমের জন্য সূচক প্রদর্শন করতে হয় যা 70% সম্পূর্ণ:

কোটলিন

import androidx.media.utils.MediaConstants

val extras = Bundle()
extras.putLong(
    MediaConstants.METADATA_KEY_IS_EXPLICIT,
    MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
extras.putInt(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
    MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED)
extras.putDouble(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.7)
val description =
    MediaDescriptionCompat.Builder()
        .setMediaId(/*...*/)
        .setTitle(resources.getString(/*...*/))
        .setExtras(extras)
        .build()
return MediaBrowserCompat.MediaItem(description, /* flags */)

জাভা

import androidx.media.utils.MediaConstants;

Bundle extras = new Bundle();
extras.putLong(
    MediaConstants.METADATA_KEY_IS_EXPLICIT,
    MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT);
extras.putInt(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
    MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED);
extras.putDouble(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.7);
MediaDescriptionCompat description =
    new MediaDescriptionCompat.Builder()
        .setMediaId(/*...*/)
        .setTitle(resources.getString(/*...*/))
        .setExtras(extras)
        .build();
return new MediaBrowserCompat.MediaItem(description, /* flags */);

বর্তমানে চালানো হচ্ছে এমন একটি মিডিয়া আইটেমের জন্য সূচক প্রদর্শন করতে, আপনি আপনার mediaSession MediaMetadataCompatMETADATA_KEY_IS_EXPLICIT বা EXTRA_DOWNLOAD_STATUS এর জন্য Long মান ঘোষণা করতে পারেন। আপনি প্লেব্যাক ভিউতে DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS বা DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE সূচকগুলি প্রদর্শন করতে পারবেন না৷

নিম্নলিখিত কোড স্নিপেট দেখায় যে প্লেব্যাক ভিউতে বর্তমান গানটি স্পষ্ট এবং ডাউনলোড করা হয়েছে তা কীভাবে নির্দেশ করতে হয়:

কোটলিন

import androidx.media.utils.MediaConstants

mediaSession.setMetadata(
    MediaMetadataCompat.Builder()
        .putString(
            MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Song Name")
        .putString(
            MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "Artist name")
        .putString(
            MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI,
            albumArtUri.toString())
        .putLong(
            MediaConstants.METADATA_KEY_IS_EXPLICIT,
            MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
        .putLong(
            MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS,
            MediaDescriptionCompat.STATUS_DOWNLOADED)
        .build())

জাভা

import androidx.media.utils.MediaConstants;

mediaSession.setMetadata(
    new MediaMetadataCompat.Builder()
        .putString(
            MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Song Name")
        .putString(
            MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "Artist name")
        .putString(
            MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI,
            albumArtUri.toString())
        .putLong(
            MediaConstants.METADATA_KEY_IS_EXPLICIT,
            MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
        .putLong(
            MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS,
            MediaDescriptionCompat.STATUS_DOWNLOADED)
        .build());

বিষয়বস্তু প্লে হচ্ছে হিসাবে ব্রাউজ দৃশ্যে অগ্রগতি বার আপডেট করুন

পূর্বে উল্লিখিত হিসাবে, আপনি ব্রাউজ ভিউতে আংশিকভাবে খেলা সামগ্রীর জন্য একটি অগ্রগতি বার দেখাতে DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE অতিরিক্ত ব্যবহার করতে পারেন৷ যাইহোক, যদি একজন ব্যবহারকারী Android Auto বা Android Automotive OS থেকে আংশিকভাবে প্লে করা সামগ্রী চালিয়ে যান, তাহলে সময়ের সাথে সাথে সেই সূচকটি ভুল হয়ে যায়।

Android Auto এবং Android Automotive OS-এর জন্য অগ্রগতি বার আপ টু ডেট রাখতে, আপনি ব্রাউজ ভিউতে মিডিয়া আইটেমগুলির সাথে চলমান সামগ্রী লিঙ্ক করতে MediaMetadataCompat এবং PlaybackStateCompat এ অতিরিক্ত তথ্য সরবরাহ করতে পারেন। মিডিয়া আইটেমের জন্য একটি স্বয়ংক্রিয়ভাবে আপডেট হওয়া অগ্রগতি বার থাকার জন্য নিম্নলিখিত প্রয়োজনীয়তাগুলি অবশ্যই পূরণ করতে হবে:

  • যখন এটি তৈরি করা হয়, তখন MediaItem অবশ্যই তার অতিরিক্তগুলিতে 0.0 এবং 1.0 এর মধ্যে একটি মান সহ DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE পাঠাতে হবে।
  • MediaMetadataCompat অবশ্যই METADATA_KEY_MEDIA_ID পাঠাতে হবে একটি স্ট্রিং মান সহ MediaItem এ পাস করা মিডিয়া আইডির সমান।
  • PlaybackStateCompatPLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID কী সহ একটি অতিরিক্ত অন্তর্ভুক্ত করতে হবে যা MediaItem এ পাস করা মিডিয়া আইডির সমান একটি স্ট্রিং মানের মানচিত্র করে।

নিচের কোড স্নিপেটটি দেখায় কিভাবে নির্দেশ করা যায় যে বর্তমানে বাজানো আইটেমটি ব্রাউজ ভিউতে একটি আইটেমের সাথে লিঙ্ক করা হয়েছে:

কোটলিন

import androidx.media.utils.MediaConstants

// When the MediaItem is constructed to show in the browse view.
// Suppose the item was 25% complete when the user launched the browse view.
val mediaItemExtras = Bundle()
mediaItemExtras.putDouble(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.25)
val description =
    MediaDescriptionCompat.Builder()
        .setMediaId("my-media-id")
        .setExtras(mediaItemExtras)
        // ...and any other setters.
        .build()
return MediaBrowserCompat.MediaItem(description, /* flags */)

// Elsewhere, when the user has selected MediaItem for playback.
mediaSession.setMetadata(
    MediaMetadataCompat.Builder()
        .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, "my-media-id")
        // ...and any other setters.
        .build())

val playbackStateExtras = Bundle()
playbackStateExtras.putString(
    MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, "my-media-id")
mediaSession.setPlaybackState(
    PlaybackStateCompat.Builder()
        .setExtras(playbackStateExtras)
        // ...and any other setters.
        .build())

জাভা

import androidx.media.utils.MediaConstants;

// When the MediaItem is constructed to show in the browse view.
// Suppose the item was 25% complete when the user launched the browse view.
Bundle mediaItemExtras = new Bundle();
mediaItemExtras.putDouble(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.25);
MediaDescriptionCompat description =
    new MediaDescriptionCompat.Builder()
        .setMediaId("my-media-id")
        .setExtras(mediaItemExtras)
        // ...and any other setters.
        .build();
return MediaBrowserCompat.MediaItem(description, /* flags */);

// Elsewhere, when the user has selected MediaItem for playback.
mediaSession.setMetadata(
    new MediaMetadataCompat.Builder()
        .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, "my-media-id")
        // ...and any other setters.
        .build());

Bundle playbackStateExtras = new Bundle();
playbackStateExtras.putString(
    MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, "my-media-id");
mediaSession.setPlaybackState(
    new PlaybackStateCompat.Builder()
        .setExtras(playbackStateExtras)
        // ...and any other setters.
        .build());

চিত্র 5. ব্যবহারকারীর ভয়েস অনুসন্ধানের সাথে সম্পর্কিত মিডিয়া আইটেমগুলি দেখার জন্য একটি "অনুসন্ধান ফলাফল" বিকল্পের সাথে প্লেব্যাক দৃশ্য।

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

ব্রাউজযোগ্য অনুসন্ধান ফলাফল প্রদর্শন করতে, আপনার পরিষেবার onGetRoot() পদ্ধতির অতিরিক্ত বান্ডেলে BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED ধ্রুবক কী অন্তর্ভুক্ত করুন, বুলিয়ান true ম্যাপিং করুন।

নিম্নলিখিত কোড স্নিপেট দেখায় কিভাবে onGetRoot() পদ্ধতিতে সমর্থন সক্ষম করতে হয়:

কোটলিন

import androidx.media.utils.MediaConstants

@Nullable
fun onGetRoot(
    @NonNull clientPackageName: String,
    clientUid: Int,
    @Nullable rootHints: Bundle
): BrowserRoot {
    val extras = Bundle()
    extras.putBoolean(
        MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true)
    return BrowserRoot(ROOT_ID, extras)
}

জাভা

import androidx.media.utils.MediaConstants;

@Nullable
@Override
public BrowserRoot onGetRoot(
    @NonNull String clientPackageName,
    int clientUid,
    @Nullable Bundle rootHints) {
    Bundle extras = new Bundle();
    extras.putBoolean(
        MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true);
    return new BrowserRoot(ROOT_ID, extras);
}

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

আপনি শিরোনাম আইটেমগুলিকে আরও ব্রাউজযোগ্য করতে আপনার পরিষেবার onSearch() পদ্ধতি থেকে অনুসন্ধান ফলাফলগুলিকে সংগঠিত করতে পারেন৷ উদাহরণস্বরূপ, যদি আপনার অ্যাপ সঙ্গীত বাজায়, আপনি অ্যালবাম, শিল্পী এবং গান দ্বারা অনুসন্ধান ফলাফলগুলি সংগঠিত করতে পারেন৷

নিম্নলিখিত কোড স্নিপেট onSearch() পদ্ধতির একটি সহজ বাস্তবায়ন দেখায়:

কোটলিন

fun onSearch(query: String, extras: Bundle) {
  // Detach from results to unblock the caller (if a search is expensive).
  result.detach()
  object:AsyncTask() {
    internal var searchResponse:ArrayList
    internal var succeeded = false
    protected fun doInBackground(vararg params:Void):Void {
      searchResponse = ArrayList()
      if (doSearch(query, extras, searchResponse))
      {
        succeeded = true
      }
      return null
    }
    protected fun onPostExecute(param:Void) {
      if (succeeded)
      {
        // Sending an empty List informs the caller that there were no results.
        result.sendResult(searchResponse)
      }
      else
      {
        // This invokes onError() on the search callback.
        result.sendResult(null)
      }
      return null
    }
  }.execute()
}
// Populates resultsToFill with search results. Returns true on success or false on error.
private fun doSearch(
    query: String,
    extras: Bundle,
    resultsToFill: ArrayList
): Boolean {
  // Implement this method.
}

জাভা

@Override
public void onSearch(final String query, final Bundle extras,
                        Result<List<MediaItem>> result) {

  // Detach from results to unblock the caller (if a search is expensive).
  result.detach();

  new AsyncTask<Void, Void, Void>() {
    List<MediaItem> searchResponse;
    boolean succeeded = false;
    @Override
    protected Void doInBackground(Void... params) {
      searchResponse = new ArrayList<MediaItem>();
      if (doSearch(query, extras, searchResponse)) {
        succeeded = true;
      }
      return null;
    }

    @Override
    protected void onPostExecute(Void param) {
      if (succeeded) {
       // Sending an empty List informs the caller that there were no results.
       result.sendResult(searchResponse);
      } else {
        // This invokes onError() on the search callback.
        result.sendResult(null);
      }
    }
  }.execute()
}

/** Populates resultsToFill with search results. Returns true on success or false on error. */
private boolean doSearch(String query, Bundle extras, ArrayList<MediaItem> resultsToFill) {
    // Implement this method.
}

কাস্টম ব্রাউজ অ্যাকশন

একটি একক কাস্টম ব্রাউজ কর্ম.

চিত্র 6. একক কাস্টম ব্রাউজ অ্যাকশন

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

একটি কাস্টম ব্রাউজ কর্ম ওভারফ্লো মেনু.

চিত্র 7. কাস্টম ব্রাউজ অ্যাকশন ওভারফ্লো

যদি OEM প্রদর্শনের অনুমতি দেয় তার চেয়ে বেশি কাস্টম অ্যাকশন থাকে, ব্যবহারকারীর কাছে একটি ওভারফ্লো মেনু উপস্থাপন করা হবে।

তারা কিভাবে কাজ করে?

প্রতিটি কাস্টম ব্রাউজ অ্যাকশন এর সাথে সংজ্ঞায়িত করা হয়েছে:

  • একটি অ্যাকশন আইডি (একটি অনন্য স্ট্রিং শনাক্তকারী)
  • একটি অ্যাকশন লেবেল (ব্যবহারকারীর কাছে প্রদর্শিত পাঠ্য)
  • একটি অ্যাকশন আইকন URI (একটি ভেক্টর অঙ্কনযোগ্য যা টিন্ট করা যেতে পারে)

আপনি আপনার BrowseRoot এর অংশ হিসাবে বিশ্বব্যাপী কাস্টম ব্রাউজ ক্রিয়াগুলির একটি তালিকা সংজ্ঞায়িত করেন। তারপর আপনি পৃথক MediaItem.

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

একটি ব্রাউজ নোড রুটে কাস্টম ব্রাউজ কর্ম।

চিত্র 8. কাস্টম ব্রাউজ অ্যাকশন টুলবার

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

কাস্টম ব্রাউজ অ্যাকশন কিভাবে বাস্তবায়ন করবেন

আপনার প্রজেক্টে কাস্টম ব্রাউজ অ্যাকশন যোগ করার ধাপগুলি এখানে রয়েছে:

  1. আপনার MediaBrowserServiceCompat বাস্তবায়নে দুটি পদ্ধতি ওভাররাইড করুন:
  2. রানটাইমে কর্ম সীমা পার্স করুন:
    • onGetRoot() এ, rootHints Bundle BROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT কী ব্যবহার করে প্রতিটি MediaItem জন্য অনুমোদিত সর্বাধিক সংখ্যক অ্যাকশন পান। 0 এর একটি সীমা নির্দেশ করে যে বৈশিষ্ট্যটি সিস্টেম দ্বারা সমর্থিত নয়৷
  3. কাস্টম ব্রাউজ অ্যাকশনের বিশ্বব্যাপী তালিকা তৈরি করুন:
    • প্রতিটি কর্মের জন্য, নিম্নলিখিত কীগুলির সাহায্যে একটি Bundle অবজেক্ট তৈরি করুন: * EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID : অ্যাকশন আইডি * EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL : অ্যাকশন লেবেল * EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI একটি অ্যাকশনের তালিকায় একটি Bundle অবজেক্ট যোগ করুন * সমস্ত অ্যাকশনের তালিকায় যোগ করুন।
  4. আপনার BrowseRoot বিশ্বব্যাপী তালিকা যোগ করুন:
  5. আপনার MediaItem অবজেক্টে কর্ম যোগ করুন:
    • আপনি DESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST কী ব্যবহার করে MediaDescriptionCompat অতিরিক্ত অ্যাকশন আইডিগুলির তালিকা অন্তর্ভুক্ত করে পৃথক MediaItem অবজেক্টে অ্যাকশন যোগ করতে পারেন। এই তালিকাটি অবশ্যই BrowseRoot এ সংজ্ঞায়িত কর্মের বিশ্বব্যাপী তালিকার একটি উপসেট হতে হবে।
  6. ক্রিয়াগুলি পরিচালনা করুন এবং অগ্রগতি বা ফলাফল ফিরিয়ে দিন:
    • onCustomAction এ, অ্যাকশন আইডি এবং আপনার প্রয়োজনীয় অন্যান্য ডেটার উপর ভিত্তি করে অ্যাকশন পরিচালনা করুন। EXTRAS_KEY_CUSTOM_BROWSER_ACTION_MEDIA_ITEM_ID কী ব্যবহার করে আপনি MediaItem এর ID পেতে পারেন যা অতিরিক্ত থেকে ক্রিয়াটি ট্রিগার করেছে। .
    • আপনি অগ্রগতি বা ফলাফল বান্ডেলে কী EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM অন্তর্ভুক্ত করে একটি MediaItem জন্য কর্মের তালিকা আপডেট করতে পারেন।

কাস্টম ব্রাউজ অ্যাকশনের সাথে শুরু করতে আপনি আপনার BrowserServiceCompat এ কিছু পরিবর্তন করতে পারেন।

BrowserServiceCompat ওভাররাইড করুন

আপনাকে MediaBrowserServiceCompat এ নিম্নলিখিত পদ্ধতিগুলি ওভাররাইড করতে হবে।

public void onLoadItem(String itemId, @NonNull Result<MediaBrowserCompat.MediaItem> result)

public void onCustomAction(@NonNull String action, Bundle extras, @NonNull Result<Bundle> result)

পার্স কর্ম সীমা

কতগুলি কাস্টম ব্রাউজ অ্যাকশন সমর্থিত তা দেখতে আপনার চেক করা উচিত।

public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, Bundle rootHints) {
    rootHints.getInt(
            MediaConstants.BROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT, 0)
}

একটি কাস্টম ব্রাউজ অ্যাকশন তৈরি করুন

প্রতিটি ক্রিয়া একটি পৃথক Bundle প্যাক করা দরকার।

  • অ্যাকশন আইডি
    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID,
                    "<ACTION_ID>")
  • অ্যাকশন লেবেল
    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL,
                    "<ACTION_LABEL>")
  • অ্যাকশন আইকন উরি
    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI,
                    "<ACTION_ICON_URI>")

Parceable ArrayList কাস্টম ব্রাউজ ক্রিয়া যুক্ত করুন

সমস্ত কাস্টম ব্রাউজ অ্যাকশন Bundle অবজেক্টগুলিকে একটি ArrayList যুক্ত করুন।

private ArrayList<Bundle> createCustomActionsList(
                                        CustomBrowseAction browseActions) {
    ArrayList<Bundle> browseActionsBundle = new ArrayList<>();
    for (CustomBrowseAction browseAction : browseActions) {
        Bundle action = new Bundle();
        action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID,
                browseAction.mId);
        action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL,
                getString(browseAction.mLabelResId));
        action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI,
                browseAction.mIcon);
        browseActionsBundle.add(action);
    }
    return browseActionsBundle;
}

ব্রাউজ রুটে কাস্টম ব্রাউজ অ্যাকশন তালিকা যুক্ত করুন

public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid,
                             Bundle rootHints) {
    Bundle browserRootExtras = new Bundle();
    browserRootExtras.putParcelableArrayList(
            BROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST,
            createCustomActionsList()));
    mRoot = new BrowserRoot(ROOT_ID, browserRootExtras);
    return mRoot;
}

একটি MediaItem ক্রিয়া যুক্ত করুন

MediaDescriptionCompat buildDescription (long id, String title, String subtitle,
                String description, Uri iconUri, Uri mediaUri,
                ArrayList<String> browseActionIds) {

    MediaDescriptionCompat.Builder bob = new MediaDescriptionCompat.Builder();
    bob.setMediaId(id);
    bob.setTitle(title);
    bob.setSubtitle(subtitle);
    bob.setDescription(description);
    bob.setIconUri(iconUri);
    bob.setMediaUri(mediaUri);

    Bundle extras = new Bundle();
    extras.putStringArrayList(
          DESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST,
          browseActionIds);

    bob.setExtras(extras);
    return bob.build();
}
MediaItem mediaItem = new MediaItem(buildDescription(...), flags);

onCustomAction ফলাফল তৈরি করুন

  • Bundle extras থেকে পার্স মিডিয়াড:
    @Override
    public void onCustomAction(
              @NonNull String action, Bundle extras, @NonNull Result<Bundle> result){
      String mediaId = extras.getString(MediaConstans.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_MEDIA_ITEM_ID);
    }
  • অ্যাসিঙ্ক্রোনাস ফলাফলের জন্য বিচ্ছিন্ন ফলাফল। result.detach()
  • ফলাফল বান্ডিল তৈরি করুন
    • ব্যবহারকারী বার্তা
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE,
                mContext.getString(stringRes))
    • আইটেম আপডেট করুন (কোনও আইটেমে ক্রিয়া আপডেট করতে ব্যবহার করুন)
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, mediaId);
    • প্লেব্যাক ভিউ খুলুন
      //Shows user the PBV without changing the playback state
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_SHOW_PLAYING_ITEM, null);
    • ব্রাউজ নোড আপডেট করুন
      //Change current browse node to mediaId
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_BROWSE_NODE, mediaId);
  • যদি কোনও ত্রুটি হয় তবে result.sendError(resultBundle).
  • যদি অগ্রগতি আপডেট হয় তবে result.sendProgressUpdate(resultBundle) কল করুন।
  • result.sendResult(resultBundle) কল করে শেষ করুন।

আপডেট অ্যাকশন স্টেট

EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM কী সহ result.sendProgressUpdate(resultBundle) পদ্ধতিটি ব্যবহার করে আপনি ক্রিয়াকলাপের নতুন অবস্থা প্রতিফলিত করতে MediaItem আপডেট করতে পারেন। এটি আপনাকে তাদের ক্রিয়াকলাপের অগ্রগতি এবং ফলাফল সম্পর্কে ব্যবহারকারীকে রিয়েল-টাইম প্রতিক্রিয়া সরবরাহ করতে দেয়।

উদাহরণ: ক্রিয়া ডাউনলোড করুন

আপনি তিনটি রাজ্যের সাথে ডাউনলোড অ্যাকশন বাস্তবায়নে কীভাবে এই বৈশিষ্ট্যটি ব্যবহার করতে পারেন তার একটি উদাহরণ এখানে:

  1. ডাউনলোড: এটি ক্রিয়াটির প্রাথমিক অবস্থা। যখন ব্যবহারকারী এই ক্রিয়াটি নির্বাচন করেন, আপনি এটি "ডাউনলোডিং" দিয়ে অদলবদল করতে পারেন এবং ইউআই আপডেট করতে sendProgressUpdate কল করতে পারেন।
  2. ডাউনলোডিং: এই রাষ্ট্রটি ইঙ্গিত দেয় যে ডাউনলোডটি চলছে। আপনি এই রাজ্যটি ব্যবহারকারীর কাছে একটি অগ্রগতি বার বা অন্য সূচক দেখানোর জন্য ব্যবহার করতে পারেন।
  3. ডাউনলোড: এই রাষ্ট্রটি ইঙ্গিত দেয় যে ডাউনলোডটি সম্পূর্ণ। ডাউনলোড শেষ হয়ে গেলে, আপনি "ডাউনলোডিং" দিয়ে "ডাউনলোডিং" অদলবদল করতে পারেন এবং আইটেমটি রিফ্রেশ করা উচিত তা বোঝাতে EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM কী দিয়ে sendResult কল করতে পারেন। অতিরিক্তভাবে, আপনি ব্যবহারকারীর কাছে সাফল্যের বার্তা প্রদর্শন করতে EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE কী ব্যবহার করতে পারেন।

এই পদ্ধতিটি আপনাকে ডাউনলোড প্রক্রিয়া এবং এর বর্তমান অবস্থা সম্পর্কে ব্যবহারকারীকে সুস্পষ্ট প্রতিক্রিয়া সরবরাহ করতে দেয়। 25%, 50%, 75%ডাউনলোড রাজ্যগুলি দেখানোর জন্য আপনি আইকনগুলির সাথে আরও বিশদ যুক্ত করতে পারেন।

উদাহরণ: প্রিয় ক্রিয়া

আর একটি উদাহরণ দুটি রাজ্যের সাথে একটি প্রিয় ক্রিয়া:

  1. প্রিয়: এই ক্রিয়াটি এমন আইটেমগুলির জন্য প্রদর্শিত হয় যা ব্যবহারকারীর পছন্দের তালিকায় নেই। যখন ব্যবহারকারী এই ক্রিয়াটি নির্বাচন করেন, আপনি এটি "পছন্দসই" দিয়ে অদলবদল করতে পারেন এবং ইউআই আপডেট করার জন্য EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM কী দিয়ে sendResult কল করতে পারেন।
  2. পছন্দসই: এই ক্রিয়াটি ব্যবহারকারীর পছন্দের তালিকায় থাকা আইটেমগুলির জন্য প্রদর্শিত হয়। যখন ব্যবহারকারী এই ক্রিয়াটি নির্বাচন করেন, আপনি এটি "প্রিয়" দিয়ে অদলবদল করতে পারেন এবং ইউআই আপডেট করার জন্য EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM কী দিয়ে sendResult কল করতে পারেন।

এই পদ্ধতির ব্যবহারকারীদের তাদের পছন্দের আইটেমগুলি পরিচালনা করার জন্য একটি পরিষ্কার এবং ধারাবাহিক উপায় সরবরাহ করে।

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

এই বৈশিষ্ট্যটির সম্পূর্ণ উদাহরণ বাস্তবায়নের জন্য, আপনি TestMediaApp প্রকল্পটি উল্লেখ করতে পারেন।

প্লেব্যাক নিয়ন্ত্রণ সক্ষম করুন

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

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

আপনার মিডিয়া ব্রাউজার সার্ভিসের onCreate() পদ্ধতিতে একটি MediaSessionCompat তৈরি করুন, তারপরে setSessionToken() কল করে মিডিয়া সেশনটি নিবন্ধ করুন।

নিম্নলিখিত কোড স্নিপেট দেখায় যে কীভাবে একটি মিডিয়া সেশন তৈরি এবং নিবন্ধন করা যায়:

কোটলিন

override fun onCreate() {
    super.onCreate()
    ...
    // Start a new MediaSession.
    val session = MediaSessionCompat(this, "session tag").apply {
        // Set a callback object that implements MediaSession.Callback
        // to handle play control requests.
        setCallback(MyMediaSessionCallback())
    }
    sessionToken = session.sessionToken
    ...
}

জাভা

public void onCreate() {
    super.onCreate();
    ...
    // Start a new MediaSession.
    MediaSessionCompat session = new MediaSessionCompat(this, "session tag");
    setSessionToken(session.getSessionToken());

    // Set a callback object that implements MediaSession.Callback
    // to handle play control requests.
    session.setCallback(new MyMediaSessionCallback());
    ...
}

আপনি যখন মিডিয়া সেশন অবজেক্টটি তৈরি করেন, আপনি একটি কলব্যাক অবজেক্ট সেট করেন যা প্লেব্যাক নিয়ন্ত্রণের অনুরোধগুলি পরিচালনা করতে ব্যবহৃত হয়। আপনি আপনার অ্যাপ্লিকেশনটির জন্য MediaSessionCompat.Callback শ্রেণীর একটি বাস্তবায়ন সরবরাহ করে এই কলব্যাক অবজেক্টটি তৈরি করুন। পরবর্তী বিভাগে এই অবজেক্টটি কীভাবে প্রয়োগ করা যায় তা নিয়ে আলোচনা করে।

প্লে কমান্ডগুলি প্রয়োগ করুন

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

সামগ্রী প্লেব্যাক পরিচালনা করতে, আপনার অ্যাপ্লিকেশনটিকে অবশ্যই অ্যাবস্ট্রাক্ট MediaSessionCompat.Callback ক্লাসটি প্রসারিত করতে হবে এবং আপনার অ্যাপ্লিকেশনটি সমর্থন করে এমন পদ্ধতিগুলি প্রয়োগ করতে হবে।

নিম্নলিখিত সমস্ত কলব্যাক পদ্ধতিগুলি প্রয়োগ করুন যা আপনার অ্যাপ্লিকেশনটি যে ধরণের সামগ্রী সরবরাহ করে তা বোঝায়:

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

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

onPlayFromMediaId()
ব্যবহারকারী যখন কোনও নির্দিষ্ট আইটেম খেলতে পছন্দ করে তখন অনুরোধ করা হয়। আপনার মিডিয়া ব্রাউজার পরিষেবাটি আপনার বিষয়বস্তু শ্রেণিবিন্যাসে মিডিয়া আইটেমকে নির্ধারিত আইডিটি পাস করা হয়েছে।
onPlayFromSearch()
যখন ব্যবহারকারী কোনও অনুসন্ধান ক্যোয়ারী থেকে খেলতে পছন্দ করে তখন অনুরোধ করা হয়। অ্যাপ্লিকেশনটি পাস হওয়া অনুসন্ধান স্ট্রিংয়ের উপর ভিত্তি করে একটি উপযুক্ত পছন্দ করতে হবে।
onPause()
যখন ব্যবহারকারী প্লেব্যাক বিরতি দিতে পছন্দ করেন তখন অনুরোধ করা হয়।
onSkipToNext()
যখন ব্যবহারকারী পরবর্তী আইটেমটিতে এড়িয়ে যেতে পছন্দ করে তখন অনুরোধ করা হয়।
onSkipToPrevious()
যখন ব্যবহারকারী পূর্ববর্তী আইটেমটিতে এড়িয়ে যেতে পছন্দ করে তখন অনুরোধ করা হয়।
onStop()
ব্যবহারকারী যখন প্লেব্যাক বন্ধ করতে পছন্দ করেন তখন অনুরোধ করা হয়।

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

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

অডিও সামগ্রী বাজানোর বিষয়ে আরও তথ্যের জন্য, মিডিয়াপ্লেয়ার ওভারভিউ , অডিও অ্যাপ ওভারভিউ এবং এক্সোপ্লেয়ার ওভারভিউ দেখুন।

স্ট্যান্ডার্ড প্লেব্যাক ক্রিয়া সেট করুন

অ্যান্ড্রয়েড অটো এবং অ্যান্ড্রয়েড অটোমোটিভ ওএস প্রদর্শন প্লেব্যাক কন্ট্রোলগুলি PlaybackStateCompat অবজেক্টে সক্ষম করা ক্রিয়াগুলির উপর ভিত্তি করে প্লেব্যাক নিয়ন্ত্রণগুলি প্রদর্শন করে।

ডিফল্টরূপে, আপনার অ্যাপ্লিকেশন অবশ্যই নিম্নলিখিত ক্রিয়াগুলি সমর্থন করবে:

আপনার অ্যাপ্লিকেশনটি যদি অ্যাপ্লিকেশনটির সামগ্রীর সাথে প্রাসঙ্গিক হয় তবে নিম্নলিখিত ক্রিয়াকলাপগুলিকে অতিরিক্তভাবে সমর্থন করতে পারে:

এছাড়াও, আপনার কাছে একটি প্লে সারি তৈরি করার বিকল্প রয়েছে যা ব্যবহারকারীর জন্য প্রদর্শিত হতে পারে তবে এটির প্রয়োজন হয় না। এটি করার জন্য, setQueue() এবং setQueueTitle() পদ্ধতিগুলি কল করুন, ACTION_SKIP_TO_QUEUE_ITEM অ্যাকশন সক্ষম করুন এবং কলব্যাক onSkipToQueueItem() সংজ্ঞায়িত করুন।

এছাড়াও, এখন প্লে আইকনটির জন্য সমর্থন যুক্ত করুন, যা বর্তমানে যা খেলছে তার একটি সূচক। এটি করতে, setActiveQueueItemId() পদ্ধতিতে কল করুন এবং সারিটিতে বর্তমানে প্লে আইটেমটির আইডি পাস করুন। যখনই কোনও সারি পরিবর্তন হয় তখন আপনাকে setActiveQueueItemId() আপডেট করতে হবে।

অ্যান্ড্রয়েড অটো এবং অ্যান্ড্রয়েড অটোমোটিভ ওএস ডিসপ্লে বোতামগুলির জন্য প্রতিটি সক্ষম ক্রিয়াকলাপের পাশাপাশি প্লেব্যাক সারি। বোতামগুলি ক্লিক করা হলে, সিস্টেমটি MediaSessionCompat.Callback থেকে তাদের সংশ্লিষ্ট কলব্যাকটি অনুরোধ করে।

অব্যবহৃত স্থান সংরক্ষণ করুন

ACTION_SKIP_TO_PREVIOUS এবং ACTION_SKIP_TO_NEXT ক্রিয়াকলাপের জন্য ইউআইতে অ্যান্ড্রয়েড অটো এবং অ্যান্ড্রয়েড অটোমোটিভ ওএস রিজার্ভ স্পেস। যদি আপনার অ্যাপ্লিকেশনটি এই ফাংশনগুলির মধ্যে একটি সমর্থন না করে তবে অ্যান্ড্রয়েড অটো এবং অ্যান্ড্রয়েড অটোমোটিভ ওএস আপনার তৈরি কোনও কাস্টম ক্রিয়া প্রদর্শন করতে স্থানটি ব্যবহার করুন।

আপনি যদি সেই স্পেসগুলিকে কাস্টম ক্রিয়াকলাপ দিয়ে পূরণ করতে না চান তবে আপনি সেগুলি সংরক্ষণ করতে পারেন যাতে অ্যান্ড্রয়েড অটো এবং অ্যান্ড্রয়েড অটোমোটিভ ওএস যখনই আপনার অ্যাপটি সম্পর্কিত ফাংশনটিকে সমর্থন না করে তখন জায়গাটি ফাঁকা ছেড়ে দেয়। এটি করার জন্য, একটি অতিরিক্ত বান্ডিল সহ setExtras() পদ্ধতিতে কল করুন যাতে সংরক্ষিত ফাংশনগুলির সাথে সামঞ্জস্যপূর্ণ ধ্রুবক থাকে। SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT ACTION_SKIP_TO_NEXT , এবং SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV সাথে মিল রয়েছে ACTION_SKIP_TO_PREVIOUS এই ধ্রুবকগুলিকে বান্ডলে কী হিসাবে ব্যবহার করুন এবং তাদের মানগুলির জন্য বুলিয়ান true ব্যবহার করুন।

প্রাথমিক প্লেব্যাকস্টেট সেট করুন

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

এটি সম্পাদন করার জন্য, আপনার মিডিয়া সেশনের প্রাথমিক PlaybackStateCompat STATE_STOPPED , STATE_PAUSED , STATE_NONE বা STATE_ERROR সেট করুন।

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

কাস্টম প্লেব্যাক ক্রিয়া যুক্ত করুন

আপনার মিডিয়া অ্যাপ সমর্থন করে এমন অতিরিক্ত ক্রিয়া প্রদর্শন করতে আপনি কাস্টম প্লেব্যাক ক্রিয়া যুক্ত করতে পারেন। যদি স্পেস অনুমতি দেয় (এবং সংরক্ষিত না হয়) , অ্যান্ড্রয়েড পরিবহন নিয়ন্ত্রণগুলিতে কাস্টম ক্রিয়া যুক্ত করে। অন্যথায়, কাস্টম ক্রিয়াগুলি ওভারফ্লো মেনুতে প্রদর্শিত হয়। কাস্টম অ্যাকশনগুলি ক্রমে প্রদর্শিত হয় সেগুলি PlaybackStateCompat যুক্ত করা হয়।

মানক ক্রিয়া থেকে পৃথক আচরণ সরবরাহ করতে কাস্টম ক্রিয়া ব্যবহার করুন। এগুলি স্ট্যান্ডার্ড ক্রিয়াগুলি প্রতিস্থাপন বা সদৃশ করতে ব্যবহার করবেন না।

আপনি PlaybackStateCompat.Builder ক্লাসে addCustomAction() পদ্ধতি ব্যবহার করে কাস্টম ক্রিয়া যুক্ত করতে পারেন।

নিম্নলিখিত কোড স্নিপেট দেখায় যে কীভাবে একটি কাস্টম "একটি রেডিও চ্যানেল শুরু করুন" ক্রিয়া যুক্ত করবেন:

কোটলিন

val customActionExtras = Bundle()
customActionExtras.putInt(
  androidx.media3.session.MediaConstants.EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT,
  androidx.media3.session.CommandButton.ICON_RADIO)

stateBuilder.addCustomAction(
    PlaybackStateCompat.CustomAction.Builder(
        CUSTOM_ACTION_START_RADIO_FROM_MEDIA,
        resources.getString(R.string.start_radio_from_media),
        startRadioFromMediaIcon // or R.drawable.media3_icon_radio
    ).run {
        setExtras(customActionExtras)
        build()
    }
)

জাভা

Bundle customActionExtras = new Bundle();
customActionExtras.putInt(
  androidx.media3.session.MediaConstants.EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT,
  androidx.media3.session.CommandButton.ICON_RADIO);

stateBuilder.addCustomAction(
    new PlaybackStateCompat.CustomAction.Builder(
        CUSTOM_ACTION_START_RADIO_FROM_MEDIA,
        resources.getString(R.string.start_radio_from_media),
        startRadioFromMediaIcon) // or R.drawable.media3_icon_radio
    .setExtras(customActionExtras)
    .build());

এই পদ্ধতির আরও বিশদ উদাহরণের জন্য, গিটহাবের ইউনিভার্সাল অ্যান্ড্রয়েড মিউজিক প্লেয়ার নমুনা অ্যাপ্লিকেশনটিতে setCustomAction() পদ্ধতিটি দেখুন।

আপনার কাস্টম অ্যাকশন তৈরি করার পরে, আপনার মিডিয়া সেশন onCustomAction() পদ্ধতিটি ওভাররাইড করে ক্রিয়াটির প্রতিক্রিয়া জানাতে পারে।

নিম্নলিখিত কোড স্নিপেট দেখায় যে আপনার অ্যাপ্লিকেশনটি কীভাবে একটি "রেডিও চ্যানেল শুরু করুন" ক্রিয়াতে প্রতিক্রিয়া জানাতে পারে:

কোটলিন

override fun onCustomAction(action: String, extras: Bundle?) {
    when(action) {
        CUSTOM_ACTION_START_RADIO_FROM_MEDIA -> {
            ...
        }
    }
}

জাভা

@Override
public void onCustomAction(@NonNull String action, Bundle extras) {
    if (CUSTOM_ACTION_START_RADIO_FROM_MEDIA.equals(action)) {
        ...
    }
}

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

কাস্টম ক্রিয়াকলাপের জন্য আইকন

আপনি তৈরি করেন এমন প্রতিটি কাস্টম ক্রিয়াটির জন্য একটি আইকন প্রয়োজন।

যদি সেই আইকনটির বিবরণটি CommandButton.ICON_ ধ্রুবকগুলির মধ্যে একটির সাথে মেলে, আপনার কাস্টম অ্যাকশনের অতিরিক্তগুলির EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT কী জন্য সেই পূর্ণসংখ্যার মান সেট করা উচিত। সমর্থিত সিস্টেমগুলিতে, এটি CustomAction.Builder পাস করা আইকন রিসোর্সটিকে ওভাররাইড করবে, সিস্টেমের উপাদানগুলিকে আপনার ক্রিয়া এবং অন্যান্য প্লেব্যাক ক্রিয়াগুলিকে একটি ধারাবাহিক শৈলীতে রেন্ডার করার অনুমতি দেয়।

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

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

অক্ষম ক্রিয়াকলাপের জন্য বিকল্প আইকন শৈলী সরবরাহ করুন

যখন বর্তমান প্রসঙ্গে একটি কাস্টম ক্রিয়া অনুপলব্ধ থাকে, তখন একটি বিকল্প আইকন দিয়ে কাস্টম অ্যাকশন আইকনটি অদলবদল করে যা দেখায় যে ক্রিয়াটি অক্ষম রয়েছে।

চিত্র 6। অফ স্টাইলের কাস্টম অ্যাকশন আইকনগুলির নমুনা।

অডিও ফর্ম্যাট নির্দেশ করুন

বর্তমানে মিডিয়া প্লে করা একটি বিশেষ অডিও ফর্ম্যাট ব্যবহার করে তা নির্দেশ করতে, আপনি এই বৈশিষ্ট্যটিকে সমর্থন করে এমন গাড়িগুলিতে রেন্ডার করা আইকনগুলি নির্দিষ্ট করতে পারেন। আপনি বর্তমানে বাজানো মিডিয়া আইটেমের অতিরিক্ত বান্ডিল ( MediaSession.setMetadata() ) এর অতিরিক্ত বান্ডলে KEY_CONTENT_FORMAT_TINTABLE_LARGE_ICON_URI এবং KEY_CONTENT_FORMAT_TINTABLE_SMALL_ICON_URI সেট করতে পারেন। বিভিন্ন লেআউটগুলিকে সামঞ্জস্য করার জন্য, এই উভয় অতিরিক্ত সেট সেট করার বিষয়টি নিশ্চিত করুন।

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

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

লিঙ্কগুলি যুক্ত করতে, KEY_SUBTITLE_LINK_MEDIA_ID মেটাডেটা (সাবটাইটেল থেকে লিঙ্ক করতে) বা KEY_DESCRIPTION_LINK_MEDIA_ID (বিবরণ থেকে লিঙ্ক করতে) কনফিগার করুন। বিশদগুলির জন্য, সেই মেটাডেটা ক্ষেত্রগুলির জন্য রেফারেন্স ডকুমেন্টেশন দেখুন।

ভয়েস ক্রিয়া সমর্থন

আপনার মিডিয়া অ্যাপকে অবশ্যই ড্রাইভারদের একটি নিরাপদ এবং সুবিধাজনক অভিজ্ঞতা সরবরাহ করতে সহায়তা করতে ভয়েস ক্রিয়াকলাপগুলিকে সমর্থন করতে হবে যা বিভ্রান্তি হ্রাস করে। উদাহরণস্বরূপ, যদি আপনার অ্যাপ্লিকেশনটি একটি মিডিয়া আইটেম খেলছে তবে ব্যবহারকারী আপনার অ্যাপ্লিকেশনটিকে গাড়ির ডিসপ্লে না দেখে বা স্পর্শ না করে আলাদা গান বাজানোর জন্য " খেলুন [গানের শিরোনাম] " বলতে পারেন users ব্যবহারকারীরা উপযুক্ত বোতামগুলিতে ক্লিক করে প্রশ্ন শুরু করতে পারেন তাদের স্টিয়ারিং হুইলে বা হটওয়ার্ডস " ওকে গুগল " কথা বলা।

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

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

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

যদি কোনও অনুসন্ধান দ্রুত প্রক্রিয়া করা যায় না, onPlayFromSearch() এ ব্লক করবেন না। পরিবর্তে, প্লেব্যাক স্টেটটি STATE_CONNECTING সেট করুন এবং একটি অ্যাসিঙ্ক থ্রেডে অনুসন্ধান সম্পাদন করুন।

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

" প্লে " ক্যোয়ারী ছাড়াও, অ্যান্ড্রয়েড অটো এবং অ্যান্ড্রয়েড অটোমোটিভ ওএস " বিরতি সংগীত " এবং " নেক্সট গান " এর মতো প্লেব্যাক নিয়ন্ত্রণ করতে ভয়েস ক্যোয়ারীগুলি স্বীকৃতি দেয় এবং এই কমান্ডগুলি onPause() এবং onSkipToNext() মতো উপযুক্ত মিডিয়া সেশন কলব্যাকগুলিতে মেলে।

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

ডিস্ট্রাকশন সেফগার্ডগুলি প্রয়োগ করুন

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

গাড়িতে অ্যালার্ম দমন করুন

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

এই প্রয়োজনীয়তাটি পূরণ করতে, আপনার অ্যাপ্লিকেশন কোনও অডিও খেলার আগে সংকেত হিসাবে CarConnection ব্যবহার করতে পারে। আপনার অ্যাপ্লিকেশনটি গাড়ী সংযোগের ধরণের জন্য LiveData পর্যবেক্ষণ করে এবং এটি CONNECTION_TYPE_PROJECTION সমান কিনা তা পরীক্ষা করে ফোনটি কোনও গাড়ির স্ক্রিনে প্রজেক্ট করছে কিনা তা যাচাই করতে পারে।

যদি ব্যবহারকারীর ফোনটি প্রজেক্ট করা হয়, তবে মিডিয়া অ্যাপ্লিকেশনগুলি যা অ্যালার্ম সমর্থন করে তাদের অবশ্যই নিম্নলিখিত একটি কাজ করতে হবে:

  • অ্যালার্ম অক্ষম করুন।
  • STREAM_ALARM উপরে অ্যালার্মটি খেলুন এবং অ্যালার্মটি অক্ষম করতে ফোনের স্ক্রিনে একটি ইউআই সরবরাহ করুন।

মিডিয়া বিজ্ঞাপনগুলি পরিচালনা করুন

ডিফল্টরূপে, অ্যান্ড্রয়েড অটো যখন একটি অডিও প্লেব্যাক সেশনের সময় মিডিয়া মেটাডেটা পরিবর্তিত হয় তখন একটি বিজ্ঞপ্তি প্রদর্শন করে। যখন কোনও মিডিয়া অ্যাপ্লিকেশন সংগীত বাজানো থেকে কোনও বিজ্ঞাপন চালাতে স্যুইচ করে, তখন এটি ব্যবহারকারীর কাছে একটি বিজ্ঞপ্তি প্রদর্শন করতে বিভ্রান্ত হয়। অ্যান্ড্রয়েড অটোকে এই ক্ষেত্রে একটি বিজ্ঞপ্তি প্রদর্শন করা থেকে বিরত রাখতে, আপনাকে অবশ্যই মিডিয়া মেটাডেটা METADATA_KEY_IS_ADVERTISEMENT METADATA_VALUE_ATTRIBUTE_PRESENT সেট করতে হবে, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে:

কোটলিন

import androidx.media.utils.MediaConstants

override fun onPlayFromMediaId(mediaId: String, extras: Bundle?) {
    MediaMetadataCompat.Builder().apply {
        if (isAd(mediaId)) {
            putLong(
                MediaConstants.METADATA_KEY_IS_ADVERTISEMENT,
                MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
        }
        // ...add any other properties you normally would.
        mediaSession.setMetadata(build())
    }
}

জাভা

import androidx.media.utils.MediaConstants;

@Override
public void onPlayFromMediaId(String mediaId, Bundle extras) {
    MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
    if (isAd(mediaId)) {
        builder.putLong(
            MediaConstants.METADATA_KEY_IS_ADVERTISEMENT,
            MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT);
    }
    // ...add any other properties you normally would.
    mediaSession.setMetadata(builder.build());
}

সাধারণ ত্রুটিগুলি পরিচালনা করুন

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

উদাহরণস্বরূপ, যদি ব্যবহারকারীর বর্তমান অঞ্চলে সামগ্রী উপলভ্য না হয় তবে ত্রুটি বার্তাটি নির্ধারণের সময় আপনি ERROR_CODE_NOT_AVAILABLE_IN_REGION ত্রুটি কোডটি ব্যবহার করতে পারেন।

কোটলিন

mediaSession.setPlaybackState(
    PlaybackStateCompat.Builder()
        .setState(PlaybackStateCompat.STATE_ERROR)
        .setErrorMessage(PlaybackStateCompat.ERROR_CODE_NOT_AVAILABLE_IN_REGION, getString(R.string.error_unsupported_region))
        // ...and any other setters.
        .build())

জাভা

mediaSession.setPlaybackState(
    new PlaybackStateCompat.Builder()
        .setState(PlaybackStateCompat.STATE_ERROR)
        .setErrorMessage(PlaybackStateCompat.ERROR_CODE_NOT_AVAILABLE_IN_REGION, getString(R.string.error_unsupported_region))
        // ...and any other setters.
        .build());

ত্রুটি রাষ্ট্রগুলি সম্পর্কে আরও তথ্যের জন্য, একটি মিডিয়া সেশন ব্যবহার করে দেখুন: রাজ্য এবং ত্রুটি

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

অন্যান্য সম্পদ