Telegram - simple notifications

This commit is contained in:
crimean 2018-06-11 17:12:03 +03:00
parent b87c3a43d5
commit 52db9a54c3
13 changed files with 241 additions and 476 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -31,6 +31,8 @@
<string name="osmand_logo">OsmAnd logo</string>
<string name="install_osmand_dialog_message">You need to install free or paid version of OsmAnd first</string>
<string name="install_osmand">Install OsmAnd</string>
<string name="show_users_on_map">Show users on map</string>
<string name="active_chats">Active chats</string>
<string name="yard">yd</string>
<string name="foot">ft</string>

View file

@ -80,6 +80,8 @@ class TelegramSettings(private val app: TelegramApplication) {
fun getShareLocationChats() = ArrayList(shareLocationChats)
fun getShowOnMapChats() = ArrayList(showOnMapChats)
fun getShowOnMapChatsCount() = showOnMapChats.size
fun save() {
val prefs = app.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE)
val edit = prefs.edit()

View file

@ -1,39 +0,0 @@
package net.osmand.telegram.notifications
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.text.TextUtils
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.notifications.TelegramNotification.NotificationType
class NotificationDismissReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val helper = (context.applicationContext as TelegramApplication).notificationHelper
val notificationTypeStr = intent.extras!!.getString(NOTIFICATION_TYPE_KEY_NAME)
if (!TextUtils.isEmpty(notificationTypeStr)) {
try {
val notificationType = NotificationType.valueOf(notificationTypeStr)
helper.onNotificationDismissed(notificationType)
} catch (e: Exception) {
//ignored
}
}
}
companion object {
const val NOTIFICATION_TYPE_KEY_NAME = "net.osmand.telegram.notifications.NotificationType"
fun createIntent(context: Context, notificationType: NotificationType): PendingIntent {
val intent = Intent(context, NotificationDismissReceiver::class.java)
intent.putExtra(NOTIFICATION_TYPE_KEY_NAME, notificationType.name)
return PendingIntent.getBroadcast(context.applicationContext,
0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
}
}

View file

@ -13,56 +13,13 @@ import java.util.*
class NotificationHelper(private val app: TelegramApplication) {
private var shareLocationNotification: ShareLocationNotification? = null
private val all = ArrayList<TelegramNotification>()
init {
init()
}
private fun init() {
val shareLocationNotification = ShareLocationNotification(app)
this.shareLocationNotification = shareLocationNotification
all.add(shareLocationNotification)
}
val showLocationNotification = ShowLocationNotification(app)
fun buildTopNotification(): Notification? {
val notification = acquireTopNotification()
if (notification != null) {
removeNotification(notification.type)
setTopNotification(notification)
val notificationBuilder = notification.buildNotification(false)
return notificationBuilder?.build()
}
return null
}
private val all = listOf(shareLocationNotification, showLocationNotification)
private fun acquireTopNotification(): TelegramNotification? {
var notification: TelegramNotification? = null
if (shareLocationNotification!!.isEnabled && shareLocationNotification!!.isActive) {
notification = shareLocationNotification
}
return notification
}
fun updateTopNotification() {
val notification = acquireTopNotification()
setTopNotification(notification)
}
private fun setTopNotification(notification: TelegramNotification?) {
for (n in all) {
n.isTop = n === notification
}
}
fun showNotifications() {
if (!hasAnyTopNotification()) {
removeTopNotification()
}
for (notification in all) {
notification.showNotification()
}
fun buildNotification(telegramNotification: TelegramNotification): Notification {
return telegramNotification.buildNotification(false).build()
}
fun refreshNotification(notificationType: NotificationType) {
@ -74,53 +31,6 @@ class NotificationHelper(private val app: TelegramApplication) {
}
}
fun onNotificationDismissed(notificationType: NotificationType) {
for (notification in all) {
if (notification.type == notificationType) {
notification.onNotificationDismissed()
break
}
}
}
fun hasAnyTopNotification(): Boolean {
for (notification in all) {
if (notification.isTop) {
return true
}
}
return false
}
fun refreshNotifications() {
if (!hasAnyTopNotification()) {
removeTopNotification()
}
for (notification in all) {
notification.refreshNotification()
}
}
fun removeTopNotification() {
val notificationManager = NotificationManagerCompat.from(app)
notificationManager.cancel(TelegramNotification.TOP_NOTIFICATION_SERVICE_ID)
}
fun removeNotification(notificationType: NotificationType) {
for (notification in all) {
if (notification.type == notificationType) {
notification.removeNotification()
break
}
}
}
fun removeNotifications() {
for (notification in all) {
notification.removeNotification()
}
}
@TargetApi(26)
fun createNotificationChannel() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {

View file

@ -1,10 +1,5 @@
package net.osmand.telegram.notifications
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.support.v4.app.NotificationCompat
import android.support.v4.content.ContextCompat
import net.osmand.telegram.R
@ -15,16 +10,9 @@ import net.osmand.util.Algorithms
class ShareLocationNotification(app: TelegramApplication) : TelegramNotification(app, GROUP_NAME) {
companion object {
const val OSMAND_START_LOCATION_SHARING_SERVICE_ACTION = "osmand_start_location_sharing_service_action"
const val OSMAND_PAUSE_LOCATION_SHARING_SERVICE_ACTION = "osmand_pause_location_sharing_service_action"
const val OSMAND_STOP_LOCATION_SHARING_SERVICE_ACTION = "osmand_stop_location_sharing_service_action"
const val GROUP_NAME = "share_location"
}
private var wasNoDataDismissed: Boolean = false
private var lastBuiltNoData: Boolean = false
override val type: TelegramNotification.NotificationType
get() = TelegramNotification.NotificationType.SHARE_LOCATION
@ -40,113 +28,24 @@ class ShareLocationNotification(app: TelegramApplication) : TelegramNotification
override val isEnabled: Boolean
get() = app.settings.hasAnyChatToShareLocation()
override val osmandNotificationId: Int
override val telegramNotificationId: Int
get() = TelegramNotification.SHARE_LOCATION_NOTIFICATION_SERVICE_ID
override val osmandWearableNotificationId: Int
override val telegramWearableNotificationId: Int
get() = TelegramNotification.WEAR_SHARE_LOCATION_NOTIFICATION_SERVICE_ID
init {
app.registerReceiver(object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
app.shareLocationHelper.startSharingLocation()
}
}, IntentFilter(OSMAND_START_LOCATION_SHARING_SERVICE_ACTION))
app.registerReceiver(object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
app.shareLocationHelper.pauseSharingLocation()
}
}, IntentFilter(OSMAND_PAUSE_LOCATION_SHARING_SERVICE_ACTION))
app.registerReceiver(object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
app.shareLocationHelper.stopSharingLocation()
}
}, IntentFilter(OSMAND_STOP_LOCATION_SHARING_SERVICE_ACTION))
}
override fun onNotificationDismissed() {
if (!wasNoDataDismissed) {
wasNoDataDismissed = lastBuiltNoData
}
}
override fun buildNotification(wearable: Boolean): NotificationCompat.Builder? {
if (!isEnabled) {
return null
}
val notificationTitle: String
val notificationText: String
color = 0
override fun buildNotification(wearable: Boolean): NotificationCompat.Builder {
icon = R.drawable.ic_action_polygom_dark
val shareLocationHelper = app.shareLocationHelper
val isSharingLocation = shareLocationHelper.sharingLocation
val sharedDistance = shareLocationHelper.distance.toFloat()
ongoing = true
lastBuiltNoData = false
if (isSharingLocation) {
color = ContextCompat.getColor(app, R.color.osmand_orange)
notificationTitle = (app.getString(R.string.sharing_location) + ""
val notificationTitle = (app.getString(R.string.sharing_location) + ""
+ Algorithms.formatDuration((shareLocationHelper.duration / 1000).toInt(), true))
notificationText = (app.getString(R.string.shared_string_distance)
val notificationText = (app.getString(R.string.shared_string_distance)
+ ": " + OsmandFormatter.getFormattedDistance(sharedDistance, app))
} else {
if (sharedDistance > 0) {
notificationTitle = (app.getString(R.string.shared_string_paused) + ""
+ Algorithms.formatDuration((shareLocationHelper.duration / 1000).toInt(), true))
notificationText = (app.getString(R.string.shared_string_distance)
+ ": " + OsmandFormatter.getFormattedDistance(sharedDistance, app))
} else {
ongoing = false
notificationTitle = app.getString(R.string.share_location)
notificationText = app.getString(R.string.shared_string_no_data)
lastBuiltNoData = true
}
}
if ((wasNoDataDismissed || !app.settings.showNotificationAlways) && !ongoing) {
return null
}
val notificationBuilder = createBuilder(wearable)
return createBuilder(wearable)
.setContentTitle(notificationTitle)
.setStyle(NotificationCompat.BigTextStyle().bigText(notificationText))
val stopIntent = Intent(OSMAND_STOP_LOCATION_SHARING_SERVICE_ACTION)
val stopPendingIntent = PendingIntent.getBroadcast(app, 0, stopIntent,
PendingIntent.FLAG_UPDATE_CURRENT)
if (isSharingLocation) {
if (app.shareLocationHelper.distance > 0) {
val pauseIntent = Intent(OSMAND_PAUSE_LOCATION_SHARING_SERVICE_ACTION)
val pausePendingIntent = PendingIntent.getBroadcast(app, 0, pauseIntent,
PendingIntent.FLAG_UPDATE_CURRENT)
notificationBuilder.addAction(R.drawable.ic_pause,
app.getString(R.string.shared_string_pause), pausePendingIntent)
notificationBuilder.addAction(R.drawable.ic_action_rec_stop,
app.getString(R.string.shared_string_stop), stopPendingIntent)
} else {
notificationBuilder.addAction(R.drawable.ic_action_rec_stop,
app.getString(R.string.shared_string_stop), stopPendingIntent)
}
} else {
val startIntent = Intent(OSMAND_START_LOCATION_SHARING_SERVICE_ACTION)
val startPendingIntent = PendingIntent.getBroadcast(app, 0, startIntent,
PendingIntent.FLAG_UPDATE_CURRENT)
if (sharedDistance > 0) {
notificationBuilder.addAction(R.drawable.ic_action_rec_start,
app.getString(R.string.shared_string_continue), startPendingIntent)
notificationBuilder.addAction(R.drawable.ic_action_rec_stop,
app.getString(R.string.shared_string_stop), stopPendingIntent)
} else {
notificationBuilder.addAction(R.drawable.ic_action_rec_start,
app.getString(R.string.shared_string_start), startPendingIntent)
}
}
return notificationBuilder
}
}

View file

@ -0,0 +1,45 @@
package net.osmand.telegram.notifications
import android.support.v4.app.NotificationCompat
import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication
class ShowLocationNotification(app: TelegramApplication) : TelegramNotification(app, GROUP_NAME) {
companion object {
const val GROUP_NAME = "show_location"
}
override val type: TelegramNotification.NotificationType
get() = NotificationType.SHOW_LOCATION
override val priority: Int
get() = NotificationCompat.PRIORITY_DEFAULT
override val isActive: Boolean
get() {
val service = app.userLocationService
return isEnabled && service != null
}
override val isEnabled: Boolean
get() = app.settings.hasAnyChatToShowOnMap()
override val telegramNotificationId: Int
get() = TelegramNotification.SHOW_LOCATION_NOTIFICATION_SERVICE_ID
override val telegramWearableNotificationId: Int
get() = TelegramNotification.WEAR_SHOW_LOCATION_NOTIFICATION_SERVICE_ID
override fun buildNotification(wearable: Boolean): NotificationCompat.Builder {
val notificationTitle: String = app.getString(R.string.show_users_on_map)
val notificationText: String = app.getString(R.string.active_chats) + ": " + app.settings.getShowOnMapChatsCount()
color = 0
icon = R.drawable.ic_action_view
return createBuilder(wearable)
.setContentTitle(notificationTitle)
.setStyle(NotificationCompat.BigTextStyle().bigText(notificationText))
}
}

View file

@ -1,28 +1,34 @@
package net.osmand.telegram.notifications
import android.annotation.SuppressLint
import android.app.Notification
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.support.v4.app.NotificationCompat
import android.support.v4.app.NotificationManagerCompat
import net.osmand.telegram.MainActivity
import net.osmand.telegram.TelegramApplication
abstract class TelegramNotification(protected var app: TelegramApplication, val groupName: String) {
companion object {
const val SHARE_LOCATION_NOTIFICATION_SERVICE_ID = 6
const val SHOW_LOCATION_NOTIFICATION_SERVICE_ID = 7
const val WEAR_SHARE_LOCATION_NOTIFICATION_SERVICE_ID = 1006
const val WEAR_SHOW_LOCATION_NOTIFICATION_SERVICE_ID = 1006
}
protected var ongoing = true
protected var color: Int = 0
protected var icon: Int = 0
var isTop: Boolean = false
abstract val type: NotificationType
abstract val osmandNotificationId: Int
abstract val telegramNotificationId: Int
abstract val osmandWearableNotificationId: Int
abstract val telegramWearableNotificationId: Int
abstract val priority: Int
@ -31,7 +37,8 @@ abstract class TelegramNotification(protected var app: TelegramApplication, val
abstract val isEnabled: Boolean
enum class NotificationType {
SHARE_LOCATION
SHARE_LOCATION,
SHOW_LOCATION
}
@SuppressLint("InlinedApi")
@ -44,10 +51,9 @@ abstract class TelegramNotification(protected var app: TelegramApplication, val
}
val builder = NotificationCompat.Builder(app, NotificationHelper.NOTIFICATION_CHANEL_ID)
.setVisibility(android.support.v4.app.NotificationCompat.VISIBILITY_PUBLIC)
.setPriority(if (isTop) NotificationCompat.PRIORITY_HIGH else priority)
.setPriority(priority)
.setOngoing(ongoing && !wearable)
.setContentIntent(contentPendingIntent)
.setDeleteIntent(NotificationDismissReceiver.createIntent(app, type))
.setGroup(groupName).setGroupSummary(!wearable)
if (color != 0) {
@ -60,75 +66,25 @@ abstract class TelegramNotification(protected var app: TelegramApplication, val
return builder
}
abstract fun buildNotification(wearable: Boolean): NotificationCompat.Builder?
fun setupNotification(notification: Notification) {}
open fun onNotificationDismissed() {}
abstract fun buildNotification(wearable: Boolean): NotificationCompat.Builder
private fun notifyWearable(notificationManager: NotificationManagerCompat) {
val wearNotificationBuilder = buildNotification(true)
if (wearNotificationBuilder != null) {
val wearNotification = wearNotificationBuilder.build()
notificationManager.notify(osmandWearableNotificationId, wearNotification)
}
}
fun showNotification(): Boolean {
val notificationManager = NotificationManagerCompat.from(app)
if (isEnabled) {
val notificationBuilder = buildNotification(false)
if (notificationBuilder != null) {
val notification = notificationBuilder.build()
setupNotification(notification)
notificationManager.notify(if (isTop) TOP_NOTIFICATION_SERVICE_ID else osmandNotificationId, notification)
notifyWearable(notificationManager)
return true
}
}
return false
notificationManager.notify(telegramWearableNotificationId, wearNotification)
}
fun refreshNotification(): Boolean {
val notificationManager = NotificationManagerCompat.from(app)
if (isEnabled) {
val notificationBuilder = buildNotification(false)
if (notificationBuilder != null) {
val notification = notificationBuilder.build()
setupNotification(notification)
if (isTop) {
notificationManager.cancel(osmandNotificationId)
notificationManager.notify(TOP_NOTIFICATION_SERVICE_ID, notification)
} else {
notificationManager.notify(osmandNotificationId, notification)
}
notificationManager.notify(telegramNotificationId, notification)
notifyWearable(notificationManager)
return true
} else {
notificationManager.cancel(osmandNotificationId)
}
} else {
notificationManager.cancel(osmandNotificationId)
notificationManager.cancel(telegramNotificationId)
}
return false
}
fun removeNotification() {
val notificationManager = NotificationManagerCompat.from(app)
notificationManager.cancel(osmandNotificationId)
notificationManager.cancel(osmandWearableNotificationId)
}
fun closeSystemDialogs(context: Context) {
val it = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
context.sendBroadcast(it)
}
companion object {
const val SHARE_LOCATION_NOTIFICATION_SERVICE_ID = 6
const val TOP_NOTIFICATION_SERVICE_ID = 100
const val WEAR_SHARE_LOCATION_NOTIFICATION_SERVICE_ID = 1006
}
}

View file

@ -12,7 +12,6 @@ import android.os.Handler
import android.os.IBinder
import android.util.Log
import android.widget.Toast
import net.osmand.telegram.notifications.TelegramNotification
import net.osmand.PlatformUtil
import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication
@ -54,12 +53,10 @@ class MyLocationService : Service(), LocationListener {
Log.d(PlatformUtil.TAG, "GPS location provider not available")
}
val notification = app.notificationHelper.buildTopNotification()
if (notification != null) {
startForeground(TelegramNotification.TOP_NOTIFICATION_SERVICE_ID, notification)
app.notificationHelper.refreshNotification(TelegramNotification.NotificationType.SHARE_LOCATION)
//app.notificationHelper.refreshNotifications()
}
val shareLocationNotification = app.notificationHelper.shareLocationNotification
val notification = app.notificationHelper.buildNotification(shareLocationNotification)
startForeground(shareLocationNotification.telegramNotificationId, notification)
app.notificationHelper.refreshNotification(shareLocationNotification.type)
return Service.START_REDELIVER_INTENT
}
@ -78,12 +75,6 @@ class MyLocationService : Service(), LocationListener {
// remove notification
stopForeground(java.lang.Boolean.TRUE)
app.notificationHelper.updateTopNotification()
app.runInUIThread({
app.notificationHelper.refreshNotification(TelegramNotification.NotificationType.SHARE_LOCATION)
//app.notificationHelper.refreshNotifications()
}, 500)
}
override fun onLocationChanged(l: Location?) {
@ -105,7 +96,6 @@ class MyLocationService : Service(), LocationListener {
override fun onTaskRemoved(rootIntent: Intent) {
val app = app()
app.notificationHelper.removeNotifications()
if (app.myLocationService != null) {
// Do not stop service after UI task was dismissed
//this@MyLocationService.stopSelf()

View file

@ -9,7 +9,6 @@ import android.os.Handler
import android.os.IBinder
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.helpers.TelegramHelper.TelegramIncomingMessagesListener
import net.osmand.telegram.notifications.TelegramNotification
import org.drinkless.td.libcore.telegram.TdApi
import java.util.concurrent.Executors
@ -46,9 +45,10 @@ class UserLocationService : Service(), TelegramIncomingMessagesListener {
app.userLocationService = this
app.telegramHelper.incomingMessagesListener = this
//val notification = app.notificationHelper.buildTopNotification()
//startForeground(TelegramNotification.TOP_NOTIFICATION_SERVICE_ID, notification)
val showLocationNotification = app.notificationHelper.showLocationNotification
val notification = app.notificationHelper.buildNotification(showLocationNotification)
startForeground(showLocationNotification.telegramNotificationId, notification)
app.notificationHelper.refreshNotification(showLocationNotification.type)
return Service.START_REDELIVER_INTENT
}