Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show Meeting over apps . #259

Open
OsamaSaqrPaysky opened this issue Dec 6, 2024 · 22 comments
Open

Show Meeting over apps . #259

OsamaSaqrPaysky opened this issue Dec 6, 2024 · 22 comments

Comments

@OsamaSaqrPaysky
Copy link

there is feature can be used to make video meeting to show as window over apps.

@saghul
Copy link
Member

saghul commented Dec 6, 2024

What is your question?

@OsamaSaqrPaysky
Copy link
Author

there is any supported feature to enable meeting activity to show as dialog over apps like zoom and massnger apps ?

@saghul
Copy link
Member

saghul commented Dec 6, 2024

Yes, it should work by default on Android.

@OsamaSaqrPaysky
Copy link
Author

its not work with me , if its need some configuration please share it with me .

@saghul
Copy link
Member

saghul commented Dec 6, 2024

It should work out of the box. What SDK sample app did you try?

@OsamaSaqrPaysky
Copy link
Author

i just apply this sdk implementation('org.jitsi.react:jitsi-meet-sdk:+') for android sdk .

@saghul
Copy link
Member

saghul commented Dec 6, 2024

Please start by running the test app here: https://github.com/jitsi/jitsi-meet-sdk-samples/tree/master/android/java/JitsiSDKTest

@OsamaSaqrPaysky
Copy link
Author

still not working also .

@saghul
Copy link
Member

saghul commented Dec 7, 2024

Did you test the sample app without any changes?

@OsamaSaqrPaysky
Copy link
Author

OsamaSaqrPaysky commented Dec 7, 2024

no , its not build on my local machine , i just compare with my code .

@saghul
Copy link
Member

saghul commented Dec 7, 2024

Mate, it's really difficult to help you if you only share half of what you are doing, and zero logs.

@OsamaSaqrPaysky
Copy link
Author

yes , i can get my logs with
i get this from log
Error entering PiP mode: java.lang.IllegalStateException: enterPictureInPictureMode: Current activity does not support picture-in-picture. also i set feature flag for picture-in-picture with true .

@saghul
Copy link
Member

saghul commented Dec 9, 2024

Full logs and device specs please.

@OsamaSaqrPaysky
Copy link
Author

device spec : different devices with android 14 and 15 , also emulator and real device

and that is complete logs :
JitsiMeetUncaughtExceptionHandler FATAL ERROR
java.lang.IllegalStateException: enterPictureInPictureMode: Current activity does not support picture-in-picture.
at android.os.Parcel.createExceptionOrNull(Parcel.java:3250)
at android.os.Parcel.createException(Parcel.java:3226)
at android.os.Parcel.readException(Parcel.java:3209)
at android.os.Parcel.readException(Parcel.java:3151)
at android.app.IActivityClientController$Stub$Proxy.enterPictureInPictureMode(IActivityClientController.java:2096)
at android.app.ActivityClient.enterPictureInPictureMode(ActivityClient.java:392)
at android.app.Activity.enterPictureInPictureMode(Activity.java:3134)
at com.lifehospital.consultationapp.ui.MeetingActivity.onUserLeaveHint(MeetingActivity.kt:284)
at android.app.Activity.performUserLeaving(Activity.java:9224)
at android.app.Instrumentation.callActivityOnUserLeaving(Instrumentation.java:1786)
at android.app.ActivityThread.performUserLeavingActivity(ActivityThread.java:5522)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:5503)
at android.app.servertransaction.PauseActivityItem.execute(PauseActivityItem.java:47)
at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:60)
at android.app.servertransaction.TransactionExecutor.executeLifecycleItem(TransactionExecutor.java:225)
at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:107)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:81)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2636)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.app.ActivityThread.main(ActivityThread.java:8705)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)
Caused by: android.os.RemoteException: Remote stack trace:
at com.android.server.wm.ActivityClientController.ensureValidPictureInPictureActivityParams(ActivityClientController.java:1060)
at com.android.server.wm.ActivityClientController.enterPictureInPictureMode(ActivityClientController.java:962)
at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:1065)
at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:168)
at android.os.Binder.execTransactInternal(Binder.java:1500)

@saghul
Copy link
Member

saghul commented Dec 9, 2024

How did you integrate the SDK? I don't see JitsiMeetActivity in the traceback.

@OsamaSaqrPaysky
Copy link
Author

yes , i create custom activity which implement JitsiMeetActivityInterface

@saghul
Copy link
Member

saghul commented Dec 9, 2024

Does it work when you use JitsiMeetActivity?

@OsamaSaqrPaysky
Copy link
Author

when make my custom activity extend from JitsiMeetActivity get this exception : androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.swmansion.rnscreens.ScreenFragment: calling Fragment constructor caused an exception at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4048)

@saghul
Copy link
Member

saghul commented Dec 9, 2024

Please share a small project that reproduces the problem.

@OsamaSaqrPaysky
Copy link
Author

@androidentrypoint
class MeetingActivity : JitsiMeetActivity(), JitsiMeetActivityInterface {
private var view: JitsiMeetView? = null
private var callBroadcastReceiver: BroadcastReceiver? = null
var serviceIntent: Intent? = null

val meetingViewModel: MeetingViewModel by viewModels()
override fun onActivityResult(
    requestCode: Int,
    resultCode: Int,
    data: Intent?
) {
    super.onActivityResult(requestCode, resultCode, data)
    JitsiMeetActivityDelegate.onActivityResult(
        this, requestCode, resultCode, data
    )
}

override fun onBackPressed() {
    super.onBackPressed()
    JitsiMeetActivityDelegate.onBackPressed()
}

private fun registerCallBroadcastReceiver() {
    val intentFilter = IntentFilter()
    intentFilter.addAction("org.jitsi.meet.CONFERENCE_TERMINATED")
    intentFilter.addAction("org.jitsi.meet.PARTICIPANT_LEFT")

    callBroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val event = BroadcastEvent(intent)
            when (event.type) {
                BroadcastEvent.Type.CONFERENCE_TERMINATED -> {
                    lifecycleScope.launch {
                        endCall()
                    }
                }

                BroadcastEvent.Type.PARTICIPANT_LEFT -> {
                    [email protected](RESULT_OK)
                    finish()
                }

                else -> {}
            }
        }
    }

    LocalBroadcastManager.getInstance(this)
        .registerReceiver(callBroadcastReceiver as BroadcastReceiver, intentFilter)
}


suspend fun endCall() {
    val caseId = intent.getStringExtra("caseId")
    meetingViewModel.endMeeting(caseId).collectLatest {
        if (it.isEnded) {
            [email protected](RESULT_OK)
            finish()
        }
    }
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    view = JitsiMeetView(this)
    var options: JitsiMeetConferenceOptions? = null
    val url = intent.getStringExtra("url")
    if (url == null) {
        Toast.makeText(this, "Invalid Url", Toast.LENGTH_SHORT).show()
        finish()
        return
    }
    registerCallBroadcastReceiver()
    if (!checkPermissions()) {
        requestPermissions()
    }
    if (url.isEmpty()) {
        Toast.makeText(this, "Invalid Url", Toast.LENGTH_SHORT).show()
        finish()
    }
    val userInfo = JitsiMeetUserInfo()
    userInfo.displayName = "LifeHospital user"
    try {
        options = JitsiMeetConferenceOptions.Builder()
            .setServerURL(URL(url))
            .setAudioMuted(true)
            .setVideoMuted(true)
            .setAudioOnly(false)
            .setFeatureFlag("prejoinpage.enabled", false)
            .setFeatureFlag("welcomepage.enabled", false)
            .setFeatureFlag("requireDisplayName", false)
            .setFeatureFlag("overflow-menu.enabled", false)
            .setFeatureFlag("participants.enabled", false)
            .setFeatureFlag("participants.alwaysVisible", false)
            .setFeatureFlag("call-integration.enabled", false) // Disable call integration
            .setFeatureFlag("pip.enabled", true) // enable picture-in-picture
            .setFeatureFlag("chat.enabled", false) // Disable chat
            .setFeatureFlag("invite.enabled", false) // Disable invite options
            .setFeatureFlag("filmstrip.enabled", false)
            .setFeatureFlag("audio-only.enabled", false)
            .setFeatureFlag("notifications.enabled", false)
            .setFeatureFlag("invite.enabled", false) // Disable invite button
            .setFeatureFlag("share.enabled", false) // Disable share button
            .setFeatureFlag("settings.enabled", false) // Disable settings button
            .setFeatureFlag("settings.alwaysVisible", false) // Disable settings button
            .setFeatureFlag("toolbox.alwaysVisible", false)
            .setFeatureFlag("call-integration.enabled", false) // Disable call integration
            .setFeatureFlag("toolbox.enabled", true)
            .setFeatureFlag("recording.enabled", false)
            .setFeatureFlag("recording.alwaysVisible", false)
            .setFeatureFlag("live-streaming.enabled", false)
            .setFeatureFlag("video-share.enabled", false)
        .setRoom("OnlineLifeHospital")
            .setUserInfo(userInfo)
            .setRoom(url)
            .build()
    } catch (e: MalformedURLException) {
        throw RuntimeException(e)
    }
    view!!.join(options)
    setContentView(view)
    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

    val serviceIntent = Intent(this, CallForegroundService::class.java)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        //    startForegroundService(serviceIntent);
    }
}

