diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt index e20eef1e..a2c0f742 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/MainActivity.kt @@ -111,12 +111,14 @@ class MainActivity : FlutterFragmentActivity(), MethodChannel.MethodCallHandler, // start service // serviceIntent = Intent(this@MainActivity, VideoStreamContainerService::class.java) - serviceIntent = Intent(this@MainActivity, VideoStreamFloatingWidgetService::class.java) - serviceIntent?.run { - putExtras(arguments) - action = VideoStreamFloatingWidgetService.ACTION_START_CALL + if (videoStreamService == null || videoStreamService?.serviceRunning == false){ + serviceIntent = Intent(this@MainActivity, VideoStreamFloatingWidgetService::class.java) + serviceIntent?.run { + putExtras(arguments) + action = VideoStreamFloatingWidgetService.ACTION_START_CALL + } + checkFloatingWidgetPermission() } - checkFloatingWidgetPermission() } private fun checkFloatingWidgetPermission() { diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt index f79f23a4..96f0ce1f 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/Service/VideoStreamFloatingWidgetService.kt @@ -18,10 +18,7 @@ import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat import androidx.core.view.GestureDetectorCompat import com.hmg.hmgDr.R -import com.hmg.hmgDr.model.ChangeCallStatusRequestModel -import com.hmg.hmgDr.model.GetSessionStatusModel -import com.hmg.hmgDr.model.NotificationVideoModel -import com.hmg.hmgDr.model.SessionStatusModel +import com.hmg.hmgDr.model.* import com.hmg.hmgDr.ui.VideoCallContract import com.hmg.hmgDr.ui.VideoCallPresenterImpl import com.hmg.hmgDr.ui.VideoCallResponseListener @@ -115,6 +112,9 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, private var isSpeckerClicked = false private var isMicClicked = false private var elapsedTime: Long = 0 + private var formattedCallTime: String = "00:00" + private lateinit var notificationData: NotificationVideoModel + private var resume = false var isFullScreen: Boolean = true private var isCircle: Boolean = false @@ -125,7 +125,8 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, private val serviceBinder: IBinder = VideoStreamBinder() // Notification variables - private lateinit var mNotificationManagerCompat: NotificationManagerCompat + private var mNotificationManagerCompat: NotificationManagerCompat? = null + private lateinit var notificationCompatBuilder: NotificationCompat.Builder override fun onBind(intent: Intent?): IBinder { return serviceBinder @@ -180,14 +181,21 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, get() = this@VideoStreamFloatingWidgetService } - override fun onDestroy() { mWindowManager?.removeView(floatingWidgetView) // disconnectSession() - cmTimer.stop() super.onDestroy() } + private fun stopService() { + // because problem that timer still continue longer a bit than service so notification called again + mNotificationManagerCompat = null + cmTimer.stop() + stopForeground(true) + stopSelf() + + } + /* Add Floating Widget View to Window Manager */ private fun addFloatingWidgetView(inflater: LayoutInflater) { //Inflate the removing view layout we created @@ -225,7 +233,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, mWindowManager?.addView(floatingWidgetView, windowManagerParams) } - @SuppressLint("ClickableViewAccessibility") + @SuppressLint("ClickableViewAccessibility", "RestrictedApi") private fun init(view: View) { initUI(view) @@ -279,9 +287,22 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, elapsedTime += 1000 } val format = "%1$02d:%2$02d" // two digits + formattedCallTime = String.format(format, minutes, seconds) + arg0?.text = formattedCallTime - arg0?.text = String.format(format, minutes, seconds) - Log.d(TAG, "onChronometerTick: $minutes : $seconds") + try { + notificationCompatBuilder.contentView.setChronometer(R.id.notify_timer, cmTimer.base, null, true) + }catch (e : Exception){} + + // for change notification timer + if (mNotificationManagerCompat != null) { + val bigTextStyle = setNotificationBigStyle() + notificationCompatBuilder.setStyle(bigTextStyle) + mNotificationManagerCompat?.notify( + ONGOING_NOTIFICATION_ID, + notificationCompatBuilder.build() + ) + } } videoCallPresenter = VideoCallPresenterImpl(this, baseUrl) @@ -536,6 +557,9 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, } fun onMinimizedClicked() { + if (isCircle){ + onMiniCircleClicked() + } if (isFullScreen) { windowManagerParams.width = 400 windowManagerParams.height = 600 @@ -759,8 +783,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, private fun disconnectSession() { if (mSession == null) { videoCallResponseListener?.onCallFinished(Activity.RESULT_CANCELED) - stopForeground(true) - stopSelf() + stopService() return } @@ -787,8 +810,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, sessionStatusModel!!.vcid ) ) - stopForeground(true) - stopSelf() + stopService() } private fun subscribeToStream(stream: Stream) { @@ -899,8 +921,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, returnIntent.putExtra("sessionStatusNotRespond", sessionStatusModel) disconnectSession() videoCallResponseListener?.onCallFinished(Activity.RESULT_OK, returnIntent) - stopSelf() - stopForeground(true) + stopService() } } @@ -927,7 +948,7 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, private fun addForegroundService() { mNotificationManagerCompat = NotificationManagerCompat.from(applicationContext) - val areNotificationsEnabled = mNotificationManagerCompat.areNotificationsEnabled() + val areNotificationsEnabled = mNotificationManagerCompat!!.areNotificationsEnabled() if (!areNotificationsEnabled) { Toast.makeText( this, @@ -941,28 +962,33 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, generateBigTextStyleNotification() } + private fun setNotificationBigStyle(): NotificationCompat.BigTextStyle { + notificationData.mSummaryText = formattedCallTime + + return NotificationCompat.BigTextStyle() // Overrides ContentText in the big form of the template. + .bigText(notificationData.mBigText) // Overrides ContentTitle in the big form of the template. + .setBigContentTitle(notificationData.mBigContentTitle) // Summary line after the detail section in the big form of the template. + // Note: To improve readability, don't overload the user with info. If Summary Text + // doesn't add critical information, you should skip it. + .setSummaryText(notificationData.mSummaryText) + } + private fun generateBigTextStyleNotification() { - val notificationData: NotificationVideoModel = + notificationData = NotificationVideoModel( sessionStatusModel!!.patientName, "Tap to return to call", CHANNEL_DEFAULT_IMPORTANCE, CHANNEL_DEFAULT_NAME, "Video call stream background", - mSummaryText = "timer" + mSummaryText = formattedCallTime ) // 1. Create/Retrieve Notification Channel for O and beyond devices (26+). val notificationChannelId: String = NotificationUtil.createNotificationChannel(this, notificationData) // 2. Build the BIG_TEXT_STYLE. - val bigTextStyle = - NotificationCompat.BigTextStyle() // Overrides ContentText in the big form of the template. - .bigText(notificationData.mBigText) // Overrides ContentTitle in the big form of the template. - .setBigContentTitle(notificationData.mBigContentTitle) // Summary line after the detail section in the big form of the template. - // Note: To improve readability, don't overload the user with info. If Summary Text - // doesn't add critical information, you should skip it. - .setSummaryText(notificationData.mSummaryText) + val bigTextStyle = setNotificationBigStyle() // 3. Set up main Intent for notification. val pendingIntent: PendingIntent = @@ -981,20 +1007,16 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, .let { notificationIntent -> PendingIntent.getService(this, 0, notificationIntent, 0) } -// val endCallAction = NotificationCompat.Action.Builder( -// R.drawable.ic_end_call, -// "End Call", -// endCallPendingIntent -// ) -// .build() - - // 5. Build and issue the notification. - // Notification Channel Id is ignored for Android pre O (26). - + val endCallAction = NotificationCompat.Action.Builder( + R.drawable.ic_end_call, + "End Call", + endCallPendingIntent + ) + .build() // 5. Build and issue the notification. // Notification Channel Id is ignored for Android pre O (26). - val notificationCompatBuilder = notificationChannelId?.let { + notificationCompatBuilder = notificationChannelId.let { NotificationCompat.Builder( applicationContext, it ) @@ -1008,8 +1030,9 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, // notification's content mRemoteViews.setTextViewText(R.id.notify_content, notificationData.mContentText) mRemoteViews.setOnClickPendingIntent(R.id.btn_end, endCallPendingIntent) + mRemoteViews.setChronometer(R.id.notify_timer, SystemClock.elapsedRealtime(), null, false) - val notification: Notification = notificationCompatBuilder + notificationCompatBuilder // BIG_TEXT_STYLE sets title and content for API 16 (4.1 and after). .setStyle(bigTextStyle) // Title for API <16 (4.0 and below) devices. @@ -1033,10 +1056,14 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, .setPriority(notificationData.mPriority) .setVisibility(notificationData.mChannelLockscreenVisibility) // .addAction(endCallAction) - .build() + .setUsesChronometer(true) + .setWhen(elapsedTime) + .setOnlyAlertOnce(true) // This will ensure that updates to an existing notification won't sound/vibrate https://stackoverflow.com/a/52349466/6246772 - mNotificationManagerCompat.notify(ONGOING_NOTIFICATION_ID, notification) + val notification = notificationCompatBuilder + .build() + mNotificationManagerCompat!!.notify(ONGOING_NOTIFICATION_ID, notification) startForeground(ONGOING_NOTIFICATION_ID, notification) /*val notification: Notification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { Notification.Builder(this, CHANNEL_DEFAULT_IMPORTANCE) @@ -1076,7 +1103,6 @@ class VideoStreamFloatingWidgetService : Service(), Session.SessionListener, startActivity(intent) } - /** * OnTouch actions */ diff --git a/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt b/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt index 78c15a91..6b6d9217 100644 --- a/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt +++ b/android/app/src/main/kotlin/com/hmg/hmgDr/model/NotificationVideoModel.kt @@ -18,7 +18,7 @@ class NotificationVideoModel constructor( // Unique data for this Notification.Style: var mBigContentTitle: String = mContentTitle, val mBigText: String = mContentText, - val mSummaryText: String + var mSummaryText: String ) : NotificationDataModel( mContentTitle, diff --git a/android/app/src/main/res/layout/notifi_video_view.xml b/android/app/src/main/res/layout/notifi_video_view.xml index 3afd925b..cdc87a4b 100644 --- a/android/app/src/main/res/layout/notifi_video_view.xml +++ b/android/app/src/main/res/layout/notifi_video_view.xml @@ -32,17 +32,18 @@ android:textColor="@color/white" android:textSize="@dimen/text_size_small" /> - + android:format="MM:SS" + tools:text="25:45" />