mirror of
https://github.com/nextcloud/talk-android.git
synced 2024-11-23 05:25:31 +03:00
Merge pull request #2566 from nextcloud/bugfix/1724followup/improveNotificationSoundHandling
Bugfix/1724followup/improve notification sound handling
This commit is contained in:
commit
25c7d76ec9
6 changed files with 114 additions and 292 deletions
|
@ -22,22 +22,16 @@
|
|||
package com.nextcloud.talk.activities
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Notification
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.media.AudioAttributes
|
||||
import android.media.MediaPlayer
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.SystemClock
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import autodagger.AutoInjector
|
||||
import com.nextcloud.talk.R
|
||||
import com.nextcloud.talk.api.NcApi
|
||||
|
@ -49,11 +43,8 @@ import com.nextcloud.talk.extensions.loadAvatar
|
|||
import com.nextcloud.talk.models.json.conversations.Conversation
|
||||
import com.nextcloud.talk.models.json.conversations.RoomOverall
|
||||
import com.nextcloud.talk.models.json.participants.Participant
|
||||
import com.nextcloud.talk.models.json.participants.ParticipantsOverall
|
||||
import com.nextcloud.talk.utils.ApiUtils
|
||||
import com.nextcloud.talk.utils.DoNotDisturbUtils.shouldPlaySound
|
||||
import com.nextcloud.talk.utils.NotificationUtils
|
||||
import com.nextcloud.talk.utils.NotificationUtils.getCallRingtoneUri
|
||||
import com.nextcloud.talk.utils.ParticipantPermissions
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CALL_VOICE_ONLY
|
||||
|
@ -62,7 +53,6 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM
|
|||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
|
||||
import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew.hasSpreedFeatureCapability
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Observer
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
|
@ -71,7 +61,6 @@ import kotlinx.android.synthetic.main.call_item.*
|
|||
import okhttp3.Cache
|
||||
import org.parceler.Parcels
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
@SuppressLint("LongLogTag")
|
||||
|
@ -88,13 +77,14 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||
private val disposablesList: MutableList<Disposable> = ArrayList()
|
||||
private var originalBundle: Bundle? = null
|
||||
private var roomToken: String? = null
|
||||
private var notificationTimestamp: Int? = null
|
||||
private var userBeingCalled: User? = null
|
||||
private var credentials: String? = null
|
||||
private var currentConversation: Conversation? = null
|
||||
private var mediaPlayer: MediaPlayer? = null
|
||||
private var leavingScreen = false
|
||||
private var handler: Handler? = null
|
||||
private var binding: CallNotificationActivityBinding? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
Log.d(TAG, "onCreate")
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -104,6 +94,7 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||
hideNavigationIfNoPipAvailable()
|
||||
val extras = intent.extras
|
||||
roomToken = extras!!.getString(KEY_ROOM_TOKEN, "")
|
||||
notificationTimestamp = extras.getInt(BundleKeys.KEY_NOTIFICATION_TIMESTAMP)
|
||||
currentConversation = Parcels.unwrap(extras.getParcelable(KEY_ROOM))
|
||||
userBeingCalled = extras.getParcelable(KEY_USER_ENTITY)
|
||||
originalBundle = extras
|
||||
|
@ -114,9 +105,6 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||
} else {
|
||||
setUpAfterConversationIsKnown()
|
||||
}
|
||||
if (shouldPlaySound()) {
|
||||
playRingtoneSound()
|
||||
}
|
||||
initClickListeners()
|
||||
}
|
||||
|
||||
|
@ -162,7 +150,6 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||
private fun hangup() {
|
||||
leavingScreen = true
|
||||
dispose()
|
||||
endMediaNotifications()
|
||||
finish()
|
||||
}
|
||||
|
||||
|
@ -188,108 +175,6 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||
startActivity(intent)
|
||||
}
|
||||
|
||||
private fun checkIfAnyParticipantsRemainInRoom() {
|
||||
val apiVersion = ApiUtils.getCallApiVersion(userBeingCalled, intArrayOf(ApiUtils.APIv4, 1))
|
||||
ncApi!!.getPeersForCall(
|
||||
credentials,
|
||||
ApiUtils.getUrlForCall(
|
||||
apiVersion,
|
||||
userBeingCalled!!.baseUrl,
|
||||
currentConversation!!.token
|
||||
)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.repeatWhen { completed: Observable<Any?> ->
|
||||
completed.zipWith(Observable.range(TIMER_START, TIMER_COUNT)) { _: Any?, i: Int? -> i!! }
|
||||
.flatMap { Observable.timer(TIMER_DELAY, TimeUnit.SECONDS) }
|
||||
.takeWhile { !leavingScreen }
|
||||
}
|
||||
.subscribe(object : Observer<ParticipantsOverall> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
disposablesList.add(d)
|
||||
}
|
||||
|
||||
override fun onNext(participantsOverall: ParticipantsOverall) {
|
||||
val hasParticipantsInCall: Boolean
|
||||
var inCallOnDifferentDevice = false
|
||||
val participantList = participantsOverall.ocs!!.data
|
||||
hasParticipantsInCall = participantList!!.isNotEmpty()
|
||||
if (hasParticipantsInCall) {
|
||||
for (participant in participantList) {
|
||||
if (participant.calculatedActorType === Participant.ActorType.USERS &&
|
||||
participant.calculatedActorId == userBeingCalled!!.userId
|
||||
) {
|
||||
inCallOnDifferentDevice = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inCallOnDifferentDevice) {
|
||||
runOnUiThread { hangup() }
|
||||
}
|
||||
if (!hasParticipantsInCall) {
|
||||
showMissedCallNotification()
|
||||
runOnUiThread { hangup() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Log.e(TAG, "error while getPeersForCall", e)
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
showMissedCallNotification()
|
||||
runOnUiThread { hangup() }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun showMissedCallNotification() {
|
||||
val mNotifyManager: NotificationManager?
|
||||
val mBuilder: NotificationCompat.Builder?
|
||||
|
||||
mNotifyManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
mBuilder = NotificationCompat.Builder(
|
||||
context,
|
||||
NotificationUtils.NotificationChannels
|
||||
.NOTIFICATION_CHANNEL_MESSAGES_V4.name
|
||||
)
|
||||
|
||||
val notification: Notification = mBuilder
|
||||
.setContentTitle(
|
||||
String.format(resources.getString(R.string.nc_missed_call), currentConversation!!.displayName)
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_baseline_phone_missed_24)
|
||||
.setOngoing(false)
|
||||
.setAutoCancel(true)
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
.setContentIntent(getIntentToOpenConversation())
|
||||
.build()
|
||||
|
||||
val notificationId: Int = SystemClock.uptimeMillis().toInt()
|
||||
mNotifyManager.notify(notificationId, notification)
|
||||
}
|
||||
|
||||
private fun getIntentToOpenConversation(): PendingIntent? {
|
||||
val bundle = Bundle()
|
||||
val intent = Intent(context, MainActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
|
||||
bundle.putString(KEY_ROOM_TOKEN, currentConversation?.token)
|
||||
bundle.putParcelable(KEY_USER_ENTITY, userBeingCalled)
|
||||
bundle.putBoolean(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL, false)
|
||||
|
||||
intent.putExtras(bundle)
|
||||
|
||||
val requestCode = System.currentTimeMillis().toInt()
|
||||
val intentFlag: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
PendingIntent.FLAG_MUTABLE
|
||||
} else {
|
||||
0
|
||||
}
|
||||
return PendingIntent.getActivity(context, requestCode, intent, intentFlag)
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private fun handleFromNotification() {
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(
|
||||
|
@ -353,18 +238,25 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||
} else {
|
||||
binding!!.avatarImageView.setImageResource(R.drawable.ic_circular_group)
|
||||
}
|
||||
checkIfAnyParticipantsRemainInRoom()
|
||||
|
||||
val notificationHandler = Handler(Looper.getMainLooper())
|
||||
notificationHandler.post(object : Runnable {
|
||||
override fun run() {
|
||||
if (NotificationUtils.isNotificationVisible(context, notificationTimestamp!!.toInt())) {
|
||||
notificationHandler.postDelayed(this, 1000)
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
showAnswerControls()
|
||||
}
|
||||
|
||||
private fun endMediaNotifications() {
|
||||
if (mediaPlayer != null) {
|
||||
if (mediaPlayer!!.isPlaying) {
|
||||
mediaPlayer!!.stop()
|
||||
}
|
||||
mediaPlayer!!.release()
|
||||
mediaPlayer = null
|
||||
}
|
||||
override fun onStop() {
|
||||
val notificationManager = NotificationManagerCompat.from(context)
|
||||
notificationManager.cancel(notificationTimestamp!!)
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
public override fun onDestroy() {
|
||||
|
@ -374,7 +266,6 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||
handler = null
|
||||
}
|
||||
dispose()
|
||||
endMediaNotifications()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
@ -386,26 +277,6 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun playRingtoneSound() {
|
||||
val ringtoneUri = getCallRingtoneUri(applicationContext, appPreferences)
|
||||
if (ringtoneUri != null) {
|
||||
mediaPlayer = MediaPlayer()
|
||||
try {
|
||||
mediaPlayer!!.setDataSource(this, ringtoneUri)
|
||||
mediaPlayer!!.isLooping = true
|
||||
val audioAttributes = AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
||||
.build()
|
||||
mediaPlayer!!.setAudioAttributes(audioAttributes)
|
||||
mediaPlayer!!.setOnPreparedListener { mediaPlayer!!.start() }
|
||||
mediaPlayer!!.prepareAsync()
|
||||
} catch (e: IOException) {
|
||||
Log.e(TAG, "Failed to set data source")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration) {
|
||||
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
|
||||
|
@ -433,9 +304,6 @@ class CallNotificationActivity : CallBaseActivity() {
|
|||
|
||||
companion object {
|
||||
const val TAG = "CallNotificationActivity"
|
||||
const val TIMER_START = 1
|
||||
const val TIMER_COUNT = 12
|
||||
const val TIMER_DELAY: Long = 5
|
||||
const val GET_ROOM_RETRY_COUNT: Long = 3
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,10 +24,8 @@
|
|||
package com.nextcloud.talk.jobs
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Context.NOTIFICATION_SERVICE
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.media.AudioAttributes
|
||||
|
@ -85,6 +83,7 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FROM_NOTIFICATION_START_CA
|
|||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_INTERNAL_USER_ID
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_MESSAGE_ID
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_ID
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_NOTIFICATION_TIMESTAMP
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SYSTEM_NOTIFICATION_ID
|
||||
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
|
||||
|
@ -212,6 +211,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
val fullScreenIntent = Intent(context, CallNotificationActivity::class.java)
|
||||
val bundle = Bundle()
|
||||
bundle.putString(KEY_ROOM_TOKEN, pushMessage.id)
|
||||
bundle.putInt(KEY_NOTIFICATION_TIMESTAMP, pushMessage.timestamp.toInt())
|
||||
bundle.putParcelable(KEY_USER_ENTITY, signatureVerification.user)
|
||||
bundle.putBoolean(KEY_FROM_NOTIFICATION_START_CALL, true)
|
||||
fullScreenIntent.putExtras(bundle)
|
||||
|
@ -231,8 +231,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
)
|
||||
|
||||
val soundUri = getCallRingtoneUri(applicationContext, appPreferences)
|
||||
val notificationChannelId = NotificationUtils
|
||||
.NotificationChannels.NOTIFICATION_CHANNEL_CALLS_V4.name
|
||||
val notificationChannelId = NotificationUtils.NotificationChannels.NOTIFICATION_CHANNEL_CALLS_V4.name
|
||||
val uri = Uri.parse(signatureVerification.user!!.baseUrl)
|
||||
val baseUrl = uri.host
|
||||
|
||||
|
@ -245,7 +244,9 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
.setShowWhen(true)
|
||||
.setWhen(pushMessage.timestamp)
|
||||
.setContentTitle(EmojiCompat.get().process(pushMessage.subject))
|
||||
.setAutoCancel(true)
|
||||
// auto cancel is set to false because notification (including sound) should continue while
|
||||
// CallNotificationActivity is active
|
||||
.setAutoCancel(false)
|
||||
.setOngoing(true)
|
||||
.setContentIntent(fullScreenPendingIntent)
|
||||
.setFullScreenIntent(fullScreenPendingIntent, true)
|
||||
|
@ -255,7 +256,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
|
||||
sendNotification(pushMessage.timestamp.toInt(), notification)
|
||||
|
||||
checkIfCallIsActive(signatureVerification, pushMessage)
|
||||
checkIfCallIsActive(signatureVerification)
|
||||
}
|
||||
|
||||
private fun initNcApiAndCredentials() {
|
||||
|
@ -660,10 +661,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
notificationManager.cancel(notificationId)
|
||||
}
|
||||
|
||||
private fun checkIfCallIsActive(
|
||||
signatureVerification: SignatureVerification,
|
||||
decryptedPushMessage: DecryptedPushMessage
|
||||
) {
|
||||
private fun checkIfCallIsActive(signatureVerification: SignatureVerification) {
|
||||
Log.d(TAG, "checkIfCallIsActive")
|
||||
var hasParticipantsInCall = true
|
||||
var inCallOnDifferentDevice = false
|
||||
|
@ -680,7 +678,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
ApiUtils.getUrlForCall(
|
||||
apiVersion,
|
||||
signatureVerification.user!!.baseUrl,
|
||||
decryptedPushMessage.id
|
||||
pushMessage.id
|
||||
)
|
||||
)
|
||||
.repeatWhen { completed ->
|
||||
|
@ -707,16 +705,19 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
}
|
||||
if (inCallOnDifferentDevice) {
|
||||
Log.d(TAG, "inCallOnDifferentDevice is true")
|
||||
removeNotification(decryptedPushMessage.timestamp.toInt())
|
||||
removeNotification(pushMessage.timestamp.toInt())
|
||||
}
|
||||
|
||||
if (!hasParticipantsInCall) {
|
||||
showMissedCallNotification()
|
||||
Log.d(TAG, "no participants in call")
|
||||
removeNotification(decryptedPushMessage.timestamp.toInt())
|
||||
removeNotification(pushMessage.timestamp.toInt())
|
||||
}
|
||||
|
||||
isCallNotificationVisible = isCallNotificationVisible(decryptedPushMessage)
|
||||
isCallNotificationVisible = NotificationUtils.isNotificationVisible(
|
||||
context,
|
||||
pushMessage.timestamp.toInt()
|
||||
)
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
|
@ -730,71 +731,78 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
showMissedCallNotification()
|
||||
}
|
||||
|
||||
removeNotification(decryptedPushMessage.timestamp.toInt())
|
||||
removeNotification(pushMessage.timestamp.toInt())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun showMissedCallNotification() {
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(
|
||||
signatureVerification.user,
|
||||
intArrayOf(
|
||||
ApiUtils.APIv4,
|
||||
ApiUtils.APIv3, 1
|
||||
)
|
||||
val isOngoingCallNotificationVisible = NotificationUtils.isNotificationVisible(
|
||||
context,
|
||||
pushMessage.timestamp.toInt()
|
||||
)
|
||||
ncApi.getRoom(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoom(
|
||||
apiVersion, signatureVerification.user?.baseUrl,
|
||||
pushMessage.id
|
||||
|
||||
if (isOngoingCallNotificationVisible) {
|
||||
val apiVersion = ApiUtils.getConversationApiVersion(
|
||||
signatureVerification.user,
|
||||
intArrayOf(
|
||||
ApiUtils.APIv4,
|
||||
ApiUtils.APIv3, 1
|
||||
)
|
||||
)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.retry(GET_ROOM_RETRY_COUNT)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Observer<RoomOverall> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
// unused atm
|
||||
}
|
||||
ncApi.getRoom(
|
||||
credentials,
|
||||
ApiUtils.getUrlForRoom(
|
||||
apiVersion, signatureVerification.user?.baseUrl,
|
||||
pushMessage.id
|
||||
)
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.retry(GET_ROOM_RETRY_COUNT)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Observer<RoomOverall> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
// unused atm
|
||||
}
|
||||
|
||||
override fun onNext(roomOverall: RoomOverall) {
|
||||
val currentConversation = roomOverall.ocs!!.data
|
||||
val notificationBuilder: NotificationCompat.Builder?
|
||||
override fun onNext(roomOverall: RoomOverall) {
|
||||
val currentConversation = roomOverall.ocs!!.data
|
||||
val notificationBuilder: NotificationCompat.Builder?
|
||||
|
||||
notificationBuilder = NotificationCompat.Builder(
|
||||
context!!,
|
||||
NotificationUtils.NotificationChannels
|
||||
.NOTIFICATION_CHANNEL_MESSAGES_V4.name
|
||||
)
|
||||
|
||||
val notification: Notification = notificationBuilder
|
||||
.setContentTitle(
|
||||
String.format(
|
||||
context!!.resources.getString(R.string.nc_missed_call),
|
||||
currentConversation!!.displayName
|
||||
)
|
||||
notificationBuilder = NotificationCompat.Builder(
|
||||
context!!,
|
||||
NotificationUtils.NotificationChannels
|
||||
.NOTIFICATION_CHANNEL_MESSAGES_V4.name
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_baseline_phone_missed_24)
|
||||
.setOngoing(false)
|
||||
.setAutoCancel(true)
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
.setContentIntent(getIntentToOpenConversation())
|
||||
.build()
|
||||
|
||||
val notificationId: Int = SystemClock.uptimeMillis().toInt()
|
||||
notificationManager.notify(notificationId, notification)
|
||||
Log.d(TAG, "'you missed a call' notification was created")
|
||||
}
|
||||
val notification: Notification = notificationBuilder
|
||||
.setContentTitle(
|
||||
String.format(
|
||||
context!!.resources.getString(R.string.nc_missed_call),
|
||||
currentConversation!!.displayName
|
||||
)
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_baseline_phone_missed_24)
|
||||
.setOngoing(false)
|
||||
.setAutoCancel(true)
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
.setContentIntent(getIntentToOpenConversation())
|
||||
.build()
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
Log.e(TAG, "An error occurred while fetching room for the 'missed call' notification", e)
|
||||
}
|
||||
val notificationId: Int = SystemClock.uptimeMillis().toInt()
|
||||
notificationManager.notify(notificationId, notification)
|
||||
Log.d(TAG, "'you missed a call' notification was created")
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
// unused atm
|
||||
}
|
||||
})
|
||||
override fun onError(e: Throwable) {
|
||||
Log.e(TAG, "An error occurred while fetching room for the 'missed call' notification", e)
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
// unused atm
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun getIntentToOpenConversation(): PendingIntent? {
|
||||
|
@ -817,20 +825,6 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||
return PendingIntent.getActivity(context, requestCode, intent, intentFlag)
|
||||
}
|
||||
|
||||
private fun isCallNotificationVisible(decryptedPushMessage: DecryptedPushMessage): Boolean {
|
||||
var isVisible = false
|
||||
|
||||
val notificationManager = context!!.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
||||
val notifications = notificationManager.activeNotifications
|
||||
for (notification in notifications) {
|
||||
if (notification.id == decryptedPushMessage.timestamp.toInt()) {
|
||||
isVisible = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return isVisible
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG = NotificationWorker::class.simpleName
|
||||
private const val CHAT = "chat"
|
||||
|
|
|
@ -25,7 +25,6 @@ import android.app.NotificationManager
|
|||
import android.content.Context
|
||||
import android.media.AudioManager
|
||||
import android.os.Build
|
||||
import android.os.Vibrator
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.nextcloud.talk.application.NextcloudTalkApplication
|
||||
|
||||
|
@ -60,28 +59,4 @@ object DoNotDisturbUtils {
|
|||
|
||||
return shouldPlaySound
|
||||
}
|
||||
|
||||
private fun hasVibrator(context: Context?): Boolean {
|
||||
val vibrator = context?.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
|
||||
return vibrator.hasVibrator()
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun shouldVibrate(
|
||||
context: Context? = NextcloudTalkApplication.sharedApplication?.applicationContext,
|
||||
vibrate: Boolean
|
||||
): Boolean {
|
||||
|
||||
if (hasVibrator(context)) {
|
||||
val audioManager = context?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
|
||||
return if (vibrate) {
|
||||
audioManager.ringerMode != AudioManager.RINGER_MODE_SILENT
|
||||
} else {
|
||||
audioManager.ringerMode == AudioManager.RINGER_MODE_VIBRATE
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -274,6 +274,24 @@ object NotificationUtils {
|
|||
}
|
||||
}
|
||||
|
||||
fun isNotificationVisible(
|
||||
context: Context?,
|
||||
notificationId: Int
|
||||
): Boolean {
|
||||
|
||||
var isVisible = false
|
||||
|
||||
val notificationManager = context!!.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
val notifications = notificationManager.activeNotifications
|
||||
for (notification in notifications) {
|
||||
if (notification.id == notificationId) {
|
||||
isVisible = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return isVisible
|
||||
}
|
||||
|
||||
private fun getRingtoneUri(
|
||||
context: Context,
|
||||
ringtonePreferencesString: String?,
|
||||
|
|
|
@ -66,6 +66,7 @@ object BundleKeys {
|
|||
const val KEY_ACCOUNT = "KEY_ACCOUNT"
|
||||
const val KEY_FILE_ID = "KEY_FILE_ID"
|
||||
const val KEY_NOTIFICATION_ID = "KEY_NOTIFICATION_ID"
|
||||
const val KEY_NOTIFICATION_TIMESTAMP = "KEY_NOTIFICATION_TIMESTAMP"
|
||||
const val KEY_SHARED_TEXT = "KEY_SHARED_TEXT"
|
||||
const val KEY_GEOCODING_QUERY = "KEY_GEOCODING_QUERY"
|
||||
const val KEY_META_DATA = "KEY_META_DATA"
|
||||
|
|
|
@ -24,7 +24,6 @@ import android.app.NotificationManager;
|
|||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Build;
|
||||
import android.os.Vibrator;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -32,7 +31,6 @@ import org.mockito.Mock;
|
|||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class DoNotDisturbUtilsTest {
|
||||
|
@ -46,18 +44,14 @@ public class DoNotDisturbUtilsTest {
|
|||
@Mock
|
||||
private AudioManager audioManager;
|
||||
|
||||
@Mock
|
||||
private Vibrator vibrator;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
when(context.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(notificationManager);
|
||||
when(context.getSystemService(Context.AUDIO_SERVICE)).thenReturn(audioManager);
|
||||
when(context.getSystemService(Context.VIBRATOR_SERVICE)).thenReturn(vibrator);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void shouldPlaySound_givenAndroidMAndInterruptionFilterNone_assertReturnsFalse() {
|
||||
DoNotDisturbUtils.INSTANCE.setTestingBuildVersion(Build.VERSION_CODES.M);
|
||||
|
@ -77,32 +71,4 @@ public class DoNotDisturbUtilsTest {
|
|||
assertFalse("shouldPlaySound incorrectly returned true",
|
||||
DoNotDisturbUtils.INSTANCE.shouldPlaySound(context));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrate_givenNoVibrator_assertReturnsFalse() {
|
||||
when(vibrator.hasVibrator()).thenReturn(false);
|
||||
|
||||
assertFalse("shouldVibrate returned true despite no vibrator",
|
||||
DoNotDisturbUtils.INSTANCE.shouldVibrate(context, true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrate_givenVibratorAndRingerModeNormal_assertReturnsTrue() {
|
||||
when(vibrator.hasVibrator()).thenReturn(true);
|
||||
|
||||
when(audioManager.getRingerMode()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
|
||||
|
||||
assertTrue("shouldVibrate incorrectly returned false",
|
||||
DoNotDisturbUtils.INSTANCE.shouldVibrate(context, true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldVibrate_givenVibratorAndRingerModeSilent_assertReturnsFalse() {
|
||||
when(vibrator.hasVibrator()).thenReturn(true);
|
||||
|
||||
when(audioManager.getRingerMode()).thenReturn(AudioManager.RINGER_MODE_SILENT);
|
||||
|
||||
assertFalse("shouldVibrate returned true despite ringer mode set to silent",
|
||||
DoNotDisturbUtils.INSTANCE.shouldVibrate(context, true));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue