I am trying to play custom mp3 sound file of (10-25 seconds) with local notification. I have placed the custom sound file in iOS project folder (same level as Resources) with BundleResource as BuildAction. I have also placed the sound file in Resources folder with same build action. It seems both doesn't work.
var content = new UNMutableNotificationContent
{
Title = title,
//Subtitle = "Notification Subtitle",
Body = body,
Badge = 1,
Sound = UNNotificationSound.GetSound("music.mp3"), //play custom sound
UserInfo = NSDictionary.FromObjectAndKey(NSObject.FromObject(id), NSObject.FromObject(notificationKey))
};
var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(10, false);
var requestID = "request_" + id;
var request = UNNotificationRequest.FromIdentifier(requestID, content, trigger);
UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) =>
{
if (err != null)
{
throw new Exception($"Failed to schedule notification: {err}");
}
});
Any suggestion?
The code works fine, my phone sound was mute.
Related
I have UWP Windows application, developed under the Xamarin.forms. I have implemented the Toast notifications but I am facing the issue with this. In some Windows 10 systems, it is working and showing the toast notification properly, but in some of the Windows 10 systems (even having the same Windows 10 OS update) it is not working.
Below first code snippets that I have implemented in the Native UWP.
string msg = "Toast Notification Header";
string subMsg = "Toast Notification Title";
var toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
var toastTextElements = toastXml.GetElementsByTagName("text");
toastTextElements[0].AppendChild(toastXml.CreateTextNode(msg));
toastTextElements[1].AppendChild(toastXml.CreateTextNode(subMsg));
//To play the custom sound
var toastNode = toastXml.SelectSingleNode("/toast");
var audio = toastXml.CreateElement("audio");
audio.SetAttribute("src", "ms-appx:///Assets/incoming_message.wav");
audio.SetAttribute("loop", "false");
toastNode.AppendChild(audio);
var toast = new ToastNotification(toastXml);
ToastNotificationManager.CreateToastNotifier().Show(toast);
Below second code snippets that I have implemented in the Native UWP.
// "With Microsoft.Toolkit.Uwp.Notifications"
// Construct the toast content
ToastContent toastContent = new ToastContent()
{
Visual = new ToastVisual()
{
BindingGeneric = new ToastBindingGeneric()
{
Children =
{
new AdaptiveText()
{
Text = "Toast Notification Header"
},
new AdaptiveText()
{
Text = "Toast Notification Content"
}
}
}
}
};
bool supportsCustomAudio = true;
// If we're running on Desktop before Version 1511, do NOT include custom audio
// since it was not supported until Version 1511, and would result in a silent toast.
if (AnalyticsInfo.VersionInfo.DeviceFamily.Equals("Windows.Desktop")
&& !ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 2))
{
supportsCustomAudio = false;
}
if (supportsCustomAudio)
{
toastContent.Audio = new ToastAudio()
{
Src = new Uri("ms-appx:///Assets/incoming_message.wav")
};
}
// And create the toast notification
ToastNotification notification = new ToastNotification(toastContent.GetXml());
// And then send the toast
ToastNotificationManager.CreateToastNotifier().Show(notification);
Above code snips showing the Toast notification in some Windows 10 system and not working in some other Windows 10 system.
Kindly guide me on this. Thanks in advance.
Regards,
Vivek
Please follow these steps to add toast notification in UWP Project.
Step 1:- Create a new UWP project.
Step 2:- Go to the code-behind and add the namespace.
using Windows.UI.Notifications;
using
NotificationsExtensions.Toasts;
Step 3:- I created a Toast Generic Template like the following code:
public static Windows.Data.Xml.Dom.XmlDocument CreateToast()
{
var xDoc = new XDocument(
new XElement("toast",
new XElement("visual",
new XElement("binding", new XAttribute("template", "ToastGeneric"),
new XElement("text", "C# Corner"),
new XElement("text", "Do you got MVP award?")
)
),// actions
new XElement("actions",
new XElement("action", new XAttribute("activationType", "background"),
new XAttribute("content", "Yes"), new XAttribute("arguments", "yes")),
new XElement("action", new XAttribute("activationType", "background"),
new XAttribute("content", "No"), new XAttribute("arguments", "no"))
)
)
);
var xmlDoc = new Windows.Data.Xml.Dom.XmlDocument();
xmlDoc.LoadXml(xDoc.ToString());
return xmlDoc;
}
Step 4:- Create a toast notification object using XML document.
var xmdock = CreateToast();
var toast = new ToastNotification(xmdock);
Next show the toast using ToastNotificationManager class.
var notifi = Windows.UI.Notifications.ToastNotificationManager.CreateToastNotifier();
notifi.Show(toast);
Step 5:- C# code-behind:
private void showToastBtn_Click(object sender, RoutedEventArgs e)
{
var xmdock = CreateToast();
var toast = new ToastNotification(xmdock);
var notifi = Windows.UI.Notifications.ToastNotificationManager.CreateToastNotifier();
notifi.Show(toast);
}
I hope the above code will be useful for you.
Thank you
I have this code for downloading a file which runs correct:
var base64EncodedBytes = System.Convert.FromBase64String(item.FileDataAsBase64String);
var downloadDirectory = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads);
var filePath = Path.Combine(downloadDirectory, "test.pdf");
var streamWriter = File.Create(filePath);
streamWriter.Close();
File.WriteAllBytes(filePath, base64EncodedBytes);
I'm able to locate the file I downloaded in the Downloads folder, but also I want to show a notification in the notification bar that the file has been downloaded and with a click in the notifications the user to be able to open the downloaded file.
Is that possible?
You can use Plugin.LocalNotification to show the notification once the file is downloaded.
try
{
var base64EncodedBytes = System.Convert.FromBase64String(item.FileDataAsBase64String);
var downloadDirectory = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, Android.OS.Environment.DirectoryDownloads);
var filePath = Path.Combine(downloadDirectory, "test.pdf");
var streamWriter = File.Create(filePath);
streamWriter.Close();
File.WriteAllBytes(filePath, base64EncodedBytes);
DisplayNotification("test.pdf downloaded successfully", filePath);
}
catch(System.Exception e)
{
System.Console.WriteLine(e.ToString());
DisplayNotification("Download Failed",string.Empty);
}
public void DisplayNotification(string message, string filePath)
{
var notification = new NotificationRequest
{
NotificationId = 100,
Title = "Your App name",
Description = message,
ReturningData = filePath, // Returning data when tapped on notification.
NotifyTime = DateTime.Now.AddSeconds(30) // Used for Scheduling local notification, if not specified notification will show immediately.
};
NotificationCenter.Current.Show(notification);
}
Note: Make sure to initialize the plugin setup in both the project iOS and Android.
Saved image not showing on galary iOS(working fine on Android but not iOS)
Here is my code for saving image to device
public void SavePicture(string name, byte[] data, string location = "Downloads")
{
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
documentsPath = Path.Combine(documentsPath, location);
Directory.CreateDirectory(documentsPath);
string filePath = Path.Combine(documentsPath, name);
File.WriteAllBytes(filePath, data); // writes to local storage
}
Also allow for photo permission on info.plist
Privacy - Photo Library Usage Description
after execute this code I cant find the saved photo on iOS device
How to solve this?
Well in iOS to show an image into the gallery you have to write additional code as just using File.WriteAllBytes won't call the native UIImageWriteToSavedPhotosAlbum API to show it in the album.
To do that you will have to call this API as follows:
Make a dependency service:
public interface ISavePhotosToAlbum
{
void SavePhotosWithFilePath(String Path);
}
Now Add a native class and do the following:
[assembly: Dependency(typeof(SaveToAlbum))]
namespace SavePhotosDemo.iOS
{
public class SaveToAlbum : ISavePhotosToAlbum
{
public void SavePhotosWithFilePath(String Path)
{
using (var url = new NSUrl (Path))
using (var data = NSData.FromUrl (url))
var image = UIImage.LoadFromData (data);
image.SaveToPhotosAlbum((img, error) =>
{
if (error == null)
{//Success }
else
{//Failure}
});
}
}
}
Then use this Dependency Service as follows:
DependencyService.Get<ISavePhotosToAlbum>().SavePhotosWithStream(imageUrl);
Also, see to it that you add this dependency service call only for ios by adding it in an OnPlatform if statement.
UPDATE
Use the following code to Add a Custom Photo Album in Photos library:
void AddAssetToAlbum(UIImage image, PHAssetCollection album, string imageName)
{
try
{
PHPhotoLibrary.SharedPhotoLibrary.PerformChanges(() =>
{
// Create asset request
var creationRequest = PHAssetCreationRequest.CreationRequestForAsset();
var options = new PHAssetResourceCreationOptions
{
OriginalFilename = imageName
};
creationRequest.AddResource(PHAssetResourceType.Photo, image.AsJPEG(), options);
// Change asset request (change album by adding photo to it)
var addAssetRequest = PHAssetCollectionChangeRequest.ChangeRequest(album);
addAssetRequest.AddAssets(new PHObject[] { creationRequest.PlaceholderForCreatedAsset });
}, (success, error) =>
{
if (!success)
Console.WriteLine("Error adding asset to album");
});
}
catch (Exception ex)
{
string h = ex.Message;
}
}
See to it that you request authorization using the PHPhotoLibrary.RequestAuthorization method as we need to request access to be able to use the Photos library. Also, As of iOS 10 and above we also need to add an entry for access in the target .plist file for "Privacy - Photo Library Usage Description":
<key>NSPhotoLibraryUsageDescription</key>
<string>Access to photos is needed to provide app features</string>
Update
At the end, adding the following started showing the documents in the files app:
<key>UIFileSharingEnabled</key> <true/> <key>LSSupportsOpeningDocumentsInPlace</key> <true/>
i have xamarin forms app that support notification, i have done it in android with broadcast receiver now i have to do notification in ios ! , my service is depending on API REST so i want every 60 second ios app run HTTP request and get data then show it as notification, i searched for many days but i can't reach to my approach ?
if this is impossible can i use nuget or something like that in ios project only "in xamarin forms solution " or not ?
content = new UNMutableNotificationContent();
content.Title = "Notification Title";
content.Subtitle = "Notification Subtitle";
content.Body = "This is the message body of the notification.";
content.Badge = 1;
content.CategoryIdentifier = "message";
var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(60, true);
var requestID = "sampleRequest";
var request = UNNotificationRequest.FromIdentifier(requestID, content, trigger);
UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) =>
{
if (err != null)
{
// Do something with error...
}
});
Here is my code for generating a local notification on iOS
var alertsAllowed = false;
UNUserNotificationCenter.Current.GetNotificationSettings((settings) =>
{
alertsAllowed = (settings.AlertSetting == UNNotificationSetting.Enabled);
});
if (alertsAllowed)
{
var content = new UNMutableNotificationContent();
content.Title = "Incident Recorder";
content.Subtitle = "Not Synchronised";
content.Body = "There are one or more new incidents that have not been synchronised to the server.";
var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(5, false);
var requestID = "sampleRequest";
var request = UNNotificationRequest.FromIdentifier(requestID, content, trigger);
UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) =>
{
if (err != null)
{
Console.WriteLine(err.LocalizedFailureReason);
}
});
}
The first parameter in CreateTrigger is how long before the notification is generated. I notice you have 60 in yours. Also bear in mind a notification will not appear if your app is foregrounded.
I'm using the media manager nuget plugin and it's great, but for the life of me, I can't get the lock screen or car bluetooth to show the notifications. I'm using the following to display the notifications (set within OnAppearing)
ViewModel.PropertyChanged += (sender, e) =>
{
switch (e.PropertyName)
{
case "RadioSchedule":
if (listData != null)
{
listData.ItemsSource = null;
var first = ViewModel.RadioSchedule[0];
Device.BeginInvokeOnMainThread(() =>
{
listData.ItemsSource = ViewModel.RadioSchedule;
MediaFile.Metadata.Artist = MediaFile.Metadata.DisplaySubtitle = MediaFile.Metadata.AlbumArtist = first.Artist;
MediaFile.Metadata.Title = MediaFile.Metadata.DisplayTitle = first.Track;
MediaFile.Metadata.DisplayIcon = new Image { Source = "icon".CorrectedImageSource() };
MediaFile.Metadata.BluetoothFolderType = "1";
MediaFile.Type = MediaFileType.Audio;
MediaFile.Url = Constants.RadioStream;
MediaFile.Availability = ResourceAvailability.Remote;
MediaFile.MetadataExtracted = true;
MediaFile.Metadata.Date = DateTime.Now;
MediaFile.Metadata.Duration = 300;
MediaFile.Metadata.Genre = "Rock";
MediaFile.Metadata.TrackNumber = MediaFile.Metadata.NumTracks = 1;
MediaFile.Metadata.DisplayDescription = "Radio Station";
if (!ViewModel.NotificationStarted)
{
if (CrossMediaManager.Current.MediaNotificationManager != null)
CrossMediaManager.Current.MediaNotificationManager.StartNotification(MediaFile);
ViewModel.NotificationStarted = true;
}
CrossMediaManager.Current.MediaNotificationManager?.UpdateNotifications(MediaFile, MediaPlayerStatus.Playing);
});
}
break;
The code itself is being hit (I can set break points and they are hit). I've tried it on and off the UI thread as well.
The playlist comes from a webapi which works fine. The notifier gives unknown/unknown on the device media player (both iOS and Android) and nothing in-car. For Android, the permissions the readme file says to use have also been set.
Is there some sort of magic I have to do to get this to work? This is a Xam.Forms package rather than something native.
The MediaPlayer is started further in the class using the following code
CrossMediaManager.Current.Play(Constants.RadioStream, MediaFileType.Audio, ResourceAvailability.Remote);
Where Constants.RadioStream is the URL of the radio stream.