• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Android 10 Use custom recording for push notification sound.

RazR2019

Lurker
Oct 9, 2019
1
0
Please help me out with this issue, been trying to figure it out for days now.

Before Android 10(Q) I could record a sound or voice, copy the *.wav file to external storage and then create a notification channel that uses that URI of that *.wav file in external storage, and it worked.

Now with Android 10(Q) the push notificaiton comes in, the phone vibrates, but the push notification custom recording sound does not sound when the app is in the background. When the app is in the foreground I am using a different URI though from AppData folder.

I have tried using external storage/directory.Notifications to store the custom sound but it does not work. Any suggestions please? This is the code in C# that I am using now and its now working. Does not matter if the suggestion is in JAVA, just need to know what the logic is, where I should store that custom sound file.

From what I read in documentation, I got the hint that I should use MediaStore, but honestly dont know how to use MediaStore.

>>>>>> Copty the custom file to exernal storage
public async void CopyRecordingToExternalStorage(string filePath)
{
string externalDirPath = CrossCurrentActivity.Current.AppContext.GetExternalFilesDir(Android.OS.Environment.DirectoryNotifications).AbsolutePath;
string recordingFileExternalPath = Path.Combine(externalDirPath, AppConstants.CUSTOM_ALERT_FILENAME);
Java.IO.File storage = CrossCurrentActivity.Current.AppContext.GetExternalFilesDir(Android.OS.Environment.DirectoryNotifications);
string state = Android.OS.Environment.GetExternalStorageState(storage);
var storageStatus = await CrossPermissions.Current.CheckPermissionStatusAsync(Plugin.Permissions.Abstractions.Permission.Storage);
if (storageStatus != Plugin.Permissions.Abstractions.PermissionStatus.Granted)
{
var results = await CrossPermissions.Current.RequestPermissionsAsync(new[] { Plugin.Permissions.Abstractions.Permission.Storage });
storageStatus = results[Plugin.Permissions.Abstractions.Permission.Storage];
}
if (storageStatus == Plugin.Permissions.Abstractions.PermissionStatus.Granted)
{
try
{
if (File.Exists(recordingFileExternalPath))
{
File.Delete(recordingFileExternalPath);
}
File.Copy(filePath, recordingFileExternalPath);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
else
{
UserDialogs.Instance.Alert("Permission to write to External Storage denied, cannot save settings.", "Permission Denied", "Ok");
}
}

>>>>>>> Create the notification channel:
private void createCustomNotificationChannel()
{
try
{
// the custom channel
var urgentChannelName = GetString(Resource.String.noti_chan_custom);
var customChannelDescription = GetString(Resource.String.noti_chan_custom_description);
long[] customVibrationPattern = { 100, 30, 100, 30, 100, 200, 200, 30, 200, 30, 200, 200, 100, 30, 100, 30, 100, 100, 30, 100, 30, 100, 200, 200, 30, 200, 30, 200, 200, 100, 30, 100, 30, 100 };

// Creating an Audio Attribute
var alarmAttributes = new AudioAttributes.Builder()
.SetContentType(AudioContentType.Sonification)
.SetUsage(AudioUsageKind.Notification).Build();

string externalDirPath = CrossCurrentActivity.Current.AppContext.GetExternalFilesDir(Android.OS.Environment.DirectoryNotifications).AbsolutePath;
string alarmSourcePath = System.IO.Path.Combine(externalDirPath, AppConstants.CUSTOM_ALERT_FILENAME);
Java.IO.File storage = CrossCurrentActivity.Current.AppContext.GetExternalFilesDir(Android.OS.Environment.DirectoryNotifications);
string state = Android.OS.Environment.GetExternalStorageState(storage);
var urgentAlarmUri = Android.Net.Uri.Parse(alarmSourcePath);
bool soundFileExists = File.Exists(alarmSourcePath);
var chan3 = new NotificationChannel(TERTIARY_CHANNEL_ID, urgentChannelName, NotificationImportance.High)
{
Description = customChannelDescription
};
// set the urgent channel properties
chan3.EnableLights(true);
chan3.LightColor = Android.Graphics.Color.Red;
chan3.SetSound(urgentAlarmUri, alarmAttributes);
chan3.EnableVibration(true);
chan3.SetVibrationPattern(customVibrationPattern);
chan3.SetBypassDnd(true);
chan3.LockscreenVisibility = NotificationVisibility.Public;

var manager = (NotificationManager)GetSystemService(NotificationService);

// create chan3 which is the urgent notifications channel
manager.CreateNotificationChannel(chan3);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}


>>>>>>> And finally send the notification:
if (useCustomSound)
createCustomNotificationChannel();
try
{
string channel = (useCustomSound == true ? TERTIARY_CHANNEL_ID : PRIMARY_CHANNEL_ID);
Notification.BigPictureStyle bigPictureStyle = new Notification.BigPictureStyle();
if (useCustomPhoto)
{
var customPhotoFilePath = Preferences.Get(AppConstants.CUSTOM_PICTURE_FILE_PATH, null);
BitmapFactory.Options options = new BitmapFactory.Options();
options.InSampleSize = 2;
notifPhoto = BitmapFactory.DecodeFile(customPhotoFilePath, options);
}
else
{

notifPhoto = BitmapFactory.DecodeResource(Resources, Resource.Drawable.alert_header);
}
bigPictureStyle.BigPicture(notifPhoto);

var notificationBuilder = new Notification.Builder(ApplicationContext, channel)
.SetContentTitle(title)
.SetContentText(notificationBody)
.SetFullScreenIntent(pendingIntent, true)
.SetLargeIcon(notifPhoto)
.SetStyle(bigPictureStyle)
.SetSmallIcon(Resource.Drawable.notification_icon_background)
.SetWhen(Java.Lang.JavaSystem.CurrentTimeMillis())
.SetShowWhen(true)
.SetAutoCancel(false);
var manager = (NotificationManager)GetSystemService(NotificationService);
manager.Notify(notificationId, notificationBuilder.Build());
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex);
}
 

BEST TECH IN 2023

We've been tracking upcoming products and ranking the best tech since 2007. Thanks for trusting our opinion: we get rewarded through affiliate links that earn us a commission and we invite you to learn more about us.

Smartphones