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

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 এ পাস করা মিডিয়া আইডির সমান।
  • PlaybackStateCompat PLAYBACK_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>")
    
  • অ্যাকশন আইকন URI
    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI,
                    "<ACTION_ICON_URI>")
    

Parceable ArrayList এ কাস্টম ব্রাউজ অ্যাকশন যোগ করুন

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

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. ডাউনলোড করুন: এটি কর্মের প্রাথমিক অবস্থা। ব্যবহারকারী যখন এই ক্রিয়াটি নির্বাচন করেন, আপনি এটিকে "ডাউনলোডিং" দিয়ে অদলবদল করতে পারেন এবং UI আপডেট করতে sendProgressUpdate কল করতে পারেন৷
  2. ডাউনলোড হচ্ছে: এই অবস্থা নির্দেশ করে যে ডাউনলোড চলছে। আপনি ব্যবহারকারীকে একটি অগ্রগতি বার বা অন্য সূচক দেখাতে এই অবস্থাটি ব্যবহার করতে পারেন।
  3. ডাউনলোড করা হয়েছে: এই অবস্থা নির্দেশ করে যে ডাউনলোড সম্পূর্ণ হয়েছে। ডাউনলোড শেষ হলে, আপনি "ডাউনলোড" এর সাথে "ডাউনলোড করা" অদলবদল করতে পারেন এবং EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM কী দিয়ে sendResult কল করতে পারেন যাতে আইটেমটি রিফ্রেশ করা উচিত। উপরন্তু, আপনি ব্যবহারকারীকে একটি সফল বার্তা প্রদর্শন করতে EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE কী ব্যবহার করতে পারেন৷

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

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

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

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

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

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

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

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

Android Auto এবং Android Automotive OS আপনার পরিষেবার 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 ক্লাসের একটি বাস্তবায়ন প্রদান করে এই কলব্যাক অবজেক্ট তৈরি করেন। পরবর্তী বিভাগে এই বস্তুটি কিভাবে বাস্তবায়ন করা যায় তা নিয়ে আলোচনা করা হয়েছে।

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

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

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

নিম্নলিখিত সমস্ত কলব্যাক পদ্ধতিগুলি প্রয়োগ করুন যা আপনার অ্যাপের অফার করে এমন বিষয়বস্তুর ধরণকে বোঝায়:

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

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

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

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

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

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

স্ট্যান্ডার্ড প্লেব্যাক অ্যাকশন সেট করুন

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

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

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

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

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

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

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

ACTION_SKIP_TO_PREVIOUS এবং ACTION_SKIP_TO_NEXT অ্যাকশনের জন্য UI-তে Android Auto এবং Android Automotive OS রিজার্ভ স্পেস। যদি আপনার অ্যাপ এই ফাংশনগুলির একটিকে সমর্থন না করে, তাহলে Android Auto এবং Android Automotive OS আপনার তৈরি করা যেকোনো কাস্টম অ্যাকশন প্রদর্শন করতে স্থান ব্যবহার করে।

আপনি যদি কাস্টম অ্যাকশনগুলি দিয়ে সেই স্থানগুলি পূরণ করতে না চান, আপনি সেগুলি সংরক্ষণ করতে পারেন যাতে আপনার অ্যাপ সংশ্লিষ্ট ফাংশন সমর্থন না করলে Android Auto এবং Android Automotive OS স্থানটি ফাঁকা রাখে৷ এটি করার জন্য, একটি অতিরিক্ত বান্ডেল সহ 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 ব্যবহার করুন।

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

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

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

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

কাস্টম প্লেব্যাক অ্যাকশন যোগ করুন

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

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

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

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

কোটলিন

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

জাভা

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

এই পদ্ধতির আরও বিস্তারিত উদাহরণের জন্য, GitHub-এ ইউনিভার্সাল অ্যান্ড্রয়েড মিউজিক প্লেয়ার নমুনা অ্যাপে 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)) {
        ...
    }
}

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

কাস্টম কর্মের জন্য আইকন

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

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

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

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

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

অডিও বিন্যাস নির্দেশ করুন

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

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

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

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

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

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

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

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

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

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

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

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

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

বিক্ষিপ্ত সুরক্ষা ব্যবস্থা প্রয়োগ করুন

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

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

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

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

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

  • অ্যালার্ম নিষ্ক্রিয় করুন।
  • STREAM_ALARM এ অ্যালার্ম বাজান এবং অ্যালার্ম নিষ্ক্রিয় করতে ফোনের স্ক্রিনে একটি UI প্রদান করুন৷

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

ডিফল্টরূপে, অডিও প্লেব্যাক সেশনের সময় মিডিয়া মেটাডেটা পরিবর্তন হলে Android Auto একটি বিজ্ঞপ্তি প্রদর্শন করে। যখন একটি মিডিয়া অ্যাপ সঙ্গীত বাজানো থেকে একটি বিজ্ঞাপন চালানোর জন্য স্যুইচ করে, তখন ব্যবহারকারীর কাছে একটি বিজ্ঞপ্তি প্রদর্শন করা বিভ্রান্তিকর। এই ক্ষেত্রে Android Auto-কে একটি বিজ্ঞপ্তি প্রদর্শন করা থেকে আটকাতে, আপনাকে অবশ্যই মিডিয়া মেটাডেটা কী 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());

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

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

অন্যান্য উৎস