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

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

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

আপনার পরিষেবার onGetRoot পদ্ধতি আপনার বিষয়বস্তু অনুক্রমের রুট নোড সম্পর্কে তথ্য প্রদান করে। Android Auto এবং AAOS এই রুট নোড ব্যবহার করে 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 পদ্ধতিতে একটি কল করা হয়, কলিং প্যাকেজটি আপনার পরিষেবাতে সনাক্তকারী তথ্য পাস করে৷ আপনার পরিষেবা এই তথ্যটি ব্যবহার করে সিদ্ধান্ত নিতে পারে যে প্যাকেজটি আপনার সামগ্রী অ্যাক্সেস করতে পারে কিনা৷

উদাহরণস্বরূপ, আপনি অনুমোদিত প্যাকেজের তালিকায় আপনার অ্যাপের সামগ্রীতে অ্যাক্সেস সীমাবদ্ধ করতে পারেন:

  • আপনার অনুমোদিত তালিকার সাথে clientPackageName তুলনা করুন।
  • প্যাকেজের জন্য APK স্বাক্ষর করতে ব্যবহৃত শংসাপত্রটি যাচাই করুন।

যদি প্যাকেজটি যাচাই করা না যায়, তাহলে আপনার সামগ্রীতে অ্যাক্সেস অস্বীকার করতে null ফেরত দিন।

আপনার সামগ্রীতে অ্যাক্সেস সহ Android Auto এবং AAOS-এর মতো সিস্টেম অ্যাপগুলি প্রদান করতে, যখন এই সিস্টেম অ্যাপগুলি onGetRoot পদ্ধতিতে কল করে তখন আপনার পরিষেবাকে একটি নন-নাল BrowserRoot ফেরত দিতে হবে।

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

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

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 AAOS রয়েছে।

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

আপনার রুট নোড অবজেক্ট পাওয়ার পর, অ্যান্ড্রয়েড অটো এবং AAOS এর উত্তরসূরি পেতে রুট নোড অবজেক্টে 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&lt;MediaBrowserCompat.MediaItem> = mutableListOf()

    // Check if 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 descendants of that menu in the mediaItems list.
    }
    result.sendResult(mediaItems)
}

জাভা

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

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

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

    // Check if 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 descendants of that menu in the mediaItems list.
    }
    result.sendResult(mediaItems);
}

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

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

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

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

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

এই ইঙ্গিতগুলি প্রয়োগ করে, সিস্টেম ন্যাভিগেশনাল ট্যাব হিসাবে রুট বিষয়বস্তু প্রদর্শন করে। এই ইঙ্গিতগুলি প্রয়োগ না করে, কিছু রুট বিষয়বস্তু বাদ দেওয়া বা কম আবিষ্কারযোগ্য করা হতে পারে। এই ইঙ্গিতগুলি প্রেরণ করা হয়:

কোটলিন

import androidx.media.utils.MediaConstants

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 এবং AAOS-এর বাইরে MediaBrowser ইন্টিগ্রেশনের মধ্যে পরিবর্তিত হয়।

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

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

  • প্রতিটি ট্যাব আইটেমের জন্য একরঙা (পছন্দ করে সাদা) আইকন

  • প্রতিটি ট্যাব আইটেমের জন্য সংক্ষিপ্ত এবং অর্থপূর্ণ লেবেল (সংক্ষিপ্ত লেবেলগুলি লেবেলগুলি কাটার সম্ভাবনা কমায়)