private fun checkPermissions(): Boolean {
    val cameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
    val micPermission =
        ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
    return cameraPermission == PackageManager.PERMISSION_GRANTED &&
            micPermission == PackageManager.PERMISSION_GRANTED
}

private fun requestPermissions() {
    ActivityCompat.requestPermissions(
        this,
        arrayOf(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO),
        PERMISSION_REQUEST_CODE
    )

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        val permissions = arrayOf(
            Manifest.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION
        )

        ActivityCompat.requestPermissions(this, permissions, 1001)
    }
}

override fun onDestroy() {
    super.onDestroy()

    view!!.dispose()
    view = null
    if (serviceIntent != null) stopService(serviceIntent)

    finish()
    JitsiMeetActivityDelegate.onHostDestroy(this)
}

public override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    JitsiMeetActivityDelegate.onNewIntent(intent)
}

override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    JitsiMeetActivityDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults)
}

override fun onResume() {
    super.onResume()
    JitsiMeetActivityDelegate.onHostResume(this)

}

override fun onStop() {
    super.onStop()
    JitsiMeetActivityDelegate.onHostPause(this)
    finish()
}


override fun requestPermissions(
    strings: Array<String>,
    i: Int,
    permissionListener: PermissionListener
) {
}

override fun onPointerCaptureChanged(hasCapture: Boolean) {
    super.onPointerCaptureChanged(hasCapture)
}

}

@OsamaSaqrPaysky
Copy link
Author

that is crash
Caused by: androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.swmansion.rnscreens.ScreenFragment: calling Fragment constructor caused an exception
at androidx.fragment.app.Fragment.instantiate(Fragment.java:681)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:498)
at androidx.fragment.app.FragmentState.instantiate(FragmentState.java:81)
at androidx.fragment.app.FragmentStateManager.(FragmentStateManager.java:85)
at androidx.fragment.app.FragmentManager.restoreSaveStateInternal(FragmentManager.java:2496)
at androidx.fragment.app.FragmentManager.attachController(FragmentManager.java:2656)
at androidx.fragment.app.FragmentController.attachHost(FragmentController.java:117)
at androidx.fragment.app.FragmentActivity.lambda$init$3$androidx-fragment-app-FragmentActivity(FragmentActivity.java:140)
at androidx.fragment.app.FragmentActivity$$ExternalSyntheticLambda3.onContextAvailable(D8$$SyntheticClass:0)
at androidx.activity.contextaware.ContextAwareHelper.dispatchOnContextAvailable(ContextAwareHelper.kt:84)
at androidx.activity.ComponentActivity.onCreate(ComponentActivity.kt:331)
at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:217)
at org.jitsi.meet.sdk.JitsiMeetActivity.onCreate(JitsiMeetActivity.java:103)
at com.lifehospital.consultationapp.ui.Hilt_MeetingActivity.onCreate(Hilt_MeetingActivity.java:57)
at com.lifehospital.consultationapp.ui.MeetingActivity.onCreate(MeetingActivity.kt:103)
at android.app.Activity.performCreate(Activity.java:9002)
at android.app.Activity.performCreate(Activity.java:8980)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1526)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4030)
... 16 more
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
2024-12-09 19:43:01.053 16944-16944 JitsiMeetSDK com.lifehospital.consultationapp E at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at androidx.fragment.app.Fragment.instantiate(Fragment.java:663)
... 35 more
Caused by: java.lang.IllegalStateException: Screen fragments should never be restored. Follow instructions from software-mansion/react-native-screens#17 (comment) to properly configure your main activity.
at com.swmansion.rnscreens.ScreenFragment.(ScreenFragment.kt:65)
... 38 more

@saghul
Copy link
Member

saghul commented Dec 9, 2024

PlI are share a project, not just the activity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants