আপনার অ্যান্ড্রয়েড অ্যাপে উন্নত বৈশিষ্ট্য যোগ করুন

বিজ্ঞাপন বিরতি

অ্যান্ড্রয়েড সেন্ডার SDK একটি নির্দিষ্ট মিডিয়া স্ট্রিমের মধ্যে অ্যাড ব্রেক এবং কম্প্যানিয়ন বিজ্ঞাপনের জন্য সহায়তা প্রদান করে।

অ্যাড ব্রেক কীভাবে কাজ করে সে সম্পর্কে আরও তথ্যের জন্য ওয়েব রিসিভার অ্যাড ব্রেকস ওভারভিউ দেখুন।

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

অ্যান্ড্রয়েডে, AdBreakClipInfo এবং AdBreakInfo ব্যবহার করে একটি লোড কমান্ডে বিজ্ঞাপন বিরতি নির্দিষ্ট করুন:

কোটলিন
val breakClip1: AdBreakClipInfo =
    AdBreakClipInfo.Builder("bc0")
        .setTitle("Clip title")
        .setPosterUrl("https://www.some.url")
        .setDuration(60000)
        .setWhenSkippableInMs(5000)  // Set this field so that the ad is skippable
        .build()

val breakClip2: AdBreakClipInfo = 
val breakClip3: AdBreakClipInfo = 

val break1: AdBreakClipInfo =
    AdBreakInfo.Builder(/* playbackPositionInMs= */ 10000)
        .setId("b0")
        .setBreakClipIds({"bc0","bc1","bc2"})
        
        .build()

val mediaInfo: MediaInfo = MediaInfo.Builder()
    
    .setAdBreaks({break1})
    .setAdBreakClips({breakClip1, breakClip2, breakClip3})
    .build()

val mediaLoadRequestData: MediaLoadRequestData = MediaInfo.Builder()
    
    .setMediaInfo(mediaInfo)
    .build()

remoteMediaClient.load(mediaLoadRequestData)
জাভা
AdBreakClipInfo breakClip1 =
    new AdBreakClipInfo.Builder("bc0")
        .setTitle("Clip title")
        .setPosterUrl("https://www.some.url")
        .setDuration(60000)
        .setWhenSkippableInMs(5000)  // Set this field so that the ad is skippable
        .build();

AdBreakClipInfo breakClip2 = 
AdBreakClipInfo breakClip3 = 

AdBreakInfo break1 =
    new AdBreakInfo.Builder(/* playbackPositionInMs= */ 10000)
        .setId("b0")
        .setBreakClipIds({"bc0","bc1","bc2"})
        
        .build();

MediaInfo mediaInfo = new MediaInfo.Builder()
    
    .setAdBreaks({break1})
    .setAdBreakClips({breakClip1, breakClip2, breakClip3})
    .build();

MediaLoadRequestData mediaLoadRequestData = new MediaInfo.Builder()
    
    .setMediaInfo(mediaInfo)
    .build();

remoteMediaClient.load(mediaLoadRequestData);

কাস্টম অ্যাকশন যোগ করুন

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

// In AndroidManifest.xml
<receiver android:name="com.example.MyMediaIntentReceiver" />
কোটলিন
// In your OptionsProvider
var mediaOptions = CastMediaOptions.Builder()
    .setMediaIntentReceiverClassName(MyMediaIntentReceiver::class.java.name)
    .build()

// Implementation of MyMediaIntentReceiver
internal class MyMediaIntentReceiver : MediaIntentReceiver() {
    override fun onReceiveActionTogglePlayback(currentSession: Session) {
    }

    override fun onReceiveActionMediaButton(currentSession: Session, intent: Intent) {
    }

    override fun onReceiveOtherAction(context: Context?, action: String, intent: Intent) {
    }
}
জাভা
// In your OptionsProvider
CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
        .setMediaIntentReceiverClassName(MyMediaIntentReceiver.class.getName())
        .build();

// Implementation of MyMediaIntentReceiver
class MyMediaIntentReceiver extends MediaIntentReceiver {
    @Override
    protected void onReceiveActionTogglePlayback(Session currentSession) {
    }

    @Override
    protected void onReceiveActionMediaButton(Session currentSession, Intent intent) {
    }

    @Override
    protected void onReceiveOtherAction(Context context, String action, Intent intent) {
    }
}

একটি কাস্টম চ্যানেল যোগ করুন

প্রেরক অ্যাপটি রিসিভার অ্যাপের সাথে যোগাযোগ করার জন্য, আপনার অ্যাপটিকে একটি কাস্টম চ্যানেল তৈরি করতে হবে। প্রেরক কাস্টম চ্যানেল ব্যবহার করে রিসিভারে স্ট্রিং বার্তা পাঠাতে পারেন। প্রতিটি কাস্টম চ্যানেল একটি অনন্য নেমস্পেস দ্বারা সংজ্ঞায়িত এবং urn:x-cast: উপসর্গ দিয়ে শুরু হওয়া উচিত, উদাহরণস্বরূপ, urn:x-cast:com.example.custom । একাধিক কাস্টম চ্যানেল থাকা সম্ভব, প্রতিটির একটি অনন্য নেমস্পেস থাকবে। রিসিভার অ্যাপটি একই নেমস্পেস ব্যবহার করে বার্তা পাঠাতে এবং গ্রহণ করতে পারে।

কাস্টম চ্যানেলটি Cast.MessageReceivedCallback ইন্টারফেসের মাধ্যমে বাস্তবায়িত হয়:

কোটলিন
class HelloWorldChannel : MessageReceivedCallback {
    val namespace: String
        get() = "urn:x-cast:com.example.custom"

    override fun onMessageReceived(castDevice: CastDevice, namespace: String, message: String) {
        Log.d(TAG, "onMessageReceived: $message")
    }
}
জাভা
class HelloWorldChannel implements Cast.MessageReceivedCallback {
    public String getNamespace() {
        return "urn:x-cast:com.example.custom";
    }
    @Override
    public void onMessageReceived(CastDevice castDevice, String namespace, String message) {
        Log.d(TAG, "onMessageReceived: " + message);
    }
}

একবার প্রেরক অ্যাপটি রিসিভার অ্যাপের সাথে সংযুক্ত হয়ে গেলে, setMessageReceivedCallbacks পদ্ধতি ব্যবহার করে কাস্টম চ্যানেল তৈরি করা যেতে পারে:

কোটলিন
try {
    mCastSession.setMessageReceivedCallbacks(
        mHelloWorldChannel.namespace,
        mHelloWorldChannel)
} catch (e: IOException) {
    Log.e(TAG, "Exception while creating channel", e)
}
জাভা
try {
    mCastSession.setMessageReceivedCallbacks(
            mHelloWorldChannel.getNamespace(),
            mHelloWorldChannel);
} catch (IOException e) {
    Log.e(TAG, "Exception while creating channel", e);
}

একবার কাস্টম চ্যানেল তৈরি হয়ে গেলে, প্রেরক sendMessage পদ্ধতি ব্যবহার করে সেই চ্যানেলের মাধ্যমে রিসিভারের কাছে স্ট্রিং বার্তা পাঠাতে পারেন:

কোটলিন
private fun sendMessage(message: String) {
    if (mHelloWorldChannel != null) {
        try {
            mCastSession.sendMessage(mHelloWorldChannel.namespace, message)
                .setResultCallback { status ->
                    if (!status.isSuccess) {
                        Log.e(TAG, "Sending message failed")
                    }
                }
        } catch (e: Exception) {
            Log.e(TAG, "Exception while sending message", e)
        }
    }
}
জাভা
private void sendMessage(String message) {
    if (mHelloWorldChannel != null) {
        try {
            mCastSession.sendMessage(mHelloWorldChannel.getNamespace(), message)
                .setResultCallback( status -> {
                    if (!status.isSuccess()) {
                        Log.e(TAG, "Sending message failed");
                    }
                });
        } catch (Exception e) {
            Log.e(TAG, "Exception while sending message", e);
        }
    }
}

অটোপ্লে সমর্থন করে

অটোপ্লে এবং কিউইং API বিভাগটি দেখুন।

UX উইজেটের জন্য ছবি নির্বাচন ওভাররাইড করুন

ফ্রেমওয়ার্কের বিভিন্ন উপাদান (যেমন কাস্ট ডায়ালগ, মিনি কন্ট্রোলার এবং UIMediaController, যদি কনফিগার করা থাকে) বর্তমানে কাস্ট করা মিডিয়ার জন্য আর্টওয়ার্ক প্রদর্শন করবে। ইমেজ আর্টওয়ার্কের URL গুলি সাধারণত মিডিয়ার জন্য MediaMetadata তে অন্তর্ভুক্ত থাকে, তবে প্রেরক অ্যাপের URL গুলির জন্য একটি বিকল্প উৎস থাকতে পারে।

