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

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

  1. supportsPictureInPicture जोड़ें और उसे true पर सेट करें. इससे यह एलान किया जा सकेगा कि आपके ऐप्लिकेशन में PiP का इस्तेमाल किया जाएगा.
  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 से पहले के वर्शन के लिए, ऐप्लिकेशन छोड़ने पर पिन किए गए विंडो मोड जोड़ना

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

  1. वर्शन गेट जोड़ें, ताकि इस कोड को सिर्फ़ O से लेकर R तक के वर्शन में ऐक्सेस किया जा सके.
  2. Context को पासकोड के तौर पर इस्तेमाल करके, DisposableEffect का इस्तेमाल करें.
  3. DisposableEffect में, लैम्डा का इस्तेमाल करके onUserLeaveHintProvider के ट्रिगर होने पर होने वाले व्यवहार के बारे में बताएं. लैम्ब्डा फ़ंक्शन में, findActivity() पर enterPictureInPictureMode() को कॉल करें और PictureInPictureParams.Builder().build() को पास करें.
  4. findActivity() का इस्तेमाल करके addOnUserLeaveHintListener जोड़ें और उसे lambda फ़ंक्शन में पास करें.
  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: () -> Unit = {
            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 के बाद के वर्शन के लिए, ऐप्लिकेशन इस्तेमाल करते समय पिन किए गए वीडियो को दूसरे ऐप्लिकेशन पर चलाने की सुविधा जोड़ना

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

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

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 का इस्तेमाल करना

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

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 प्लेयर के लिए किया जाता है.