একটি টিভি ইনপুট সার্ভিস একটি মিডিয়া স্ট্রিম সোর্সকে প্রতিনিধিত্ব করে এবং আপনাকে আপনার মিডিয়া কন্টেন্টকে চ্যানেল ও প্রোগ্রাম হিসেবে একটি লিনিয়ার, ব্রডকাস্ট টিভির ধরনে উপস্থাপন করতে দেয়। একটি টিভি ইনপুট সার্ভিসের মাধ্যমে, আপনি প্যারেন্টাল কন্ট্রোল, প্রোগ্রাম গাইডের তথ্য এবং কন্টেন্ট রেটিং প্রদান করতে পারেন। টিভি ইনপুট সার্ভিসটি অ্যান্ড্রয়েড সিস্টেম টিভি অ্যাপের সাথে কাজ করে। এই অ্যাপটিই চূড়ান্তভাবে টিভিতে চ্যানেলের কন্টেন্ট নিয়ন্ত্রণ ও উপস্থাপন করে। সিস্টেম টিভি অ্যাপটি বিশেষভাবে ডিভাইসটির জন্য তৈরি করা হয়েছে এবং থার্ড-পার্টি অ্যাপ দ্বারা এটি অপরিবর্তনীয়। টিভি ইনপুট ফ্রেমওয়ার্ক (TIF) আর্কিটেকচার এবং এর উপাদানগুলো সম্পর্কে আরও তথ্যের জন্য, টিভি ইনপুট ফ্রেমওয়ার্ক দেখুন।
TIF কম্প্যানিয়ন লাইব্রেরি ব্যবহার করে একটি টিভি ইনপুট পরিষেবা তৈরি করুন
TIF কম্প্যানিয়ন লাইব্রেরি হলো একটি ফ্রেমওয়ার্ক যা সাধারণ টিভি ইনপুট পরিষেবা বৈশিষ্ট্যগুলির সম্প্রসারণযোগ্য বাস্তবায়ন প্রদান করে। এটি শুধুমাত্র অ্যান্ড্রয়েড ৫.০ (এপিআই লেভেল ২১) থেকে অ্যান্ড্রয়েড ৭.১ (এপিআই লেভেল ২৫) পর্যন্ত সংস্করণের জন্য চ্যানেল তৈরি করতে OEM-দের ব্যবহারের উদ্দেশ্যে তৈরি।
আপনার প্রজেক্ট আপডেট করুন
OEM-দের পুরোনো সংস্করণ ব্যবহারের জন্য TIF Companion Library-টি androidtv-sample-inputs রিপোজিটরিতে পাওয়া যায়। কোনো অ্যাপে লাইব্রেরিটি কীভাবে অন্তর্ভুক্ত করতে হয়, তার একটি উদাহরণের জন্য ওই রিপোজিটরিটি দেখুন।
ম্যানিফেস্টে আপনার টিভি ইনপুট পরিষেবা ঘোষণা করুন।
আপনার অ্যাপকে অবশ্যই একটি TvInputService সামঞ্জস্যপূর্ণ সার্ভিস প্রদান করতে হবে, যা সিস্টেম আপনার অ্যাপ অ্যাক্সেস করার জন্য ব্যবহার করে। TIF Companion Library-তে BaseTvInputService ক্লাসটি রয়েছে, যা TvInputService এর একটি ডিফল্ট ইমপ্লিমেন্টেশন প্রদান করে এবং আপনি তা কাস্টমাইজ করতে পারেন। BaseTvInputService এর একটি সাবক্লাস তৈরি করুন এবং আপনার ম্যানিফেস্টে সাবক্লাসটিকে একটি সার্ভিস হিসেবে ডিক্লেয়ার করুন।
সার্ভিসটিকে সিস্টেমের সাথে টিভি ইনপুট সংযোগ করার অনুমতি দিতে, ম্যানিফেস্ট ডিক্লারেশনের মধ্যে BIND_TV_INPUT পারমিশনটি উল্লেখ করুন। একটি সিস্টেম সার্ভিস বাইন্ডিং সম্পাদন করে এবং সেটির BIND_TV_INPUT পারমিশন থাকে। সিস্টেম টিভি অ্যাপটি TvInputManager ইন্টারফেসের মাধ্যমে টিভি ইনপুট সার্ভিসগুলোতে অনুরোধ পাঠায়।
আপনার সার্ভিস ডিক্লারেশনে, একটি ইন্টেন্ট ফিল্টার অন্তর্ভুক্ত করুন যা ইন্টেন্টটির মাধ্যমে সম্পাদন করার জন্য অ্যাকশন হিসেবে TvInputService নির্দিষ্ট করে। এছাড়াও, সার্ভিস মেটাডেটাকে একটি পৃথক XML রিসোর্স হিসেবে ডিক্লেয়ার করুন। সার্ভিস ডিক্লারেশন, ইন্টেন্ট ফিল্টার এবং সার্ভিস মেটাডেটা ডিক্লারেশন নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
<service android:name=".rich.RichTvInputService" android:label="@string/rich_input_label" android:permission="android.permission.BIND_TV_INPUT"> <!-- Required filter used by the system to launch our account service. --> <intent-filter> <action android:name="android.media.tv.TvInputService" /> </intent-filter> <!-- An XML file which describes this input. This provides pointers to the RichTvInputSetupActivity to the system/TV app. --> <meta-data android:name="android.media.tv.input" android:resource="@xml/richtvinputservice" /> </service>
একটি পৃথক XML ফাইলে সার্ভিস মেটাডেটা সংজ্ঞায়িত করুন। সার্ভিস মেটাডেটা XML ফাইলটিতে অবশ্যই একটি সেটআপ ইন্টারফেস অন্তর্ভুক্ত থাকতে হবে, যা টিভি ইনপুটের প্রাথমিক কনফিগারেশন এবং চ্যানেল স্ক্যান বর্ণনা করে। মেটাডেটা ফাইলটিতে একটি ফ্ল্যাগও থাকা উচিত, যা নির্দেশ করবে ব্যবহারকারীরা কন্টেন্ট রেকর্ড করতে পারবে কি না। আপনার অ্যাপে কীভাবে কন্টেন্ট রেকর্ডিং সমর্থন করবেন সে সম্পর্কে আরও তথ্যের জন্য, ‘কন্টেন্ট রেকর্ডিং সমর্থন’ দেখুন।
সার্ভিস মেটাডেটা ফাইলটি আপনার অ্যাপের XML রিসোর্স ডিরেক্টরিতে অবস্থিত এবং এর নাম অবশ্যই ম্যানিফেস্টে ঘোষিত রিসোর্সের নামের সাথে মিলতে হবে। পূর্ববর্তী উদাহরণের ম্যানিফেস্ট এন্ট্রিগুলো ব্যবহার করে, আপনাকে res/xml/richtvinputservice.xml ঠিকানায় নিম্নলিখিত বিষয়বস্তু সহ XML ফাইলটি তৈরি করতে হবে:
<?xml version="1.0" encoding="utf-8"?> <tv-input xmlns:android="http://schemas.android.com/apk/res/android" android:canRecord="true" android:setupActivity="com.example.android.sampletvinput.rich.RichTvInputSetupActivity" />
চ্যানেলগুলি সংজ্ঞায়িত করুন এবং আপনার সেটআপ কার্যকলাপ তৈরি করুন
আপনার টিভি ইনপুট সার্ভিসে অবশ্যই অন্তত একটি চ্যানেল নির্ধারণ করতে হবে, যা ব্যবহারকারীরা সিস্টেম টিভি অ্যাপের মাধ্যমে অ্যাক্সেস করতে পারে। আপনার চ্যানেলগুলো সিস্টেম ডেটাবেসে রেজিস্টার করা উচিত এবং একটি সেটআপ অ্যাক্টিভিটি প্রদান করা উচিত, যা সিস্টেম আপনার অ্যাপের জন্য কোনো চ্যানেল খুঁজে না পেলে চালু করবে।
প্রথমে, আপনার অ্যাপকে সিস্টেমের ইলেকট্রনিক প্রোগ্রামিং গাইড (EPG) থেকে ডেটা পড়া এবং তাতে লেখার অনুমতি দিন, যার ডেটাতে ব্যবহারকারীর জন্য উপলব্ধ চ্যানেল ও প্রোগ্রামগুলো অন্তর্ভুক্ত থাকে। আপনার অ্যাপকে এই কাজগুলো করতে সক্ষম করতে এবং ডিভাইস রিস্টার্টের পর EPG-এর সাথে সিঙ্ক করার জন্য, আপনার অ্যাপ ম্যানিফেস্টে নিম্নলিখিত উপাদানগুলো যোগ করুন:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/>
আপনার অ্যাপটি যেন অ্যান্ড্রয়েড টিভিতে কন্টেন্ট চ্যানেল সরবরাহকারী একটি অ্যাপ হিসেবে গুগল প্লে স্টোরে প্রদর্শিত হয়, তা নিশ্চিত করতে নিম্নলিখিত উপাদানটি যোগ করুন:
<uses-feature android:name="android.software.live_tv" android:required="true" />
এরপরে, EpgSyncJobService ক্লাসকে এক্সটেন্ড করে এমন একটি ক্লাস তৈরি করুন। এই অ্যাবস্ট্রাক্ট ক্লাসটি আপনাকে এমন একটি জব সার্ভিস তৈরি করতে দেয়, যা সিস্টেম ডাটাবেসে চ্যানেল তৈরি ও আপডেট করে।
আপনার সাবক্লাসে, getChannels ফাংশনে আপনার চ্যানেলের সম্পূর্ণ তালিকা তৈরি করুন এবং তা রিটার্ন করুন। যদি আপনার চ্যানেলগুলো কোনো XMLTV ফাইল থেকে আসে, তাহলে XmlTvParser ক্লাসটি ব্যবহার করুন। অন্যথায়, Channel.Builder ক্লাস ব্যবহার করে প্রোগ্রাম্যাটিকভাবে চ্যানেল তৈরি করুন।
প্রতিটি চ্যানেলের জন্য, একটি নির্দিষ্ট সময়সীমার মধ্যে দেখা যাবে এমন প্রোগ্রামগুলির তালিকা প্রয়োজন হলে সিস্টেম getProgramsForChannel কল করে। এটি চ্যানেলটির জন্য Program অবজেক্টের একটি তালিকা ফেরত দেয়। একটি XMLTV ফাইল থেকে প্রোগ্রাম পেতে XmlTvParser ক্লাসটি ব্যবহার করুন, অথবা Program.Builder ক্লাস ব্যবহার করে প্রোগ্রাম্যাটিকভাবে সেগুলি তৈরি করুন।
প্রতিটি Program অবজেক্টের জন্য, প্রোগ্রামের ভিডিও টাইপের মতো তথ্য সেট করতে একটি InternalProviderData অবজেক্ট ব্যবহার করুন। যদি আপনার কাছে সীমিত সংখ্যক প্রোগ্রাম থাকে যা আপনি চ্যানেলে একটি লুপে পুনরাবৃত্তি করতে চান, তাহলে আপনার প্রোগ্রাম সম্পর্কে তথ্য সেট করার সময় InternalProviderData.setRepeatable মেথডটির মান true ব্যবহার করুন।
জব সার্ভিসটি ইমপ্লিমেন্ট করার পর, এটিকে আপনার অ্যাপ ম্যানিফেস্টে যোগ করুন:
<service android:name=".sync.SampleJobService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" />
সবশেষে, একটি সেটআপ অ্যাক্টিভিটি তৈরি করুন। আপনার সেটআপ অ্যাক্টিভিটিতে চ্যানেল এবং প্রোগ্রামের ডেটা সিঙ্ক করার একটি উপায় থাকা উচিত। এটি করার একটি উপায় হলো, ব্যবহারকারী অ্যাক্টিভিটির UI ব্যবহার করে কাজটি করবে। এছাড়াও, অ্যাক্টিভিটি শুরু হওয়ার সময় অ্যাপটি স্বয়ংক্রিয়ভাবে এটি করে দিতে পারে। যখন সেটআপ অ্যাক্টিভিটির চ্যানেল এবং প্রোগ্রামের তথ্য সিঙ্ক করার প্রয়োজন হবে, তখন অ্যাপটি জব সার্ভিসটি চালু করবে:
কোটলিন
val inputId = getActivity().intent.getStringExtra(TvInputInfo.EXTRA_INPUT_ID) EpgSyncJobService.cancelAllSyncRequests(getActivity()) EpgSyncJobService.requestImmediateSync( getActivity(), inputId, ComponentName(getActivity(), SampleJobService::class.java) )
জাভা
String inputId = getActivity().getIntent().getStringExtra(TvInputInfo.EXTRA_INPUT_ID); EpgSyncJobService.cancelAllSyncRequests(getActivity()); EpgSyncJobService.requestImmediateSync(getActivity(), inputId, new ComponentName(getActivity(), SampleJobService.class));
জব সার্ভিস সিঙ্ক করার জন্য requestImmediateSync মেথডটি ব্যবহার করুন। সিঙ্ক শেষ হওয়া পর্যন্ত ব্যবহারকারীকে অপেক্ষা করতে হয়, তাই আপনার রিকোয়েস্ট পিরিয়ড তুলনামূলকভাবে সংক্ষিপ্ত রাখা উচিত।
ব্যাকগ্রাউন্ডে জব সার্ভিসকে দিয়ে পর্যায়ক্রমে চ্যানেল ও প্রোগ্রাম ডেটা সিঙ্ক করানোর জন্য setUpPeriodicSync মেথডটি ব্যবহার করুন:
কোটলিন
EpgSyncJobService.setUpPeriodicSync( context, inputId, ComponentName(context, SampleJobService::class.java) )
জাভা
EpgSyncJobService.setUpPeriodicSync(context, inputId, new ComponentName(context, SampleJobService.class));
TIF কম্প্যানিয়ন লাইব্রেরি ` requestImmediateSync নামে একটি অতিরিক্ত ওভারলোডেড মেথড প্রদান করে, যা আপনাকে মিলিসেকেন্ডে চ্যানেল ডেটা সিঙ্ক করার সময়কাল নির্দিষ্ট করতে দেয়। ডিফল্ট মেথডটি এক ঘণ্টার চ্যানেল ডেটা সিঙ্ক করে।
TIF কম্প্যানিয়ন লাইব্রেরিটি setUpPeriodicSync নামে একটি অতিরিক্ত ওভারলোডেড মেথডও প্রদান করে, যা আপনাকে চ্যানেল ডেটা সিঙ্ক করার সময়কাল এবং কত ঘন ঘন এই পর্যায়ক্রমিক সিঙ্কটি হওয়া উচিত তা নির্দিষ্ট করতে দেয়। ডিফল্ট মেথডটি প্রতি ১২ ঘণ্টায় ৪৮ ঘণ্টার চ্যানেল ডেটা সিঙ্ক করে।
চ্যানেল ডেটা এবং EPG সম্পর্কে আরও বিস্তারিত জানতে, “চ্যানেল ডেটা নিয়ে কাজ করুন” দেখুন।
টিউনিং অনুরোধ এবং মিডিয়া প্লেব্যাক পরিচালনা করুন
যখন কোনো ব্যবহারকারী একটি নির্দিষ্ট চ্যানেল নির্বাচন করেন, তখন সিস্টেম টিভি অ্যাপটি আপনার অ্যাপ দ্বারা তৈরি একটি Session ব্যবহার করে অনুরোধকৃত চ্যানেলটিতে টিউন করে এবং কন্টেন্ট প্লে করে। টিআইএফ কম্প্যানিয়ন লাইব্রেরি এমন বেশ কিছু ক্লাস সরবরাহ করে, যা আপনি সিস্টেম থেকে আসা চ্যানেল এবং সেশন কলগুলো পরিচালনা করার জন্য এক্সটেন্ড করতে পারেন।
আপনার BaseTvInputService সাবক্লাসটি সেশন তৈরি করে যা টিউনিং অনুরোধগুলি পরিচালনা করে। onCreateSession মেথডটি ওভাররাইড করুন, BaseTvInputService.Session ক্লাস থেকে এক্সটেন্ড করা একটি সেশন তৈরি করুন, এবং আপনার নতুন সেশনটি দিয়ে super.sessionCreated কল করুন। নিম্নলিখিত উদাহরণে, onCreateSession একটি RichTvInputSessionImpl অবজেক্ট রিটার্ন করে যা BaseTvInputService.Session থেকে এক্সটেন্ড করে:
কোটলিন
override fun onCreateSession(inputId: String): Session = RichTvInputSessionImpl(this, inputId).apply { setOverlayViewEnabled(true) }
জাভা
@Override public final Session onCreateSession(String inputId) { RichTvInputSessionImpl session = new RichTvInputSessionImpl(this, inputId); session.setOverlayViewEnabled(true); return session; }
যখন ব্যবহারকারী সিস্টেম টিভি অ্যাপ ব্যবহার করে আপনার কোনো একটি চ্যানেল দেখা শুরু করেন, তখন সিস্টেম আপনার সেশনের onPlayChannel মেথডটি কল করে। প্রোগ্রামটি প্লে হওয়া শুরু করার আগে যদি আপনার কোনো বিশেষ চ্যানেল ইনিশিয়ালাইজেশন করার প্রয়োজন হয়, তবে এই মেথডটি ওভাররাইড করুন।
এরপর সিস্টেমটি বর্তমানে নির্ধারিত প্রোগ্রামটি সংগ্রহ করে এবং প্রোগ্রামের তথ্য ও মিলিসেকেন্ডে শুরুর সময় উল্লেখ করে আপনার সেশনের onPlayProgram মেথডটিকে কল করে। প্রোগ্রামটি চালানো শুরু করতে TvPlayer ইন্টারফেসটি ব্যবহার করুন।
নির্দিষ্ট প্লেব্যাক ইভেন্টগুলো পরিচালনা করার জন্য আপনার মিডিয়া প্লেয়ার কোডে TvPlayer ইমপ্লিমেন্ট করা উচিত। TvPlayer ক্লাসটি আপনার BaseTvInputService ইমপ্লিমেন্টেশনে কোনো জটিলতা না বাড়িয়েই টাইম-শিফটিং কন্ট্রোলের মতো ফিচারগুলো পরিচালনা করে।
আপনার সেশনের getTvPlayer মেথডে, TvPlayer ইমপ্লিমেন্ট করে এমন আপনার মিডিয়া প্লেয়ারটি রিটার্ন করুন। TV Input Service স্যাম্পল অ্যাপটি ExoPlayer ব্যবহার করে এমন একটি মিডিয়া প্লেয়ার ইমপ্লিমেন্ট করে।
টিভি ইনপুট ফ্রেমওয়ার্ক ব্যবহার করে একটি টিভি ইনপুট সার্ভিস তৈরি করুন।
যদি আপনার টিভি ইনপুট পরিষেবা TIF Companion Library ব্যবহার করতে না পারে, তাহলে আপনাকে নিম্নলিখিত উপাদানগুলি বাস্তবায়ন করতে হবে:
-
TvInputServiceটিভি ইনপুটের জন্য দীর্ঘস্থায়ী এবং ব্যাকগ্রাউন্ডে উপলব্ধতা প্রদান করে। -
TvInputService.Sessionটিভির ইনপুট অবস্থা বজায় রাখে এবং হোস্টিং অ্যাপের সাথে যোগাযোগ করে। -
TvContractটিভি ইনপুটে উপলব্ধ চ্যানেল এবং প্রোগ্রামগুলির বর্ণনা দেয়। -
TvContract.Channelsএকটি টিভি চ্যানেল সম্পর্কিত তথ্য উপস্থাপন করে। -
TvContract.Programsএকটি টিভি প্রোগ্রামের শিরোনাম এবং শুরুর সময়ের মতো তথ্য দিয়ে প্রোগ্রামটির বর্ণনা দেয়। -
TvTrackInfoএকটি অডিও, ভিডিও, বা সাবটাইটেল ট্র্যাককে বোঝায়। -
TvContentRatingএকটি কন্টেন্ট রেটিং বর্ণনা করে এবং নিজস্ব কন্টেন্ট রেটিং স্কিম তৈরির সুযোগ দেয়। -
TvInputManagerসিস্টেম টিভি অ্যাপের জন্য একটি এপিআই প্রদান করে এবং টিভি ইনপুট ও অ্যাপগুলোর সাথে মিথস্ক্রিয়া পরিচালনা করে।
আপনাকে নিম্নলিখিত কাজগুলোও করতে হবে:
- ম্যানিফেস্টে আপনার টিভি ইনপুট পরিষেবাটি ঘোষণা করুন, যেমনটি "ম্যানিফেস্টে আপনার টিভি ইনপুট পরিষেবা ঘোষণা করুন" অংশে বর্ণনা করা হয়েছে।
- সার্ভিস মেটাডেটা ফাইলটি তৈরি করুন।
- আপনার চ্যানেল ও অনুষ্ঠানের তথ্য তৈরি এবং নিবন্ধন করুন।
- আপনার সেটআপ কার্যকলাপ তৈরি করুন।
আপনার টিভি ইনপুট পরিষেবা সংজ্ঞায়িত করুন
আপনার সার্ভিসের জন্য, আপনি TvInputService ক্লাসটি এক্সটেন্ড করবেন। একটি TvInputService ইমপ্লিমেন্টেশন হলো একটি বাউন্ড সার্ভিস , যেখানে সিস্টেম সার্ভিসটি হলো ক্লায়েন্ট যা এর সাথে বাইন্ড করে। আপনার যে সার্ভিস লাইফসাইকেল মেথডগুলো ইমপ্লিমেন্ট করতে হবে, তা চিত্র ১-এ দেখানো হয়েছে।
onCreate মেথডটি HandlerThread ইনিশিয়ালাইজ ও চালু করে, যা সিস্টেম-চালিত অ্যাকশনগুলো পরিচালনা করার জন্য UI থ্রেড থেকে আলাদা একটি প্রসেস থ্রেড প্রদান করে। নিচের উদাহরণে, onCreate মেথডটি CaptioningManager ইনিশিয়ালাইজ করে এবং ACTION_BLOCKED_RATINGS_CHANGED ও ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED অ্যাকশনগুলো পরিচালনা করার জন্য প্রস্তুত হয়। এই অ্যাকশনগুলো এমন সিস্টেম ইনটেন্টকে বর্ণনা করে, যা ব্যবহারকারী প্যারেন্টাল কন্ট্রোল সেটিংস পরিবর্তন করলে এবং ব্লক করা রেটিং-এর তালিকায় কোনো পরিবর্তন হলে ফায়ার হয়।
কোটলিন
override fun onCreate() { super.onCreate() handlerThread = HandlerThread(javaClass.simpleName).apply { start() } dbHandler = Handler(handlerThread.looper) handler = Handler() captioningManager = getSystemService(Context.CAPTIONING_SERVICE) as CaptioningManager setTheme(android.R.style.Theme_Holo_Light_NoActionBar) sessions = mutableListOf<BaseTvInputSessionImpl>() val intentFilter = IntentFilter().apply { addAction(TvInputManager.ACTION_BLOCKED_RATINGS_CHANGED) addAction(TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED) } registerReceiver(broadcastReceiver, intentFilter) }
জাভা
@Override public void onCreate() { super.onCreate(); handlerThread = new HandlerThread(getClass() .getSimpleName()); handlerThread.start(); dbHandler = new Handler(handlerThread.getLooper()); handler = new Handler(); captioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE); setTheme(android.R.style.Theme_Holo_Light_NoActionBar); sessions = new ArrayList<BaseTvInputSessionImpl>(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(TvInputManager .ACTION_BLOCKED_RATINGS_CHANGED); intentFilter.addAction(TvInputManager .ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED); registerReceiver(broadcastReceiver, intentFilter); }

চিত্র ১. TvInputService-এর জীবনচক্র।
ব্লক করা কন্টেন্ট নিয়ে কাজ করা এবং প্যারেন্টাল কন্ট্রোল প্রদান করার বিষয়ে আরও তথ্যের জন্য ‘কন্ট্রোল কন্টেন্ট’ দেখুন। আপনার টিভি ইনপুট সার্ভিসে পরিচালনা করতে চাইতে পারেন এমন আরও সিস্টেম-চালিত অ্যাকশনের জন্য TvInputManager দেখুন।
TvInputService একটি TvInputService.Session তৈরি করে যা প্লেয়ারের অবস্থার পরিবর্তন পরিচালনা করার জন্য Handler.Callback ইমপ্লিমেন্ট করে। onSetSurface এর মাধ্যমে, TvInputService.Session ভিডিও কন্টেন্ট দিয়ে Surface সেট করে। ভিডিও রেন্ডার করার জন্য Surface নিয়ে কাজ করার বিষয়ে আরও তথ্যের জন্য “Integrate player with surface” দেখুন।
ব্যবহারকারী যখন কোনো চ্যানেল নির্বাচন করেন, তখন TvInputService.Session onTune ইভেন্টটি পরিচালনা করে এবং কন্টেন্ট ও কন্টেন্ট মেটাডেটার পরিবর্তনের জন্য সিস্টেম টিভি অ্যাপকে অবহিত করে। এই notify মেথডগুলো এই প্রশিক্ষণের পরবর্তী অংশে `Control Content` এবং `Handle track selection` অংশে বর্ণনা করা হয়েছে।
আপনার সেটআপ কার্যকলাপ সংজ্ঞায়িত করুন
সিস্টেম টিভি অ্যাপটি আপনার টিভি ইনপুটের জন্য নির্ধারিত সেটআপ অ্যাক্টিভিটির সাথে কাজ করে। সেটআপ অ্যাক্টিভিটিটি আবশ্যক এবং সিস্টেম ডাটাবেসের জন্য এতে অবশ্যই অন্তত একটি চ্যানেল রেকর্ড থাকতে হবে। যখন সিস্টেম টিভি অ্যাপটি টিভি ইনপুটের জন্য কোনো চ্যানেল খুঁজে পায় না, তখন এটি সেটআপ অ্যাক্টিভিটিটি চালু করে।
সেটআপ অ্যাক্টিভিটিটি সিস্টেম টিভি অ্যাপকে টিভি ইনপুটের মাধ্যমে উপলব্ধ চ্যানেলগুলো সম্পর্কে বর্ণনা করে, যেমনটি পরবর্তী পাঠ, ‘চ্যানেল ডেটা তৈরি ও আপডেট করুন’- এ দেখানো হয়েছে।
অতিরিক্ত তথ্যসূত্র
,একটি টিভি ইনপুট সার্ভিস একটি মিডিয়া স্ট্রিম সোর্সকে প্রতিনিধিত্ব করে এবং আপনাকে আপনার মিডিয়া কন্টেন্টকে চ্যানেল ও প্রোগ্রাম হিসেবে একটি লিনিয়ার, ব্রডকাস্ট টিভির ধরনে উপস্থাপন করতে দেয়। একটি টিভি ইনপুট সার্ভিসের মাধ্যমে, আপনি প্যারেন্টাল কন্ট্রোল, প্রোগ্রাম গাইডের তথ্য এবং কন্টেন্ট রেটিং প্রদান করতে পারেন। টিভি ইনপুট সার্ভিসটি অ্যান্ড্রয়েড সিস্টেম টিভি অ্যাপের সাথে কাজ করে। এই অ্যাপটিই চূড়ান্তভাবে টিভিতে চ্যানেলের কন্টেন্ট নিয়ন্ত্রণ ও উপস্থাপন করে। সিস্টেম টিভি অ্যাপটি বিশেষভাবে ডিভাইসটির জন্য তৈরি করা হয়েছে এবং থার্ড-পার্টি অ্যাপ দ্বারা এটি অপরিবর্তনীয়। টিভি ইনপুট ফ্রেমওয়ার্ক (TIF) আর্কিটেকচার এবং এর উপাদানগুলো সম্পর্কে আরও তথ্যের জন্য, টিভি ইনপুট ফ্রেমওয়ার্ক দেখুন।
TIF কম্প্যানিয়ন লাইব্রেরি ব্যবহার করে একটি টিভি ইনপুট পরিষেবা তৈরি করুন
TIF কম্প্যানিয়ন লাইব্রেরি হলো একটি ফ্রেমওয়ার্ক যা সাধারণ টিভি ইনপুট পরিষেবা বৈশিষ্ট্যগুলির সম্প্রসারণযোগ্য বাস্তবায়ন প্রদান করে। এটি শুধুমাত্র অ্যান্ড্রয়েড ৫.০ (এপিআই লেভেল ২১) থেকে অ্যান্ড্রয়েড ৭.১ (এপিআই লেভেল ২৫) পর্যন্ত সংস্করণের জন্য চ্যানেল তৈরি করতে OEM-দের ব্যবহারের উদ্দেশ্যে তৈরি।
আপনার প্রজেক্ট আপডেট করুন
OEM-দের পুরোনো সংস্করণ ব্যবহারের জন্য TIF Companion Library-টি androidtv-sample-inputs রিপোজিটরিতে পাওয়া যায়। কোনো অ্যাপে লাইব্রেরিটি কীভাবে অন্তর্ভুক্ত করতে হয়, তার একটি উদাহরণের জন্য ওই রিপোজিটরিটি দেখুন।
ম্যানিফেস্টে আপনার টিভি ইনপুট পরিষেবা ঘোষণা করুন।
আপনার অ্যাপকে অবশ্যই একটি TvInputService সামঞ্জস্যপূর্ণ সার্ভিস প্রদান করতে হবে, যা সিস্টেম আপনার অ্যাপ অ্যাক্সেস করার জন্য ব্যবহার করে। TIF Companion Library-তে BaseTvInputService ক্লাসটি রয়েছে, যা TvInputService এর একটি ডিফল্ট ইমপ্লিমেন্টেশন প্রদান করে এবং আপনি তা কাস্টমাইজ করতে পারেন। BaseTvInputService এর একটি সাবক্লাস তৈরি করুন এবং আপনার ম্যানিফেস্টে সাবক্লাসটিকে একটি সার্ভিস হিসেবে ডিক্লেয়ার করুন।
সার্ভিসটিকে সিস্টেমের সাথে টিভি ইনপুট সংযোগ করার অনুমতি দিতে, ম্যানিফেস্ট ডিক্লারেশনের মধ্যে BIND_TV_INPUT পারমিশনটি উল্লেখ করুন। একটি সিস্টেম সার্ভিস বাইন্ডিং সম্পাদন করে এবং সেটির BIND_TV_INPUT পারমিশন থাকে। সিস্টেম টিভি অ্যাপটি TvInputManager ইন্টারফেসের মাধ্যমে টিভি ইনপুট সার্ভিসগুলোতে অনুরোধ পাঠায়।
আপনার সার্ভিস ডিক্লারেশনে, একটি ইন্টেন্ট ফিল্টার অন্তর্ভুক্ত করুন যা ইন্টেন্টটির মাধ্যমে সম্পাদন করার জন্য অ্যাকশন হিসেবে TvInputService নির্দিষ্ট করে। এছাড়াও, সার্ভিস মেটাডেটাকে একটি পৃথক XML রিসোর্স হিসেবে ডিক্লেয়ার করুন। সার্ভিস ডিক্লারেশন, ইন্টেন্ট ফিল্টার এবং সার্ভিস মেটাডেটা ডিক্লারেশন নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
<service android:name=".rich.RichTvInputService" android:label="@string/rich_input_label" android:permission="android.permission.BIND_TV_INPUT"> <!-- Required filter used by the system to launch our account service. --> <intent-filter> <action android:name="android.media.tv.TvInputService" /> </intent-filter> <!-- An XML file which describes this input. This provides pointers to the RichTvInputSetupActivity to the system/TV app. --> <meta-data android:name="android.media.tv.input" android:resource="@xml/richtvinputservice" /> </service>
একটি পৃথক XML ফাইলে সার্ভিস মেটাডেটা সংজ্ঞায়িত করুন। সার্ভিস মেটাডেটা XML ফাইলটিতে অবশ্যই একটি সেটআপ ইন্টারফেস অন্তর্ভুক্ত থাকতে হবে, যা টিভি ইনপুটের প্রাথমিক কনফিগারেশন এবং চ্যানেল স্ক্যান বর্ণনা করে। মেটাডেটা ফাইলটিতে একটি ফ্ল্যাগও থাকা উচিত, যা নির্দেশ করবে ব্যবহারকারীরা কন্টেন্ট রেকর্ড করতে পারবে কি না। আপনার অ্যাপে কীভাবে কন্টেন্ট রেকর্ডিং সমর্থন করবেন সে সম্পর্কে আরও তথ্যের জন্য, ‘কন্টেন্ট রেকর্ডিং সমর্থন’ দেখুন।
সার্ভিস মেটাডেটা ফাইলটি আপনার অ্যাপের XML রিসোর্স ডিরেক্টরিতে অবস্থিত এবং এর নাম অবশ্যই ম্যানিফেস্টে ঘোষিত রিসোর্সের নামের সাথে মিলতে হবে। পূর্ববর্তী উদাহরণের ম্যানিফেস্ট এন্ট্রিগুলো ব্যবহার করে, আপনাকে res/xml/richtvinputservice.xml ঠিকানায় নিম্নলিখিত বিষয়বস্তু সহ XML ফাইলটি তৈরি করতে হবে:
<?xml version="1.0" encoding="utf-8"?> <tv-input xmlns:android="http://schemas.android.com/apk/res/android" android:canRecord="true" android:setupActivity="com.example.android.sampletvinput.rich.RichTvInputSetupActivity" />
চ্যানেলগুলি সংজ্ঞায়িত করুন এবং আপনার সেটআপ কার্যকলাপ তৈরি করুন
আপনার টিভি ইনপুট সার্ভিসে অবশ্যই অন্তত একটি চ্যানেল নির্ধারণ করতে হবে, যা ব্যবহারকারীরা সিস্টেম টিভি অ্যাপের মাধ্যমে অ্যাক্সেস করতে পারে। আপনার চ্যানেলগুলো সিস্টেম ডেটাবেসে রেজিস্টার করা উচিত এবং একটি সেটআপ অ্যাক্টিভিটি প্রদান করা উচিত, যা সিস্টেম আপনার অ্যাপের জন্য কোনো চ্যানেল খুঁজে না পেলে চালু করবে।
প্রথমে, আপনার অ্যাপকে সিস্টেমের ইলেকট্রনিক প্রোগ্রামিং গাইড (EPG) থেকে ডেটা পড়া এবং তাতে লেখার অনুমতি দিন, যার ডেটাতে ব্যবহারকারীর জন্য উপলব্ধ চ্যানেল ও প্রোগ্রামগুলো অন্তর্ভুক্ত থাকে। আপনার অ্যাপকে এই কাজগুলো করতে সক্ষম করতে এবং ডিভাইস রিস্টার্টের পর EPG-এর সাথে সিঙ্ক করার জন্য, আপনার অ্যাপ ম্যানিফেস্টে নিম্নলিখিত উপাদানগুলো যোগ করুন:
<uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED "/>
আপনার অ্যাপটি যেন অ্যান্ড্রয়েড টিভিতে কন্টেন্ট চ্যানেল সরবরাহকারী একটি অ্যাপ হিসেবে গুগল প্লে স্টোরে প্রদর্শিত হয়, তা নিশ্চিত করতে নিম্নলিখিত উপাদানটি যোগ করুন:
<uses-feature android:name="android.software.live_tv" android:required="true" />
এরপরে, EpgSyncJobService ক্লাসকে এক্সটেন্ড করে এমন একটি ক্লাস তৈরি করুন। এই অ্যাবস্ট্রাক্ট ক্লাসটি আপনাকে এমন একটি জব সার্ভিস তৈরি করতে দেয়, যা সিস্টেম ডাটাবেসে চ্যানেল তৈরি ও আপডেট করে।
আপনার সাবক্লাসে, getChannels ফাংশনে আপনার চ্যানেলের সম্পূর্ণ তালিকা তৈরি করুন এবং তা রিটার্ন করুন। যদি আপনার চ্যানেলগুলো কোনো XMLTV ফাইল থেকে আসে, তাহলে XmlTvParser ক্লাসটি ব্যবহার করুন। অন্যথায়, Channel.Builder ক্লাস ব্যবহার করে প্রোগ্রাম্যাটিকভাবে চ্যানেল তৈরি করুন।
প্রতিটি চ্যানেলের জন্য, একটি নির্দিষ্ট সময়সীমার মধ্যে দেখা যাবে এমন প্রোগ্রামগুলির তালিকা প্রয়োজন হলে সিস্টেম getProgramsForChannel কল করে। এটি চ্যানেলটির জন্য Program অবজেক্টের একটি তালিকা ফেরত দেয়। একটি XMLTV ফাইল থেকে প্রোগ্রাম পেতে XmlTvParser ক্লাসটি ব্যবহার করুন, অথবা Program.Builder ক্লাস ব্যবহার করে প্রোগ্রাম্যাটিকভাবে সেগুলি তৈরি করুন।
প্রতিটি Program অবজেক্টের জন্য, প্রোগ্রামের ভিডিও টাইপের মতো তথ্য সেট করতে একটি InternalProviderData অবজেক্ট ব্যবহার করুন। যদি আপনার কাছে সীমিত সংখ্যক প্রোগ্রাম থাকে যা আপনি চ্যানেলে একটি লুপে পুনরাবৃত্তি করতে চান, তাহলে আপনার প্রোগ্রাম সম্পর্কে তথ্য সেট করার সময় InternalProviderData.setRepeatable মেথডটির মান true ব্যবহার করুন।
জব সার্ভিসটি ইমপ্লিমেন্ট করার পর, এটিকে আপনার অ্যাপ ম্যানিফেস্টে যোগ করুন:
<service android:name=".sync.SampleJobService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" />
সবশেষে, একটি সেটআপ অ্যাক্টিভিটি তৈরি করুন। আপনার সেটআপ অ্যাক্টিভিটিতে চ্যানেল এবং প্রোগ্রামের ডেটা সিঙ্ক করার একটি উপায় থাকা উচিত। এটি করার একটি উপায় হলো, ব্যবহারকারী অ্যাক্টিভিটির UI ব্যবহার করে কাজটি করবে। এছাড়াও, অ্যাক্টিভিটি শুরু হওয়ার সময় অ্যাপটি স্বয়ংক্রিয়ভাবে এটি করে দিতে পারে। যখন সেটআপ অ্যাক্টিভিটির চ্যানেল এবং প্রোগ্রামের তথ্য সিঙ্ক করার প্রয়োজন হবে, তখন অ্যাপটি জব সার্ভিসটি চালু করবে:
কোটলিন
val inputId = getActivity().intent.getStringExtra(TvInputInfo.EXTRA_INPUT_ID) EpgSyncJobService.cancelAllSyncRequests(getActivity()) EpgSyncJobService.requestImmediateSync( getActivity(), inputId, ComponentName(getActivity(), SampleJobService::class.java) )
জাভা
String inputId = getActivity().getIntent().getStringExtra(TvInputInfo.EXTRA_INPUT_ID); EpgSyncJobService.cancelAllSyncRequests(getActivity()); EpgSyncJobService.requestImmediateSync(getActivity(), inputId, new ComponentName(getActivity(), SampleJobService.class));
জব সার্ভিস সিঙ্ক করার জন্য requestImmediateSync মেথডটি ব্যবহার করুন। সিঙ্ক শেষ হওয়া পর্যন্ত ব্যবহারকারীকে অপেক্ষা করতে হয়, তাই আপনার রিকোয়েস্ট পিরিয়ড তুলনামূলকভাবে সংক্ষিপ্ত রাখা উচিত।
ব্যাকগ্রাউন্ডে জব সার্ভিসকে দিয়ে পর্যায়ক্রমে চ্যানেল ও প্রোগ্রাম ডেটা সিঙ্ক করানোর জন্য setUpPeriodicSync মেথডটি ব্যবহার করুন:
কোটলিন
EpgSyncJobService.setUpPeriodicSync( context, inputId, ComponentName(context, SampleJobService::class.java) )
জাভা
EpgSyncJobService.setUpPeriodicSync(context, inputId, new ComponentName(context, SampleJobService.class));
TIF কম্প্যানিয়ন লাইব্রেরি ` requestImmediateSync নামে একটি অতিরিক্ত ওভারলোডেড মেথড প্রদান করে, যা আপনাকে মিলিসেকেন্ডে চ্যানেল ডেটা সিঙ্ক করার সময়কাল নির্দিষ্ট করতে দেয়। ডিফল্ট মেথডটি এক ঘণ্টার চ্যানেল ডেটা সিঙ্ক করে।
TIF কম্প্যানিয়ন লাইব্রেরিটি setUpPeriodicSync নামে একটি অতিরিক্ত ওভারলোডেড মেথডও প্রদান করে, যা আপনাকে চ্যানেল ডেটা সিঙ্ক করার সময়কাল এবং কত ঘন ঘন এই পর্যায়ক্রমিক সিঙ্কটি হওয়া উচিত তা নির্দিষ্ট করতে দেয়। ডিফল্ট মেথডটি প্রতি ১২ ঘণ্টায় ৪৮ ঘণ্টার চ্যানেল ডেটা সিঙ্ক করে।
চ্যানেল ডেটা এবং EPG সম্পর্কে আরও বিস্তারিত জানতে, “চ্যানেল ডেটা নিয়ে কাজ করুন” দেখুন।
টিউনিং অনুরোধ এবং মিডিয়া প্লেব্যাক পরিচালনা করুন
যখন কোনো ব্যবহারকারী একটি নির্দিষ্ট চ্যানেল নির্বাচন করেন, তখন সিস্টেম টিভি অ্যাপটি আপনার অ্যাপ দ্বারা তৈরি একটি Session ব্যবহার করে অনুরোধকৃত চ্যানেলটিতে টিউন করে এবং কন্টেন্ট প্লে করে। টিআইএফ কম্প্যানিয়ন লাইব্রেরি এমন বেশ কিছু ক্লাস সরবরাহ করে, যা আপনি সিস্টেম থেকে আসা চ্যানেল এবং সেশন কলগুলো পরিচালনা করার জন্য এক্সটেন্ড করতে পারেন।
আপনার BaseTvInputService সাবক্লাসটি সেশন তৈরি করে যা টিউনিং অনুরোধগুলি পরিচালনা করে। onCreateSession মেথডটি ওভাররাইড করুন, BaseTvInputService.Session ক্লাস থেকে এক্সটেন্ড করা একটি সেশন তৈরি করুন, এবং আপনার নতুন সেশনটি দিয়ে super.sessionCreated কল করুন। নিম্নলিখিত উদাহরণে, onCreateSession একটি RichTvInputSessionImpl অবজেক্ট রিটার্ন করে যা BaseTvInputService.Session থেকে এক্সটেন্ড করে:
কোটলিন
override fun onCreateSession(inputId: String): Session = RichTvInputSessionImpl(this, inputId).apply { setOverlayViewEnabled(true) }
জাভা
@Override public final Session onCreateSession(String inputId) { RichTvInputSessionImpl session = new RichTvInputSessionImpl(this, inputId); session.setOverlayViewEnabled(true); return session; }
যখন ব্যবহারকারী সিস্টেম টিভি অ্যাপ ব্যবহার করে আপনার কোনো একটি চ্যানেল দেখা শুরু করেন, তখন সিস্টেম আপনার সেশনের onPlayChannel মেথডটি কল করে। প্রোগ্রামটি প্লে হওয়া শুরু করার আগে যদি আপনার কোনো বিশেষ চ্যানেল ইনিশিয়ালাইজেশন করার প্রয়োজন হয়, তবে এই মেথডটি ওভাররাইড করুন।
এরপর সিস্টেমটি বর্তমানে নির্ধারিত প্রোগ্রামটি সংগ্রহ করে এবং প্রোগ্রামের তথ্য ও মিলিসেকেন্ডে শুরুর সময় উল্লেখ করে আপনার সেশনের onPlayProgram মেথডটিকে কল করে। প্রোগ্রামটি চালানো শুরু করতে TvPlayer ইন্টারফেসটি ব্যবহার করুন।
নির্দিষ্ট প্লেব্যাক ইভেন্টগুলো পরিচালনা করার জন্য আপনার মিডিয়া প্লেয়ার কোডে TvPlayer ইমপ্লিমেন্ট করা উচিত। TvPlayer ক্লাসটি আপনার BaseTvInputService ইমপ্লিমেন্টেশনে কোনো জটিলতা না বাড়িয়েই টাইম-শিফটিং কন্ট্রোলের মতো ফিচারগুলো পরিচালনা করে।
আপনার সেশনের getTvPlayer মেথডে, TvPlayer ইমপ্লিমেন্ট করে এমন আপনার মিডিয়া প্লেয়ারটি রিটার্ন করুন। TV Input Service স্যাম্পল অ্যাপটি ExoPlayer ব্যবহার করে এমন একটি মিডিয়া প্লেয়ার ইমপ্লিমেন্ট করে।
টিভি ইনপুট ফ্রেমওয়ার্ক ব্যবহার করে একটি টিভি ইনপুট সার্ভিস তৈরি করুন।
যদি আপনার টিভি ইনপুট পরিষেবা TIF Companion Library ব্যবহার করতে না পারে, তাহলে আপনাকে নিম্নলিখিত উপাদানগুলি বাস্তবায়ন করতে হবে:
-
TvInputServiceটিভি ইনপুটের জন্য দীর্ঘস্থায়ী এবং ব্যাকগ্রাউন্ডে উপলব্ধতা প্রদান করে। -
TvInputService.Sessionটিভির ইনপুট অবস্থা বজায় রাখে এবং হোস্টিং অ্যাপের সাথে যোগাযোগ করে। -
TvContractটিভি ইনপুটে উপলব্ধ চ্যানেল এবং প্রোগ্রামগুলির বর্ণনা দেয়। -
TvContract.Channelsএকটি টিভি চ্যানেল সম্পর্কিত তথ্য উপস্থাপন করে। -
TvContract.Programsএকটি টিভি প্রোগ্রামের শিরোনাম এবং শুরুর সময়ের মতো তথ্য দিয়ে প্রোগ্রামটির বর্ণনা দেয়। -
TvTrackInfoএকটি অডিও, ভিডিও, বা সাবটাইটেল ট্র্যাককে বোঝায়। -
TvContentRatingএকটি কন্টেন্ট রেটিং বর্ণনা করে এবং নিজস্ব কন্টেন্ট রেটিং স্কিম তৈরির সুযোগ দেয়। -
TvInputManagerসিস্টেম টিভি অ্যাপের জন্য একটি এপিআই প্রদান করে এবং টিভি ইনপুট ও অ্যাপগুলোর সাথে মিথস্ক্রিয়া পরিচালনা করে।
আপনাকে নিম্নলিখিত কাজগুলোও করতে হবে:
- ম্যানিফেস্টে আপনার টিভি ইনপুট পরিষেবাটি ঘোষণা করুন, যেমনটি "ম্যানিফেস্টে আপনার টিভি ইনপুট পরিষেবা ঘোষণা করুন" অংশে বর্ণনা করা হয়েছে।
- সার্ভিস মেটাডেটা ফাইলটি তৈরি করুন।
- আপনার চ্যানেল ও অনুষ্ঠানের তথ্য তৈরি এবং নিবন্ধন করুন।
- আপনার সেটআপ কার্যকলাপ তৈরি করুন।
আপনার টিভি ইনপুট পরিষেবা সংজ্ঞায়িত করুন
আপনার সার্ভিসের জন্য, আপনি TvInputService ক্লাসটি এক্সটেন্ড করবেন। একটি TvInputService ইমপ্লিমেন্টেশন হলো একটি বাউন্ড সার্ভিস , যেখানে সিস্টেম সার্ভিসটি হলো ক্লায়েন্ট যা এর সাথে বাইন্ড করে। আপনার যে সার্ভিস লাইফসাইকেল মেথডগুলো ইমপ্লিমেন্ট করতে হবে, তা চিত্র ১-এ দেখানো হয়েছে।
onCreate মেথডটি HandlerThread ইনিশিয়ালাইজ ও চালু করে, যা সিস্টেম-চালিত অ্যাকশনগুলো পরিচালনা করার জন্য UI থ্রেড থেকে আলাদা একটি প্রসেস থ্রেড প্রদান করে। নিচের উদাহরণে, onCreate মেথডটি CaptioningManager ইনিশিয়ালাইজ করে এবং ACTION_BLOCKED_RATINGS_CHANGED ও ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED অ্যাকশনগুলো পরিচালনা করার জন্য প্রস্তুত হয়। এই অ্যাকশনগুলো এমন সিস্টেম ইনটেন্টকে বর্ণনা করে, যা ব্যবহারকারী প্যারেন্টাল কন্ট্রোল সেটিংস পরিবর্তন করলে এবং ব্লক করা রেটিং-এর তালিকায় কোনো পরিবর্তন হলে ফায়ার হয়।
কোটলিন
override fun onCreate() { super.onCreate() handlerThread = HandlerThread(javaClass.simpleName).apply { start() } dbHandler = Handler(handlerThread.looper) handler = Handler() captioningManager = getSystemService(Context.CAPTIONING_SERVICE) as CaptioningManager setTheme(android.R.style.Theme_Holo_Light_NoActionBar) sessions = mutableListOf<BaseTvInputSessionImpl>() val intentFilter = IntentFilter().apply { addAction(TvInputManager.ACTION_BLOCKED_RATINGS_CHANGED) addAction(TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED) } registerReceiver(broadcastReceiver, intentFilter) }
জাভা
@Override public void onCreate() { super.onCreate(); handlerThread = new HandlerThread(getClass() .getSimpleName()); handlerThread.start(); dbHandler = new Handler(handlerThread.getLooper()); handler = new Handler(); captioningManager = (CaptioningManager) getSystemService(Context.CAPTIONING_SERVICE); setTheme(android.R.style.Theme_Holo_Light_NoActionBar); sessions = new ArrayList<BaseTvInputSessionImpl>(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(TvInputManager .ACTION_BLOCKED_RATINGS_CHANGED); intentFilter.addAction(TvInputManager .ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED); registerReceiver(broadcastReceiver, intentFilter); }

চিত্র ১. TvInputService-এর জীবনচক্র।
ব্লক করা কন্টেন্ট নিয়ে কাজ করা এবং প্যারেন্টাল কন্ট্রোল প্রদান করার বিষয়ে আরও তথ্যের জন্য ‘কন্ট্রোল কন্টেন্ট’ দেখুন। আপনার টিভি ইনপুট সার্ভিসে পরিচালনা করতে চাইতে পারেন এমন আরও সিস্টেম-চালিত অ্যাকশনের জন্য TvInputManager দেখুন।
TvInputService একটি TvInputService.Session তৈরি করে যা প্লেয়ারের অবস্থার পরিবর্তন পরিচালনা করার জন্য Handler.Callback ইমপ্লিমেন্ট করে। onSetSurface এর মাধ্যমে, TvInputService.Session ভিডিও কন্টেন্ট দিয়ে Surface সেট করে। ভিডিও রেন্ডার করার জন্য Surface নিয়ে কাজ করার বিষয়ে আরও তথ্যের জন্য “Integrate player with surface” দেখুন।
ব্যবহারকারী যখন কোনো চ্যানেল নির্বাচন করেন, তখন TvInputService.Session onTune ইভেন্টটি পরিচালনা করে এবং কন্টেন্ট ও কন্টেন্ট মেটাডেটার পরিবর্তনের জন্য সিস্টেম টিভি অ্যাপকে অবহিত করে। এই notify মেথডগুলো এই প্রশিক্ষণের পরবর্তী অংশে `Control Content` এবং `Handle track selection` অংশে বর্ণনা করা হয়েছে।
আপনার সেটআপ কার্যকলাপ সংজ্ঞায়িত করুন
সিস্টেম টিভি অ্যাপটি আপনার টিভি ইনপুটের জন্য নির্ধারিত সেটআপ অ্যাক্টিভিটির সাথে কাজ করে। সেটআপ অ্যাক্টিভিটিটি আবশ্যক এবং সিস্টেম ডাটাবেসের জন্য এতে অবশ্যই অন্তত একটি চ্যানেল রেকর্ড থাকতে হবে। যখন সিস্টেম টিভি অ্যাপটি টিভি ইনপুটের জন্য কোনো চ্যানেল খুঁজে পায় না, তখন এটি সেটআপ অ্যাক্টিভিটিটি চালু করে।
সেটআপ অ্যাক্টিভিটিটি সিস্টেম টিভি অ্যাপকে টিভি ইনপুটের মাধ্যমে উপলব্ধ চ্যানেলগুলো সম্পর্কে বর্ণনা করে, যেমনটি পরবর্তী পাঠ, ‘চ্যানেল ডেটা তৈরি ও আপডেট করুন’- এ দেখানো হয়েছে।