Android Question [RESOLVED] Android 9 - NB6 - custom sounds

Jmu5667

Well-Known Member
Licensed User
Hello

I am having an issue on Android 9 with the playing of custom sounds and NB6.


Code for selecting Sound
B4X:
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
   Private rm                As RingtoneManager
  
End Sub

Sub ToolBar_MenuItemClick (Item As ACMenuItem)
 
   If Item.Id = 2 Then
       ' // Get a notification
       rm.ShowRingtonePicker("rm", rm.TYPE_NOTIFICATION, True, mod_core_consts.APPSET.notification_content )
   End If

End Sub

Sub rm_PickerResult (Success As Boolean, Uri As String)
  
   If Success Then
       ' // store URI
       mod_core_consts.APPSET.notification_content = Uri
       mod_settings.put_notification_content
   Else
       ToastMessageShow("Error loading ringtone.", True)
   End If
  
End Sub
Code for Playing sound:

B4X:
Sub BigText_Notification(m As helloMessage)
  
   Dim n As NB6
   Dim cs As CSBuilder
   Dim nm As Notification
  
   If lastNotification = 0 Then
       lastNotification = DateTime.now
   End If
  
   n.Initialize("atlas_hello_message", Application.LabelName, "DEFAULT").SmallIcon(notifyIcon).BadgeIconType("SMALL")
  
   ' // setcustom sound
   If mod_core_consts.APPSET.notification_content <> "" Then
       n.SetDefaults(False,True,True)
       Dim uri As Uri
       uri.Parse(mod_core_consts.APPSET.notification_content)
       n.CustomSound(uri)
   Else
   ' // use default sound
       n.SetDefaults(True,True,True)
   End If
   
   n.OnlyAlertOnce(False) 
   n.AutoCancel(True)
  
   mod_core_consts.APPSET.profile.notification_message_id = m.msgID
   ' // is this the messages thread we are viewing
   If mod_core_consts.APPSET.profile.current_message_store_view = m.fromID Then
       CallSubDelayed(MessagingItems,"insert_last_message")
   Else
      
       Dim p As Phone
       ' // 6+
       If p.SdkVersion >= 23 Then
           ' // setup notification
           If m.msgText.Length > 30 Then
               ' // long message
               n.BigTextStyle(m.fromName, cs.Initialize.BackgroundColor(Colors.white).Append("Expand").PopAll, m.msgText)
               svc_service.nNewMessage =  n.Build(m.fromName, m.msgText.SubString2(0,29) & "...", m.msgID , MessagingItems)
           Else
               ' // short message
               svc_service.nNewMessage = n.Build(m.fromName, m.msgText, m.msgID, MessagingItems)
           End If
       Else
       ' // 5.1.1-
           nm.Initialize
           nm.AutoCancel = True
           nm.Icon = "ic_chat_bubble_outline_white_24dp"
           nm.Number = svc_service.nNewMessageID
           ' // this will include the messageId so the MessageItems Activity can insert the newest message via the intent handler
           nm.SetInfo2(m.fromName, m.msgText,m.msgID, MessagingItems)
           ' // show notification
           svc_service.nNewMessage = nm
       End If      
       ' // notify
       CallSubDelayed(svc_service,"new_message_notification")
   End If
   
  
End Sub
This works on Mi A2 Lite (Android 9), not on a One Plus 6 (Android 9), not a Google Pixel 9.0 Preview image running on a Genymotion emulator. On the one that do not work the default sound is played.

All works fine on Android 7,8.

Any idea's


Regards
John.
 

OliverA

Expert
Licensed User
Looking at the Google API docs (https://developer.android.com/refer...oid.net.Uri,%20android.media.AudioAttributes) ), setting the sound is a one time shot, after which I don't think you can programmatically change the settings:
Sets the sound that should be played for notifications posted to this channel and its audio attributes. Notification channels with an importance of at least NotificationManager#IMPORTANCE_DEFAULT should have a sound. Only modifiable before the channel is submitted to NotificationManager#createNotificationChannel(NotificationChannel).
Even NB6's documentation (https://www.b4x.com/android/forum/threads/nb6-notifications-builder-class-2018.91819/) hints at this:
Starting from Android 8+ some of the features are set in the notification channel and not in each notification separately. Once a notification channel is created, it cannot be modified.
and offers the following solution:
If you want to make changes then you need to change the id or uninstall the app (reinstalling is not enough).
More info from this Medium article (https://medium.flatstack.com/migrat...ith-custom-sound-vibration-light-14846ebc9e96):
Until you register notification channel your app notifications are going to have default behaviour. So register it as early as you can. I put this code in Application.onCreate. Keep in mind: once you register channel you cannot change its behaviour. You have to remove app and then install it again to apply new behaviour.
Having said all that, the solution seems to be to call up the system's notification channel settings (https://stackoverflow.com/questions...ification-sound-dynamically-in-android-o?rq=1). The user then assigns the desired ring tone to the applications channel. At that point, there is no need to set the tone programmatically and if ShowRingTonePicker does indeed allow the user to change the ring tone on a system level, then
B4X:
n.SetDefaults(False,True,True)
Dim uri As Uri
uri.Parse(mod_core_consts.APPSET.notification_content)
n.CustomSound(uri)
becomes unnecessary (since technically it does nothing AFTER channel creation) for target SDK 26+. Please note: This is just conjecture from reading docs.
 

OliverA

Expert
Licensed User
Update:
Looking at the NB6 class code, createNotificationChannel is called when you use NB6's Build method. So if a channel has not been registered yet, you can assign a custom notification sound to it programmatically and then use Build once to register the channel. Subsequent calls to Build (and in turn createNotificationChannel) can be used to
update an existing channel's name, description, group, and/or importance
with following caveats
The name and description should only be changed if the locale changes or in response to the user renaming this channel. For example, if a user has a channel named 'John Doe' that represents messages from a 'John Doe', and 'John Doe' changes his name to 'John Smith,' the channel can be renamed to match.

The importance of an existing channel will only be changed if the new importance is lower than the current value and the user has not altered any settings on this channel.

The group an existing channel will only be changed if the channel does not already belong to a group.
and finally
All other fields are ignored for channels that already exist.
Source: https://developer.android.com/refer...ationChannel(android.app.NotificationChannel)
 

Jmu5667

Well-Known Member
Licensed User
As usual @OliverA you help is outstanding and research unquestionable, I have inplemented a simple work around back on your info:

B4X:
   n.Initialize("atlas_hello_message_" & mod_core_consts.APPSET.notification_content, Application.LabelName, "DEFAULT").SmallIcon(notifyIcon).BadgeIconType("SMALL")
:)
 
Top