diff --git a/app/src/gplay/java/com/nextcloud/talk/services/firebase/MagicFirebaseMessagingService.kt b/app/src/gplay/java/com/nextcloud/talk/services/firebase/MagicFirebaseMessagingService.kt index 3d3cb9000..a6cd04693 100644 --- a/app/src/gplay/java/com/nextcloud/talk/services/firebase/MagicFirebaseMessagingService.kt +++ b/app/src/gplay/java/com/nextcloud/talk/services/firebase/MagicFirebaseMessagingService.kt @@ -23,15 +23,12 @@ import android.annotation.SuppressLint import android.app.Notification import android.app.PendingIntent import android.content.Intent -import android.media.AudioAttributes import android.net.Uri import android.os.Bundle import android.os.Handler -import android.text.TextUtils import android.util.Base64 import android.util.Log import androidx.core.app.NotificationCompat -import androidx.core.app.NotificationManagerCompat import androidx.emoji.text.EmojiCompat import androidx.work.Data import androidx.work.OneTimeWorkRequest @@ -48,7 +45,6 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA import com.nextcloud.talk.events.CallNotificationClick import com.nextcloud.talk.jobs.NotificationWorker import com.nextcloud.talk.jobs.PushRegistrationWorker -import com.nextcloud.talk.models.RingtoneSettings import com.nextcloud.talk.models.SignatureVerification import com.nextcloud.talk.models.json.participants.Participant import com.nextcloud.talk.models.json.participants.ParticipantsOverall @@ -57,7 +53,7 @@ import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.NotificationUtils import com.nextcloud.talk.utils.NotificationUtils.cancelAllNotificationsForAccount import com.nextcloud.talk.utils.NotificationUtils.cancelExistingNotificationWithId -import com.nextcloud.talk.utils.NotificationUtils.createNotificationChannel +import com.nextcloud.talk.utils.NotificationUtils.getCallRingtoneUri import com.nextcloud.talk.utils.PushUtils import com.nextcloud.talk.utils.bundle.BundleKeys import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_FROM_NOTIFICATION_START_CALL @@ -73,7 +69,6 @@ import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode import retrofit2.Retrofit -import java.io.IOException import java.net.CookieManager import java.security.InvalidKeyException import java.security.NoSuchAlgorithmException @@ -202,58 +197,8 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() { PendingIntent.FLAG_UPDATE_CURRENT ) - val audioAttributesBuilder = - AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) - audioAttributesBuilder.setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST) - - val ringtonePreferencesString: String? = appPreferences!!.callRingtoneUri - val soundUri = if (TextUtils.isEmpty(ringtonePreferencesString)) { - Uri.parse( - "android.resource://" + applicationContext.packageName + - "/raw/librem_by_feandesign_call" - ) - } else { - try { - val ringtoneSettings = - LoganSquare.parse(ringtonePreferencesString, RingtoneSettings::class.java) - ringtoneSettings.ringtoneUri - } catch (exception: IOException) { - Uri.parse( - "android.resource://" + - applicationContext.packageName + - "/raw/librem_by_feandesign_call" - ) - } - } - - val notificationChannelId = NotificationUtils.getNotificationChannelId( - applicationContext.resources - .getString(R.string.nc_notification_channel_calls), - applicationContext.resources - .getString(R.string.nc_notification_channel_calls_description), - true, - NotificationManagerCompat.IMPORTANCE_HIGH, - soundUri!!, - audioAttributesBuilder.build(), - null, - false - ) - - createNotificationChannel( - applicationContext!!, - notificationChannelId, - applicationContext.resources - .getString(R.string.nc_notification_channel_calls), - applicationContext.resources - .getString(R.string.nc_notification_channel_calls_description), - true, - NotificationManagerCompat.IMPORTANCE_HIGH, - soundUri, - audioAttributesBuilder.build(), - null, - false - ) - + val soundUri = getCallRingtoneUri(applicationContext!!, appPreferences!!) + val notificationChannelId = NotificationUtils.NOTIFICATION_CHANNEL_CALLS_V4 val uri = Uri.parse(signatureVerification!!.userEntity.baseUrl) val baseUrl = uri.host diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java index 03c1deabb..d5cc86ec7 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallActivity.java @@ -2295,8 +2295,7 @@ public class CallActivity extends CallBaseActivity { stopCallingSound(); Uri ringtoneUri; if (isIncomingCallFromNotification) { - ringtoneUri = Uri.parse("android.resource://" + getApplicationContext().getPackageName() + - "/raw/librem_by_feandesign_call"); + ringtoneUri = NotificationUtils.INSTANCE.getCallRingtoneUri(getApplicationContext(), appPreferences); } else { ringtoneUri = Uri.parse("android.resource://" + getApplicationContext().getPackageName() + "/raw" + "/tr110_1_kap8_3_freiton1"); diff --git a/app/src/main/java/com/nextcloud/talk/activities/CallNotificationActivity.java b/app/src/main/java/com/nextcloud/talk/activities/CallNotificationActivity.java index 4d211e030..04be17291 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/CallNotificationActivity.java +++ b/app/src/main/java/com/nextcloud/talk/activities/CallNotificationActivity.java @@ -32,11 +32,9 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.text.TextUtils; import android.util.Log; import android.view.View; -import com.bluelinelabs.logansquare.LoganSquare; import com.facebook.common.executors.UiThreadImmediateExecutorService; import com.facebook.common.references.CloseableReference; import com.facebook.datasource.DataSource; @@ -50,7 +48,6 @@ import com.nextcloud.talk.api.NcApi; import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.databinding.CallNotificationActivityBinding; import com.nextcloud.talk.events.CallNotificationClick; -import com.nextcloud.talk.models.RingtoneSettings; import com.nextcloud.talk.models.database.CapabilitiesUtil; import com.nextcloud.talk.models.database.UserEntity; import com.nextcloud.talk.models.json.conversations.Conversation; @@ -60,6 +57,7 @@ import com.nextcloud.talk.models.json.participants.ParticipantsOverall; import com.nextcloud.talk.utils.ApiUtils; import com.nextcloud.talk.utils.DisplayUtils; import com.nextcloud.talk.utils.DoNotDisturbUtils; +import com.nextcloud.talk.utils.NotificationUtils; import com.nextcloud.talk.utils.bundle.BundleKeys; import com.nextcloud.talk.utils.preferences.AppPreferences; @@ -390,25 +388,7 @@ public class CallNotificationActivity extends CallBaseActivity { } private void playRingtoneSound() { - String callRingtonePreferenceString = appPreferences.getCallRingtoneUri(); - Uri ringtoneUri; - - if (TextUtils.isEmpty(callRingtonePreferenceString)) { - // play default sound - ringtoneUri = Uri.parse("android.resource://" + getApplicationContext().getPackageName() + - "/raw/librem_by_feandesign_call"); - } else { - try { - RingtoneSettings ringtoneSettings = LoganSquare.parse( - callRingtonePreferenceString, RingtoneSettings.class); - ringtoneUri = ringtoneSettings.getRingtoneUri(); - } catch (IOException e) { - Log.e(TAG, "Failed to parse ringtone settings"); - ringtoneUri = Uri.parse("android.resource://" + getApplicationContext().getPackageName() + - "/raw/librem_by_feandesign_call"); - } - } - + Uri ringtoneUri = NotificationUtils.INSTANCE.getCallRingtoneUri(getApplicationContext(), appPreferences); if (ringtoneUri != null) { mediaPlayer = new MediaPlayer(); try { diff --git a/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt b/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt index cb9001cf6..0dda6430c 100644 --- a/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt +++ b/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt @@ -58,6 +58,7 @@ import com.nextcloud.talk.jobs.SignalingSettingsWorker import com.nextcloud.talk.utils.ClosedInterfaceImpl import com.nextcloud.talk.utils.DeviceUtils import com.nextcloud.talk.utils.DisplayUtils +import com.nextcloud.talk.utils.NotificationUtils import com.nextcloud.talk.utils.OkHttpNetworkFetcherWithCache import com.nextcloud.talk.utils.database.arbitrarystorage.ArbitraryStorageModule import com.nextcloud.talk.utils.database.user.UserModule @@ -188,6 +189,8 @@ class NextcloudTalkApplication : MultiDexApplication(), LifecycleObserver { val emojiCompat = EmojiCompat.init(config) EmojiManager.install(GoogleCompatEmojiProvider(emojiCompat)) + + NotificationUtils.registerNotificationChannels(applicationContext, appPreferences) } override fun onTerminate() { diff --git a/app/src/main/java/com/nextcloud/talk/controllers/RingtoneSelectionController.java b/app/src/main/java/com/nextcloud/talk/controllers/RingtoneSelectionController.java index 6c8e06b92..970c4cee9 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/RingtoneSelectionController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/RingtoneSelectionController.java @@ -45,6 +45,7 @@ import com.nextcloud.talk.adapters.items.NotificationSoundItem; import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.controllers.base.BaseController; import com.nextcloud.talk.models.RingtoneSettings; +import com.nextcloud.talk.utils.NotificationUtils; import com.nextcloud.talk.utils.bundle.BundleKeys; import com.nextcloud.talk.utils.preferences.AppPreferences; import eu.davidea.flexibleadapter.FlexibleAdapter; @@ -180,13 +181,10 @@ public class RingtoneSelectionController extends BaseController implements Flexi private String getRingtoneString() { if (callNotificationSounds) { - return ("android.resource://" + context.getPackageName() + - "/raw/librem_by_feandesign_call"); + return NotificationUtils.INSTANCE.getDEFAULT_CALL_RINGTONE_URI(); } else { - return ("android.resource://" + context.getPackageName() + "/raw" + - "/librem_by_feandesign_message"); + return NotificationUtils.INSTANCE.getDEFAULT_MESSAGE_RINGTONE_URI(); } - } private void fetchNotificationSounds() { diff --git a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java index 9fd64b0bd..a4b3e8bed 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java +++ b/app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java @@ -33,9 +33,12 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.ColorStateList; import android.graphics.PorterDuff; +import android.media.Ringtone; +import android.media.RingtoneManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.provider.Settings; import android.security.KeyChain; import android.text.Editable; import android.text.InputType; @@ -59,7 +62,6 @@ import com.bluelinelabs.conductor.Controller; import com.bluelinelabs.conductor.RouterTransaction; import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler; import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler; -import com.bluelinelabs.logansquare.LoganSquare; import com.facebook.drawee.view.SimpleDraweeView; import com.google.android.material.card.MaterialCardView; import com.google.android.material.textfield.TextInputLayout; @@ -70,7 +72,6 @@ import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.controllers.base.BaseController; import com.nextcloud.talk.jobs.AccountRemovalWorker; import com.nextcloud.talk.jobs.ContactAddressBookWorker; -import com.nextcloud.talk.models.RingtoneSettings; import com.nextcloud.talk.models.database.CapabilitiesUtil; import com.nextcloud.talk.models.database.UserEntity; import com.nextcloud.talk.models.json.generic.GenericOverall; @@ -78,6 +79,7 @@ import com.nextcloud.talk.models.json.userprofile.UserProfileOverall; import com.nextcloud.talk.utils.ApiUtils; import com.nextcloud.talk.utils.DisplayUtils; import com.nextcloud.talk.utils.LoggingUtils; +import com.nextcloud.talk.utils.NotificationUtils; import com.nextcloud.talk.utils.SecurityUtils; import com.nextcloud.talk.utils.bundle.BundleKeys; import com.nextcloud.talk.utils.database.user.UserUtils; @@ -95,7 +97,6 @@ import com.yarolegovich.mp.MaterialSwitchPreference; import net.orange_box.storebox.listeners.OnPreferenceValueChangedListener; -import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; @@ -155,6 +156,8 @@ public class SettingsController extends BaseController { TextView serverAgeTextView; @BindView(R.id.server_age_warning_icon) ImageView serverAgeIcon; + @BindView(R.id.settings_notifications_category) + MaterialPreferenceCategory notificationsCategory; @BindView(R.id.settings_call_sound) MaterialStandardPreference settingsCallSound; @BindView(R.id.settings_message_sound) @@ -293,21 +296,43 @@ public class SettingsController extends BaseController { versionInfo.setSummary("v" + BuildConfig.VERSION_NAME); - settingsCallSound.setOnClickListener(v -> { - Bundle bundle = new Bundle(); - bundle.putBoolean(BundleKeys.INSTANCE.getKEY_ARE_CALL_SOUNDS(), true); - getRouter().pushController(RouterTransaction.with(new RingtoneSelectionController(bundle)) - .pushChangeHandler(new HorizontalChangeHandler()) - .popChangeHandler(new HorizontalChangeHandler())); - }); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - settingsMessageSound.setOnClickListener(v -> { - Bundle bundle = new Bundle(); - bundle.putBoolean(BundleKeys.INSTANCE.getKEY_ARE_CALL_SOUNDS(), false); - getRouter().pushController(RouterTransaction.with(new RingtoneSelectionController(bundle)) - .pushChangeHandler(new HorizontalChangeHandler()) - .popChangeHandler(new HorizontalChangeHandler())); - }); + settingsCallSound.setOnClickListener(v -> { + Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); + intent.putExtra(Settings.EXTRA_APP_PACKAGE, BuildConfig.APPLICATION_ID); + intent.putExtra(Settings.EXTRA_CHANNEL_ID, + NotificationUtils.INSTANCE.getNOTIFICATION_CHANNEL_CALLS_V4()); + startActivity(intent); + }); + + settingsMessageSound.setOnClickListener(v -> { + Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); + intent.putExtra(Settings.EXTRA_APP_PACKAGE, BuildConfig.APPLICATION_ID); + intent.putExtra(Settings.EXTRA_CHANNEL_ID, + NotificationUtils.INSTANCE.getNOTIFICATION_CHANNEL_MESSAGES_V3()); + startActivity(intent); + }); + + } else { + + settingsCallSound.setOnClickListener(v -> { + Bundle bundle = new Bundle(); + bundle.putBoolean(BundleKeys.INSTANCE.getKEY_ARE_CALL_SOUNDS(), true); + getRouter().pushController(RouterTransaction.with(new RingtoneSelectionController(bundle)) + .pushChangeHandler(new HorizontalChangeHandler()) + .popChangeHandler(new HorizontalChangeHandler())); + }); + + settingsMessageSound.setOnClickListener(v -> { + Bundle bundle = new Bundle(); + bundle.putBoolean(BundleKeys.INSTANCE.getKEY_ARE_CALL_SOUNDS(), false); + getRouter().pushController(RouterTransaction.with(new RingtoneSelectionController(bundle)) + .pushChangeHandler(new HorizontalChangeHandler()) + .popChangeHandler(new HorizontalChangeHandler())); + }); + + } if (CapabilitiesUtil.isPhoneBookIntegrationAvailable(userUtils.getCurrentUser())) { phoneBookIntegrationPreference.setVisibility(View.VISIBLE); @@ -417,6 +442,18 @@ public class SettingsController extends BaseController { } } + private String getRingtoneName(Context context, Uri ringtoneUri) { + if (ringtoneUri == null) { + return getResources().getString(R.string.nc_settings_no_ringtone); + } else if (ringtoneUri.toString().equals(NotificationUtils.INSTANCE.getDEFAULT_CALL_RINGTONE_URI()) || + ringtoneUri.toString().equals(NotificationUtils.INSTANCE.getDEFAULT_MESSAGE_RINGTONE_URI())) { + return getResources().getString(R.string.nc_settings_default_ringtone); + } else { + Ringtone r = RingtoneManager.getRingtone(context, ringtoneUri); + return r.getTitle(context); + } + } + @Override protected void onAttach(@NonNull View view) { super.onAttach(view); @@ -479,33 +516,15 @@ public class SettingsController extends BaseController { } } - String ringtoneName = ""; - RingtoneSettings ringtoneSettings; - if (!TextUtils.isEmpty(appPreferences.getCallRingtoneUri())) { - try { - ringtoneSettings = LoganSquare.parse(appPreferences.getCallRingtoneUri(), RingtoneSettings.class); - ringtoneName = ringtoneSettings.getRingtoneName(); - } catch (IOException e) { - Log.e(TAG, "Failed to parse ringtone name"); - } - settingsCallSound.setSummary(ringtoneName); - } else { - settingsCallSound.setSummary(R.string.nc_settings_default_ringtone); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + notificationsCategory.setTitle(getResources().getString(R.string.nc_settings_notification_sounds_post_oreo)); } - ringtoneName = ""; + Uri callRingtoneUri = NotificationUtils.INSTANCE.getCallRingtoneUri(view.getContext(), appPreferences); + settingsCallSound.setSummary(getRingtoneName(view.getContext(), callRingtoneUri)); - if (!TextUtils.isEmpty(appPreferences.getMessageRingtoneUri())) { - try { - ringtoneSettings = LoganSquare.parse(appPreferences.getMessageRingtoneUri(), RingtoneSettings.class); - ringtoneName = ringtoneSettings.getRingtoneName(); - } catch (IOException e) { - Log.e(TAG, "Failed to parse ringtone name"); - } - settingsMessageSound.setSummary(ringtoneName); - } else { - settingsMessageSound.setSummary(R.string.nc_settings_default_ringtone); - } + Uri messageRingtoneUri = NotificationUtils.INSTANCE.getMessageRingtoneUri(view.getContext(), appPreferences); + settingsMessageSound.setSummary(getRingtoneName(view.getContext(), messageRingtoneUri)); if ("No proxy".equals(appPreferences.getProxyType()) || appPreferences.getProxyType() == null) { hideProxySettings(); diff --git a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java index 9f2a2e09e..2f8366b9b 100644 --- a/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java +++ b/app/src/main/java/com/nextcloud/talk/jobs/NotificationWorker.java @@ -21,7 +21,6 @@ package com.nextcloud.talk.jobs; import android.app.Notification; -import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; @@ -52,7 +51,6 @@ import com.nextcloud.talk.activities.CallActivity; import com.nextcloud.talk.activities.MainActivity; import com.nextcloud.talk.api.NcApi; import com.nextcloud.talk.application.NextcloudTalkApplication; -import com.nextcloud.talk.models.RingtoneSettings; import com.nextcloud.talk.models.SignatureVerification; import com.nextcloud.talk.models.database.ArbitraryStorageEntity; import com.nextcloud.talk.models.database.UserEntity; @@ -333,51 +331,9 @@ public class NotificationWorker extends Worker { notificationBuilder.setExtras(notificationInfo); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - - /*NotificationUtils.createNotificationChannelGroup(context, - Long.toString(crc32.getValue()), - groupName);*/ - if (CHAT.equals(decryptedPushMessage.getType()) || ROOM.equals(decryptedPushMessage.getType())) { - AudioAttributes.Builder audioAttributesBuilder = new AudioAttributes.Builder().setContentType - (AudioAttributes.CONTENT_TYPE_SONIFICATION); - audioAttributesBuilder.setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT); - - String ringtonePreferencesString; - Uri soundUri; - - ringtonePreferencesString = appPreferences.getMessageRingtoneUri(); - if (TextUtils.isEmpty(ringtonePreferencesString)) { - soundUri = Uri.parse("android.resource://" + context.getPackageName() + - "/raw/librem_by_feandesign_message"); - } else { - try { - RingtoneSettings ringtoneSettings = LoganSquare.parse - (ringtonePreferencesString, RingtoneSettings.class); - soundUri = ringtoneSettings.getRingtoneUri(); - } catch (IOException exception) { - soundUri = Uri.parse("android.resource://" + context.getPackageName() + - "/raw/librem_by_feandesign_message"); - } - } - - NotificationUtils.INSTANCE.createNotificationChannel(context, - NotificationUtils.INSTANCE.getNOTIFICATION_CHANNEL_MESSAGES_V3(), context.getResources() - .getString(R.string.nc_notification_channel_messages), context.getResources() - .getString(R.string.nc_notification_channel_messages), true, - NotificationManager.IMPORTANCE_HIGH, soundUri, audioAttributesBuilder.build(), null, false); - notificationBuilder.setChannelId(NotificationUtils.INSTANCE.getNOTIFICATION_CHANNEL_MESSAGES_V3()); - } else { - /*NotificationUtils.INSTANCE.createNotificationChannel(context, - NotificationUtils.INSTANCE.getNOTIFICATION_CHANNEL_CALLS_V3(), context.getResources() - .getString(R.string.nc_notification_channel_calls), context.getResources() - .getString(R.string.nc_notification_channel_calls_description), true, - NotificationManager.IMPORTANCE_HIGH); - - notificationBuilder.setChannelId(NotificationUtils.INSTANCE.getNOTIFICATION_CHANNEL_CALLS_V3());*/ } - } else { // red color for the lights notificationBuilder.setLights(0xFFFF0000, 200, 200); @@ -491,26 +447,15 @@ public class NotificationWorker extends Worker { NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); notificationManager.notify(notificationId, notification); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + // On devices with Android 8.0 (Oreo) or later, notification sound will be handled by the system + // if notifications have not been disabled by the user. + return; + } if (!notification.category.equals(Notification.CATEGORY_CALL) || !muteCall) { - String ringtonePreferencesString; - Uri soundUri; - - ringtonePreferencesString = appPreferences.getMessageRingtoneUri(); - if (TextUtils.isEmpty(ringtonePreferencesString)) { - soundUri = Uri.parse("android.resource://" + context.getPackageName() + - "/raw/librem_by_feandesign_message"); - } else { - try { - RingtoneSettings ringtoneSettings = LoganSquare.parse - (ringtonePreferencesString, RingtoneSettings.class); - soundUri = ringtoneSettings.getRingtoneUri(); - } catch (IOException exception) { - soundUri = Uri.parse("android.resource://" + context.getPackageName() + - "/raw/librem_by_feandesign_message"); - } - } - + Uri soundUri = NotificationUtils.INSTANCE.getMessageRingtoneUri(getApplicationContext(), + appPreferences); if (soundUri != null && !ApplicationWideCurrentRoomHolder.getInstance().isInCall() && (DoNotDisturbUtils.INSTANCE.shouldPlaySound() || importantConversation)) { AudioAttributes.Builder audioAttributesBuilder = new AudioAttributes.Builder().setContentType diff --git a/app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.kt b/app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.kt index 204111cf3..dc30a0301 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/NotificationUtils.kt @@ -23,64 +23,44 @@ package com.nextcloud.talk.utils import android.annotation.TargetApi import android.app.Notification import android.app.NotificationChannel -import android.app.NotificationChannelGroup import android.app.NotificationManager import android.content.Context import android.media.AudioAttributes import android.net.Uri import android.os.Build import android.service.notification.StatusBarNotification +import android.text.TextUtils +import com.bluelinelabs.logansquare.LoganSquare +import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R +import com.nextcloud.talk.models.RingtoneSettings import com.nextcloud.talk.models.database.UserEntity import com.nextcloud.talk.utils.bundle.BundleKeys -import java.util.Objects +import com.nextcloud.talk.utils.preferences.AppPreferences +import java.io.IOException object NotificationUtils { - val NOTIFICATION_CHANNEL_CALLS = "NOTIFICATION_CHANNEL_CALLS" val NOTIFICATION_CHANNEL_MESSAGES = "NOTIFICATION_CHANNEL_MESSAGES" - val NOTIFICATION_CHANNEL_CALLS_V2 = "NOTIFICATION_CHANNEL_CALLS_V2" val NOTIFICATION_CHANNEL_MESSAGES_V2 = "NOTIFICATION_CHANNEL_MESSAGES_V2" val NOTIFICATION_CHANNEL_MESSAGES_V3 = "NOTIFICATION_CHANNEL_MESSAGES_V3" + val NOTIFICATION_CHANNEL_CALLS = "NOTIFICATION_CHANNEL_CALLS" + val NOTIFICATION_CHANNEL_CALLS_V2 = "NOTIFICATION_CHANNEL_CALLS_V2" val NOTIFICATION_CHANNEL_CALLS_V3 = "NOTIFICATION_CHANNEL_CALLS_V3" + val NOTIFICATION_CHANNEL_CALLS_V4 = "NOTIFICATION_CHANNEL_CALLS_V4" - fun getVibrationEffectForCalls(): LongArray { - return longArrayOf(0L, 400L, 800L, 600L, 800L, 800L, 800L, 1000L) - } - - fun getNotificationChannelId( - channelName: String, - channelDescription: String, - enableLights: Boolean, - importance: Int, - sound: Uri, - audioAttributes: AudioAttributes, - vibrationPattern: LongArray?, - bypassDnd: Boolean - ): String { - return Objects.hash( - channelName, - channelDescription, - enableLights, - importance, - sound, - audioAttributes, - vibrationPattern, - bypassDnd - ).toString() - } + val DEFAULT_CALL_RINGTONE_URI = + "android.resource://" + BuildConfig.APPLICATION_ID + "/raw/librem_by_feandesign_call" + val DEFAULT_MESSAGE_RINGTONE_URI = + "android.resource://" + BuildConfig.APPLICATION_ID + "/raw/librem_by_feandesign_message" @TargetApi(Build.VERSION_CODES.O) - fun createNotificationChannel( + private fun createNotificationChannel( context: Context, channelId: String, channelName: String, channelDescription: String, - enableLights: Boolean, - importance: Int, sound: Uri, - audioAttributes: AudioAttributes, - vibrationPattern: LongArray?, - bypassDnd: Boolean = false + audioAttributes: AudioAttributes ) { val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager @@ -89,42 +69,81 @@ object NotificationUtils { Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && notificationManager.getNotificationChannel(channelId) == null ) { - val channel = NotificationChannel( channelId, channelName, - importance + NotificationManager.IMPORTANCE_HIGH ) channel.description = channelDescription - channel.enableLights(enableLights) + channel.enableLights(true) channel.lightColor = R.color.colorPrimary channel.setSound(sound, audioAttributes) - if (vibrationPattern != null) { - channel.enableVibration(true) - channel.vibrationPattern = vibrationPattern - } else { - channel.enableVibration(false) - } - channel.setBypassDnd(bypassDnd) + channel.setBypassDnd(false) notificationManager.createNotificationChannel(channel) } } - @TargetApi(Build.VERSION_CODES.O) - fun createNotificationChannelGroup( + private fun createCallsNotificationChannel( context: Context, - groupId: String, - groupName: CharSequence + appPreferences: AppPreferences ) { + val audioAttributes = + AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST) + .build() + val soundUri = getCallRingtoneUri(context, appPreferences) + + createNotificationChannel( + context, + NOTIFICATION_CHANNEL_CALLS_V4, + context.resources.getString(R.string.nc_notification_channel_calls), + context.resources.getString(R.string.nc_notification_channel_calls_description), + soundUri, + audioAttributes + ) + } + + private fun createMessagesNotificationChannel( + context: Context, + appPreferences: AppPreferences + ) { + val audioAttributes = + AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT) + .build() + val soundUri = getMessageRingtoneUri(context, appPreferences) + + createNotificationChannel( + context, + NOTIFICATION_CHANNEL_MESSAGES_V3, + context.resources.getString(R.string.nc_notification_channel_messages), + context.resources.getString(R.string.nc_notification_channel_messages_description), + soundUri, + audioAttributes + ) + } + + fun registerNotificationChannels( + context: Context, + appPreferences: AppPreferences + ) { + createCallsNotificationChannel(context, appPreferences) + createMessagesNotificationChannel(context, appPreferences) + } + + @TargetApi(Build.VERSION_CODES.O) + private fun getNotificationChannel( + context: Context, + channelId: String + ): NotificationChannel? { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - - val notificationChannelGroup = NotificationChannelGroup(groupId, groupName) - if (!notificationManager.notificationChannelGroups.contains(notificationChannelGroup)) { - notificationManager.createNotificationChannelGroup(notificationChannelGroup) - } + return notificationManager.getNotificationChannel(channelId) } + return null } fun cancelAllNotificationsForAccount(context: Context?, conversationUser: UserEntity) { @@ -228,4 +247,51 @@ object NotificationUtils { } } } + + private fun getRingtoneUri( + context: Context, + ringtonePreferencesString: String?, + defaultRingtoneUri: String, + channelId: String + ): Uri { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val channel = getNotificationChannel(context, channelId) + if (channel != null) { + return channel.sound + } + // Notification channel will not be available when starting the application for the first time. + // Ringtone uris are required to register the notification channels -> get uri from preferences. + } + if (TextUtils.isEmpty(ringtonePreferencesString)) { + return Uri.parse(defaultRingtoneUri) + } else { + try { + val ringtoneSettings = + LoganSquare.parse(ringtonePreferencesString, RingtoneSettings::class.java) + return ringtoneSettings.ringtoneUri!! + } catch (exception: IOException) { + return Uri.parse(defaultRingtoneUri) + } + } + } + + fun getCallRingtoneUri( + context: Context, + appPreferences: AppPreferences + ): Uri { + return getRingtoneUri( + context, + appPreferences.callRingtoneUri, DEFAULT_CALL_RINGTONE_URI, NOTIFICATION_CHANNEL_CALLS_V4 + ) + } + + fun getMessageRingtoneUri( + context: Context, + appPreferences: AppPreferences + ): Uri { + return getRingtoneUri( + context, + appPreferences.messageRingtoneUri, DEFAULT_MESSAGE_RINGTONE_URI, NOTIFICATION_CHANNEL_MESSAGES_V3 + ) + } } diff --git a/app/src/main/res/layout/controller_settings.xml b/app/src/main/res/layout/controller_settings.xml index 1489420dc..04c19a4d1 100644 --- a/app/src/main/res/layout/controller_settings.xml +++ b/app/src/main/res/layout/controller_settings.xml @@ -161,6 +161,7 @@ Talk app is not installed on the server you tried to authenticate against Your already existing account was updated, instead of adding a new one The account is scheduled for deletion, and cannot be changed - Sound + Notification sounds + Notifications Calls call_ringtone - Notifications + Messages message_ringtone Librem by feandesign No sound @@ -227,9 +228,10 @@ %1$s on %2$s notification channel - Calls notification channel - Messages notification channel - Shows incoming calls + Calls + Messages + Notify about incoming calls + Notify about incoming messages Notification settings Messages Always notify