अपने ऐप्लिकेशन को पीआईपी के लिए सेट अप करना

अपनी AndroidManifest.xml फ़ाइल के गतिविधि टैग में, यह तरीका अपनाएं:

  1. अपने ऐप्लिकेशन में पिक्चर में पिक्चर (पीआईपी) मोड का इस्तेमाल करने का एलान करने के लिए, supportsPictureInPicture जोड़ें और इसे true पर सेट करें.
  2. configChanges जोड़ें और उसे orientation|screenLayout|screenSize|smallestScreenSize पर सेट करें. इससे यह पता चलेगा कि आपकी गतिविधि, लेआउट कॉन्फ़िगरेशन में होने वाले बदलावों को मैनेज करती है. इस तरह, पीआईपी मोड के ट्रांज़िशन के दौरान लेआउट में बदलाव होने पर, आपकी गतिविधि फिर से लॉन्च नहीं होती.
<activity
    android:name=".SnippetsActivity"
    android:exported="true"
    android:supportsPictureInPicture="true"
    android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize"
    android:theme="@style/Theme.Snippets">

अपने Compose कोड में, यह काम करें:

  1. Context पर यह एक्सटेंशन जोड़ें. गतिविधि को ऐक्सेस करने के लिए, आपको इस एक्सटेंशन का इस्तेमाल कई बार करना होगा.
    internal fun Context.findActivity(): ComponentActivity {
        var context = this
        while (context is ContextWrapper) {
            if (context is ComponentActivity) return context
            context = context.baseContext
        }
        throw IllegalStateException("Picture in picture should be called in the context of an Activity")
    }

Android 12 से पहले के वर्शन के लिए, लीव ऐप्लिकेशन में PiP मोड की सुविधा जोड़ना

Android 12 से पहले के वर्शन वाले डिवाइसों में पीआईपी मोड जोड़ने के लिए, addOnUserLeaveHintProvider का इस्तेमाल करें. Android 12 से पहले के वर्शन में PiP मोड जोड़ने के लिए, यह तरीका अपनाएं:

  1. वर्शन गेट जोड़ें, ताकि इस कोड को सिर्फ़ O से R वर्शन में ऐक्सेस किया जा सके.
  2. Context को कुंजी के तौर पर इस्तेमाल करके, DisposableEffect का इस्तेमाल करें.
  3. DisposableEffect के अंदर, लैंबडा का इस्तेमाल करके यह तय करें कि onUserLeaveHintProvider कब ट्रिगर होगा. लैम्डा में, findActivity() पर enterPictureInPictureMode() को कॉल करें और PictureInPictureParams.Builder().build() को पास करें.
  4. findActivity() का इस्तेमाल करके addOnUserLeaveHintListener जोड़ें और लैम्ब्डा में पास करें.
  5. onDispose में, findActivity() का इस्तेमाल करके removeOnUserLeaveHintListener जोड़ें और इसे लैम्डा में पास करें.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
    Build.VERSION.SDK_INT < Build.VERSION_CODES.S
) {
    val context = LocalContext.current
    DisposableEffect(context) {
        val onUserLeaveBehavior = Runnable {
            context.findActivity()
                .enterPictureInPictureMode(PictureInPictureParams.Builder().build())
        }
        context.findActivity().addOnUserLeaveHintListener(
            onUserLeaveBehavior
        )
        onDispose {
            context.findActivity().removeOnUserLeaveHintListener(
                onUserLeaveBehavior
            )
        }
    }
} else {
    Log.i("PiP info", "API does not support PiP")
}

Android 12 और इसके बाद के वर्शन के लिए, छुट्टी वाले ऐप्लिकेशन में PiP मोड जोड़ने की सुविधा

Android 12 के बाद, PictureInPictureParams.Builder को एक ऐसे मॉडिफ़ायर के ज़रिए जोड़ा जाता है जिसे ऐप्लिकेशन के वीडियो प्लेयर को पास किया जाता है.

  1. एक modifier बनाएं और उस पर onGloballyPositioned को कॉल करें. लेआउट के कोऑर्डिनेट का इस्तेमाल बाद के चरण में किया जाएगा.
  2. PictureInPictureParams.Builder() के लिए एक वैरिएबल बनाएं.
  3. यह देखने के लिए कि एसडीके का वर्शन S या उसके बाद का है या नहीं, if स्टेटमेंट जोड़ें. अगर ऐसा है, तो बिल्डर में setAutoEnterEnabled जोड़ें और इसे true पर सेट करें, ताकि स्वाइप करने पर PiP मोड चालू हो जाए. इससे enterPictureInPictureMode के मुकाबले, बेहतर ऐनिमेशन मिलता है.
  4. setPictureInPictureParams() को कॉल करने के लिए, findActivity() का इस्तेमाल करें. build() को कॉल करें और builder पर कॉल करके उसे पास करें.

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(true)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}
VideoPlayer(pipModifier)

PiP विंडो का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) सेट करने के लिए, setAspectRatio का इस्तेमाल करें

PiP विंडो का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) सेट करने के लिए, किसी खास आसपेक्ट रेशियो को चुना जा सकता है. इसके अलावा, प्लेयर के वीडियो साइज़ की चौड़ाई और ऊंचाई का इस्तेमाल भी किया जा सकता है. अगर Media3 प्लेयर का इस्तेमाल किया जा रहा है, तो पक्का करें कि प्लेयर शून्य न हो. साथ ही, पहलू अनुपात सेट करने से पहले, यह भी पक्का करें कि प्लेयर के वीडियो का साइज़ VideoSize.UNKNOWN के बराबर न हो.

val context = LocalContext.current

val pipModifier = modifier.onGloballyPositioned { layoutCoordinates ->
    val builder = PictureInPictureParams.Builder()
    if (shouldEnterPipMode && player != null && player.videoSize != VideoSize.UNKNOWN) {
        val sourceRect = layoutCoordinates.boundsInWindow().toAndroidRectF().toRect()
        builder.setSourceRectHint(sourceRect)
        builder.setAspectRatio(
            Rational(player.videoSize.width, player.videoSize.height)
        )
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        builder.setAutoEnterEnabled(shouldEnterPipMode)
    }
    context.findActivity().setPictureInPictureParams(builder.build())
}

VideoPlayer(pipModifier)

अगर कस्टम प्लेयर का इस्तेमाल किया जा रहा है, तो प्लेयर की ऊंचाई और चौड़ाई के लिए आसपेक्ट रेशियो सेट करें. इसके लिए, अपने प्लेयर के हिसाब से सिंटैक्स का इस्तेमाल करें. ध्यान दें कि अगर प्लेयर को शुरू करते समय उसका साइज़ बदलता है और वह पहलू अनुपात की मान्य सीमाओं से बाहर चला जाता है, तो आपका ऐप्लिकेशन क्रैश हो जाएगा. आपको यह जांच करनी पड़ सकती है कि पहलू अनुपात की गणना कब की जा सकती है. यह जांच, Media3 प्लेयर के लिए की जाने वाली जांच की तरह ही होती है.