ImagePicker ক্লাসটি MediaMetadata এর ছবির তালিকা থেকে একটি উপযুক্ত ছবি নির্বাচন করার একটি উপায় নির্ধারণ করে, যা ছবির ব্যবহারের উপর ভিত্তি করে, উদাহরণস্বরূপ, বিজ্ঞপ্তি থাম্বনেল বা পূর্ণ স্ক্রিন ব্যাকগ্রাউন্ড। ডিফল্ট ImagePicker বাস্তবায়ন সর্বদা প্রথম ছবিটি বেছে নেয়, অথবা MediaMetadata এ কোনও ছবি উপলব্ধ না থাকলে null প্রদান করে। আপনার অ্যাপ ImagePicker সাবক্লাস করতে পারে এবং onPickImage(MediaMetadata, ImageHints) পদ্ধতিকে ওভাররাইড করে একটি বিকল্প বাস্তবায়ন প্রদান করতে পারে, এবং তারপর CastMediaOptions.Builder এর setImagePicker পদ্ধতি ব্যবহার করে সেই সাবক্লাসটি নির্বাচন করতে পারে। ImageHints একটি ImagePicker কে UI তে প্রদর্শনের জন্য নির্বাচিত একটি ছবির ধরণ এবং আকার সম্পর্কে ইঙ্গিত প্রদান করে।

কাস্ট ডায়ালগ কাস্টমাইজ করা

সেশন জীবনচক্র পরিচালনা

সেশন লাইফসাইকেল পরিচালনার জন্য SessionManager হল কেন্দ্রীয় স্থান। SessionManager সেশন শুরু, পুনঃসূচনা এবং শেষ করার জন্য অ্যান্ড্রয়েড MediaRouter রুট নির্বাচনের অবস্থার পরিবর্তনগুলি শোনে। যখন একটি রুট নির্বাচন করা হয়, তখন SessionManager একটি Session অবজেক্ট তৈরি করবে এবং এটি শুরু বা পুনঃসূচনা করার চেষ্টা করবে। যখন একটি রুট নির্বাচন করা না হয়, তখন SessionManager বর্তমান সেশনটি শেষ করবে।

অতএব, SessionManager সঠিকভাবে সেশন জীবনচক্র পরিচালনা করে তা নিশ্চিত করার জন্য, আপনাকে অবশ্যই নিশ্চিত করতে হবে যে:

আপনি কীভাবে কাস্ট ডায়ালগ তৈরি করেন তার উপর নির্ভর করে, অতিরিক্ত পদক্ষেপ নেওয়ার প্রয়োজন হতে পারে:

  • যদি আপনি MediaRouteChooserDialog এবং MediaRouteControllerDialog ব্যবহার করে Cast ডায়ালগ তৈরি করেন, তাহলে এই ডায়ালগগুলি MediaRouter এ স্বয়ংক্রিয়ভাবে রুট নির্বাচন আপডেট করবে, তাই কিছুই করার প্রয়োজন নেই।
  • যদি আপনি CastButtonFactory.setUpMediaRouteButton(Context, Menu, int) অথবা CastButtonFactory.setUpMediaRouteButton(Context, MediaRouteButton) ব্যবহার করে আপনার Cast বোতাম সেট আপ করেন, তাহলে ডায়ালগগুলি আসলে MediaRouteChooserDialog এবং MediaRouteControllerDialog ব্যবহার করে তৈরি করা হয়, তাই কিছুই করার প্রয়োজন নেই।
  • অন্যান্য ক্ষেত্রে, আপনাকে কাস্টম কাস্ট ডায়ালগ তৈরি করতে হবে, তাই MediaRouter এ রুট নির্বাচনের অবস্থা আপডেট করার জন্য আপনাকে উপরের নির্দেশাবলী অনুসরণ করতে হবে।

জিরো ডিভাইসের অবস্থা

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

আপনি যদি ডিফল্ট MediaRouteChooserDialog ব্যবহার করেন, তাহলে জিরো ডিভাইসের অবস্থা ইতিমধ্যেই পরিচালনা করা হয়েছে।

পরবর্তী পদক্ষেপ

এর মাধ্যমে আপনি আপনার অ্যান্ড্রয়েড সেন্ডার অ্যাপে যে বৈশিষ্ট্যগুলি যোগ করতে পারেন তা শেষ হবে। আপনি এখন অন্য প্ল্যাটফর্মের জন্য ( iOS বা ওয়েব ) একটি সেন্ডার অ্যাপ তৈরি করতে পারেন, অথবা একটি ওয়েব রিসিভার অ্যাপ তৈরি করতে পারেন।