Dedicated notification builder and opening map on tap of notification
This commit is contained in:
parent
e9bd271642
commit
f56c315207
|
@ -377,7 +377,7 @@
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".features.location.LocationSharingAndroidService"
|
android:name=".features.location.live.tracking.LocationSharingAndroidService"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:foregroundServiceType="location" />
|
android:foregroundServiceType="location" />
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ import im.vector.app.features.home.AvatarRenderer
|
||||||
import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider
|
import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider
|
||||||
import im.vector.app.features.location.live.LiveLocationLabsFlagPromotionBottomSheet
|
import im.vector.app.features.location.live.LiveLocationLabsFlagPromotionBottomSheet
|
||||||
import im.vector.app.features.location.live.duration.ChooseLiveDurationBottomSheet
|
import im.vector.app.features.location.live.duration.ChooseLiveDurationBottomSheet
|
||||||
|
import im.vector.app.features.location.live.tracking.LocationSharingAndroidService
|
||||||
import im.vector.app.features.location.option.LocationSharingOption
|
import im.vector.app.features.location.option.LocationSharingOption
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import org.matrix.android.sdk.api.util.MatrixItem
|
import org.matrix.android.sdk.api.util.MatrixItem
|
||||||
|
|
|
@ -22,6 +22,7 @@ import android.content.Intent
|
||||||
import android.content.ServiceConnection
|
import android.content.ServiceConnection
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
|
import im.vector.app.features.location.live.tracking.LocationSharingAndroidService
|
||||||
import im.vector.app.features.session.coroutineScope
|
import im.vector.app.features.session.coroutineScope
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
|
|
@ -24,6 +24,7 @@ import im.vector.app.R
|
||||||
import im.vector.app.core.extensions.addFragment
|
import im.vector.app.core.extensions.addFragment
|
||||||
import im.vector.app.core.platform.VectorBaseActivity
|
import im.vector.app.core.platform.VectorBaseActivity
|
||||||
import im.vector.app.databinding.ActivityLocationSharingBinding
|
import im.vector.app.databinding.ActivityLocationSharingBinding
|
||||||
|
import im.vector.app.features.MainActivity
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
|
@ -59,10 +60,15 @@ class LocationLiveMapViewActivity : VectorBaseActivity<ActivityLocationSharingBi
|
||||||
|
|
||||||
private const val EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS = "EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS"
|
private const val EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS = "EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS"
|
||||||
|
|
||||||
fun getIntent(context: Context, locationLiveMapViewArgs: LocationLiveMapViewArgs): Intent {
|
fun getIntent(context: Context, locationLiveMapViewArgs: LocationLiveMapViewArgs, firstStartMainActivity: Boolean = false): Intent {
|
||||||
return Intent(context, LocationLiveMapViewActivity::class.java).apply {
|
val intent = Intent(context, LocationLiveMapViewActivity::class.java).apply {
|
||||||
putExtra(EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS, locationLiveMapViewArgs)
|
putExtra(EXTRA_LOCATION_LIVE_MAP_VIEW_ARGS, locationLiveMapViewArgs)
|
||||||
}
|
}
|
||||||
|
return if (firstStartMainActivity) {
|
||||||
|
MainActivity.getIntentWithNextIntent(context, intent)
|
||||||
|
} else {
|
||||||
|
intent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.location.live.tracking
|
||||||
|
|
||||||
|
import android.app.Notification
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.TaskStackBuilder
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.core.extensions.createIgnoredUri
|
||||||
|
import im.vector.app.core.platform.PendingIntentCompat
|
||||||
|
import im.vector.app.core.resources.StringProvider
|
||||||
|
import im.vector.app.core.time.Clock
|
||||||
|
import im.vector.app.features.home.HomeActivity
|
||||||
|
import im.vector.app.features.home.room.detail.RoomDetailActivity
|
||||||
|
import im.vector.app.features.home.room.detail.arguments.TimelineArgs
|
||||||
|
import im.vector.app.features.location.live.map.LocationLiveMapViewActivity
|
||||||
|
import im.vector.app.features.location.live.map.LocationLiveMapViewArgs
|
||||||
|
import im.vector.app.features.notifications.NotificationUtils
|
||||||
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class LiveLocationNotificationBuilder @Inject constructor(
|
||||||
|
private val context: Context,
|
||||||
|
private val stringProvider: StringProvider,
|
||||||
|
private val clock: Clock,
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a notification that indicates the application is retrieving location even if it is in background or killed.
|
||||||
|
* @param roomId the id of the room where a live location is shared
|
||||||
|
*/
|
||||||
|
fun buildLiveLocationSharingNotification(roomId: String): Notification {
|
||||||
|
return NotificationCompat.Builder(context, NotificationUtils.SILENT_NOTIFICATION_CHANNEL_ID)
|
||||||
|
.setContentTitle(stringProvider.getString(R.string.live_location_sharing_notification_title))
|
||||||
|
.setContentText(stringProvider.getString(R.string.live_location_sharing_notification_description))
|
||||||
|
.setSmallIcon(R.drawable.ic_attachment_location_live_white)
|
||||||
|
.setColor(ThemeUtils.getColor(context, android.R.attr.colorPrimary))
|
||||||
|
.setCategory(NotificationCompat.CATEGORY_LOCATION_SHARING)
|
||||||
|
.setContentIntent(buildOpenLiveLocationMapIntent(roomId))
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildOpenLiveLocationMapIntent(roomId: String): PendingIntent? {
|
||||||
|
val homeIntent = HomeActivity.newIntent(context, firstStartMainActivity = false)
|
||||||
|
val roomIntent = RoomDetailActivity.newIntent(context, TimelineArgs(roomId = roomId, switchToParentSpace = true), firstStartMainActivity = false)
|
||||||
|
val mapIntent = LocationLiveMapViewActivity.getIntent(
|
||||||
|
context = context,
|
||||||
|
locationLiveMapViewArgs = LocationLiveMapViewArgs(roomId = roomId),
|
||||||
|
firstStartMainActivity = true
|
||||||
|
)
|
||||||
|
mapIntent.action = NotificationUtils.TAP_TO_VIEW_ACTION
|
||||||
|
// pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that
|
||||||
|
mapIntent.data = createIgnoredUri("openLiveLocationMap?$roomId")
|
||||||
|
|
||||||
|
// Recreate the back stack
|
||||||
|
return TaskStackBuilder.create(context)
|
||||||
|
.addNextIntentWithParentStack(homeIntent)
|
||||||
|
.addNextIntent(roomIntent)
|
||||||
|
.addNextIntent(mapIntent)
|
||||||
|
.getPendingIntent(
|
||||||
|
clock.epochMillis().toInt(),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.app.features.location
|
package im.vector.app.features.location.live.tracking
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Binder
|
import android.os.Binder
|
||||||
|
@ -24,8 +24,9 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.services.VectorAndroidService
|
import im.vector.app.core.services.VectorAndroidService
|
||||||
|
import im.vector.app.features.location.LocationData
|
||||||
|
import im.vector.app.features.location.LocationTracker
|
||||||
import im.vector.app.features.location.live.GetLiveLocationShareSummaryUseCase
|
import im.vector.app.features.location.live.GetLiveLocationShareSummaryUseCase
|
||||||
import im.vector.app.features.notifications.NotificationUtils
|
|
||||||
import im.vector.app.features.redaction.CheckIfEventIsRedactedUseCase
|
import im.vector.app.features.redaction.CheckIfEventIsRedactedUseCase
|
||||||
import im.vector.app.features.session.coroutineScope
|
import im.vector.app.features.session.coroutineScope
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
@ -54,7 +55,7 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca
|
||||||
val durationMillis: Long
|
val durationMillis: Long
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
|
|
||||||
@Inject lateinit var notificationUtils: NotificationUtils
|
@Inject lateinit var liveLocationNotificationBuilder: LiveLocationNotificationBuilder
|
||||||
@Inject lateinit var locationTracker: LocationTracker
|
@Inject lateinit var locationTracker: LocationTracker
|
||||||
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
|
@Inject lateinit var activeSessionHolder: ActiveSessionHolder
|
||||||
@Inject lateinit var getLiveLocationShareSummaryUseCase: GetLiveLocationShareSummaryUseCase
|
@Inject lateinit var getLiveLocationShareSummaryUseCase: GetLiveLocationShareSummaryUseCase
|
||||||
|
@ -102,7 +103,7 @@ class LocationSharingAndroidService : VectorAndroidService(), LocationTracker.Ca
|
||||||
|
|
||||||
if (roomArgs != null) {
|
if (roomArgs != null) {
|
||||||
// Show a sticky notification
|
// Show a sticky notification
|
||||||
val notification = notificationUtils.buildLiveLocationSharingNotification()
|
val notification = liveLocationNotificationBuilder.buildLiveLocationSharingNotification(roomArgs.roomId)
|
||||||
startForeground(roomArgs.roomId.hashCode(), notification)
|
startForeground(roomArgs.roomId.hashCode(), notification)
|
||||||
|
|
||||||
// Send beacon info state event
|
// Send beacon info state event
|
|
@ -105,7 +105,7 @@ class NotificationUtils @Inject constructor(
|
||||||
const val SMART_REPLY_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.SMART_REPLY_ACTION"
|
const val SMART_REPLY_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.SMART_REPLY_ACTION"
|
||||||
const val DISMISS_SUMMARY_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.DISMISS_SUMMARY_ACTION"
|
const val DISMISS_SUMMARY_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.DISMISS_SUMMARY_ACTION"
|
||||||
const val DISMISS_ROOM_NOTIF_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.DISMISS_ROOM_NOTIF_ACTION"
|
const val DISMISS_ROOM_NOTIF_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.DISMISS_ROOM_NOTIF_ACTION"
|
||||||
private const val TAP_TO_VIEW_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.TAP_TO_VIEW_ACTION"
|
const val TAP_TO_VIEW_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.TAP_TO_VIEW_ACTION"
|
||||||
const val DIAGNOSTIC_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.DIAGNOSTIC"
|
const val DIAGNOSTIC_ACTION = "${BuildConfig.APPLICATION_ID}.NotificationActions.DIAGNOSTIC"
|
||||||
const val PUSH_ACTION = "${BuildConfig.APPLICATION_ID}.PUSH"
|
const val PUSH_ACTION = "${BuildConfig.APPLICATION_ID}.PUSH"
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ class NotificationUtils @Inject constructor(
|
||||||
|
|
||||||
private const val NOISY_NOTIFICATION_CHANNEL_ID = "DEFAULT_NOISY_NOTIFICATION_CHANNEL_ID"
|
private const val NOISY_NOTIFICATION_CHANNEL_ID = "DEFAULT_NOISY_NOTIFICATION_CHANNEL_ID"
|
||||||
|
|
||||||
private const val SILENT_NOTIFICATION_CHANNEL_ID = "DEFAULT_SILENT_NOTIFICATION_CHANNEL_ID_V2"
|
const val SILENT_NOTIFICATION_CHANNEL_ID = "DEFAULT_SILENT_NOTIFICATION_CHANNEL_ID_V2"
|
||||||
private const val CALL_NOTIFICATION_CHANNEL_ID = "CALL_NOTIFICATION_CHANNEL_ID_V2"
|
private const val CALL_NOTIFICATION_CHANNEL_ID = "CALL_NOTIFICATION_CHANNEL_ID_V2"
|
||||||
|
|
||||||
fun supportNotificationChannels() = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
fun supportNotificationChannels() = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||||
|
@ -540,20 +540,6 @@ class NotificationUtils @Inject constructor(
|
||||||
return builder.build()
|
return builder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a notification that indicates the application is retrieving location even if it is in background or killed.
|
|
||||||
*/
|
|
||||||
fun buildLiveLocationSharingNotification(): Notification {
|
|
||||||
return NotificationCompat.Builder(context, SILENT_NOTIFICATION_CHANNEL_ID)
|
|
||||||
.setContentTitle(stringProvider.getString(R.string.live_location_sharing_notification_title))
|
|
||||||
.setContentText(stringProvider.getString(R.string.live_location_sharing_notification_description))
|
|
||||||
.setSmallIcon(R.drawable.ic_attachment_location_live_white)
|
|
||||||
.setColor(ThemeUtils.getColor(context, android.R.attr.colorPrimary))
|
|
||||||
.setCategory(NotificationCompat.CATEGORY_LOCATION_SHARING)
|
|
||||||
.setContentIntent(buildOpenHomePendingIntentForSummary())
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a notification that indicates the application is capturing the screen.
|
* Creates a notification that indicates the application is capturing the screen.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue