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

अपनी 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 से पहले के वर्शन के लिए, ऐप्लिकेशन से बाहर निकलने पर पीआईपी मोड चालू करने की सुविधा जोड़ना

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

  1. वर्शन गेट जोड़ें, ताकि इस कोड को सिर्फ़ O से लेकर R तक के वर्शन में ऐक्सेस किया जा सके.
  2. DisposableEffect का इस्तेमाल करें और Context को कुंजी के तौर पर सेट करें.
  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 के बाद के वर्शन के लिए, ऐप्लिकेशन छोड़ने पर पीआईपी मोड चालू करने की सुविधा जोड़ना

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

  1. modifier बनाएं और उस पर onGloballyPositioned को कॉल करें. लेआउट के कोऑर्डिनेट का इस्तेमाल, बाद के चरण में किया जाएगा.
  2. PictureInPictureParams.Builder() के लिए एक वैरिएबल बनाएं.
  3. एसडीके, S या इसके बाद का वर्शन है या नहीं, यह देखने के लिए if स्टेटमेंट जोड़ें. अगर ऐसा है, तो बिल्डर में 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)

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

पीआईपी विंडो का आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) सेट करने के लिए, कोई खास आसपेक्ट रेशियो चुना जा सकता है. इसके अलावा, प्लेयर के वीडियो साइज़ की चौड़ाई और ऊंचाई का इस्तेमाल किया जा सकता है. अगर 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 प्लेयर के लिए किया जाता है.