I'm trying to learn and play a bit with Xamarin :)
I wanted to play a simple sound at the end of a certain time and in part I succeeded, this works on the android and ios emulators but when I try to build the app on my iPhone this crush at the moment of sound reproduction!
the code I wrote I copied from here!
so my code is this:
iAudio.cs :
using System;
namespace StopWatch
{
public interface IAudio
{
void PlayAudioFile(string fileName);
}
}
AudioService.cs in Android :
using System;
using Xamarin.Forms;
using StopWatch.Droid;
using Android.Media;
using Android.Content.Res;
[assembly: Dependency(typeof(AudioService))]
namespace StopWatch.Droid
{
public class AudioService : IAudio
{
public AudioService()
{ }
public void PlayAudioFile(string fileName)
{
var player = new MediaPlayer();
var fd = global::Android.App.Application.Context.Assets.OpenFd(fileName);
player.Prepared += (s, e) =>
{
player.Start();
};
player.SetDataSource(fd.FileDescriptor, fd.StartOffset, fd.Length);
player.Prepare();
}
}
}
AudioService.cs in iOS:
using System; using Xamarin.Forms; using StopWatch; using StopWatch.iOS; using System.IO; using Foundation; using AVFoundation; [assembly: Dependency(typeof(AudioService))] namespace StopWatch.iOS {
public class AudioService : IAudio
{
public AudioService()
{ }
public void PlayAudioFile(string fileName)
{
string sFilePath = NSBundle.MainBundle.PathForResource(Path.GetFileNameWithoutExtension(fileName), Path.GetExtension(fileName));
NSUrl url = NSUrl.FromString(sFilePath);
var _player = AVAudioPlayer.FromUrl(url);
_player.FinishedPlaying += (object sender, AVStatusEventArgs e) =>
{
_player = null;
};
_player.Play();
}
}
}
and this is mi MainPage.xaml.cs :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace StopWatch
{
// Learn more about making custom code visible in the Xamarin.Forms previewer
// by visiting https://aka.ms/xamarinforms-previewer
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
Stopwatch stopwatch;
public MainPage()
{
InitializeComponent();
stopwatch = new Stopwatch();
lblStopWatch.Text = "00:00:00";
lblStopWatchAllert.Text = "";
}
private void btnStartClicked(object sender, EventArgs e)
{
stopwatch.Start();
Device.StartTimer(TimeSpan.FromMilliseconds(10), () =>
{
lblStopWatch.Text = stopwatch.Elapsed.ToString().Substring(0, 8);
controll(lblStopWatch.Text);
return true;
});
}
private void btnStopClicked(object sender, EventArgs e)
{
stopwatch.Stop();
}
private void btnResetClicked(object sender, EventArgs e)
{
stopwatch.Reset();
}
private void controll(String time)
{
if (string.Compare(time, "00:00:03:0000") > 0)
{
stopwatch.Reset();
lblStopWatchAllert.Text = "time is over!";
DependencyService.Get<IAudio>().PlayAudioFile("Alert.mp3");
}
}
}
}
the code crashes me at this point of the iOS AudioService.cs file:
I think the problem lies in the info.plist (although I am most likely wrong) but I don't know how to solve it :(
can someone help me? thank you
I have checked this code , it works in my site . Invoking the play method as follow :
DependencyService.Get<IAudio>().PlayAudioFile("Alan_Walker.mp3");
The other codes are the same with yours in iOS and Android , they all play the sound successfully.
Here you need to notice that ,the local sound file should be added to each platform .And each platform has its specical folder to put the auido file .
In Android , you need to put it in Assets folder as follow :
And in iOS , you need to put it in Resources folder as follow :
==========================Update===================================
You should first add file to this folder as follow :
Then add Existing file to this folder :
Then when installing app , this filw will be added to mobile . No matter what is a simulator or a physical device.
Note :
Not copying file from other path to Xamarin.iOS project , this can't make sure the file be added to the project .
Related
I need to save an image at Parse, so I need to convert it to byte[]. Any idea how can I achieve this? I've searched for it but none of the options worked for me. I'm using a shared Xamarin Forms project. Here's an example with text :
byte[] data = System.Text.Encoding.UTF8.GetBytes("Working at Parse is great!");
ParseFile file = new ParseFile("resume.txt", data);
I'm beginner and I really need help !
[EDIT] :
For some reason, Xamarin will not let me use "System.Drawing.Image".
I've searched a lot, and I found this but I can't make it work :
public static byte[] ReadFully(System.IO.Stream input)
{
using (var ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
Thanks in advance .
If you choose images from photo gallery, you can use this codes. This codes also aim to pick up an image from photo library in iOS and save it to database as a byte array.
You said that you already have an image to display as the login form but someone who see this may not know how to get an image from your photo library in iOS so I write all of the code to archive the way to get an image and convert it to byte array.I use Prism library but any framework is ok.
If you want to only know how to convert an image to a byte array in Xamarin.forms you can go to the bottom of the codes below as MainPage class.
First, you make a new folder and name it Services. Under this folder you make an interface like this.
using System;
using System.Threading.Tasks;
using Xamarin.Forms;
using System.IO;
using Foundation;
namespace TestUIImage.Services
{
public interface IPicturePicker
{
Task<NSUrl> GetNSUrlAsync();
}
}
Then you write the content of GetNSUrlAsync method.
You need two methods GetNSUrl and OnImagePickerCancelled so that user select an image or cancel to select.
using System;
using System.IO;
using UIKit;
using Xamarin.Forms;
using System.Threading.Tasks;
using Foundation;
namespace TestUIImage.Services
{
public class PicturePickerImplementation : IPicturePicker
{
public PicturePickerImplementation()
{
}
TaskCompletionSource<NSUrl> urltaskCompletionSource;
UIImagePickerController imagePicker;
public Task<NSUrl> GetNSUrlAsync()
{
// Create and define UIImagePickerController
imagePicker = new UIImagePickerController
{
SourceType = UIImagePickerControllerSourceType.PhotoLibrary,
MediaTypes = UIImagePickerController.AvailableMediaTypes(UIImagePickerControllerSourceType.PhotoLibrary)
};
// Set event handlers
imagePicker.FinishedPickingMedia += GetNSUrl;
imagePicker.Canceled += OnImagePickerCancelled;
// Present UIImagePickerController
UIWindow window = UIApplication.SharedApplication.KeyWindow;
var viewController = window.RootViewController;
viewController.PresentModalViewController(imagePicker, true);
// Return Task object
urltaskCompletionSource = new TaskCompletionSource<NSUrl>();
return urltaskCompletionSource.Task;
}
void GetNSUrl(object sender, UIImagePickerMediaPickedEventArgs args)
{
urltaskCompletionSource.SetResult(args.ImageUrl);
imagePicker.DismissModalViewController(true);
}
void OnImagePickerCancelled(object sender, EventArgs args)
{
taskCompletionSource.SetResult(null);
imagePicker.DismissModalViewController(true);
}
}
}
Next, you register your services using DependencyService because selecting an image from your photo gallery in iOS depends on your platform.
using Prism;
using Prism.Ioc;
using TestUIImage.ViewModels;
using TestUIImage.Views;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Prism.Autofac;
using TestUIImage.Services;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace TestUIImage
{
public partial class App : PrismApplication
{
public App() : this(null) { }
public App(IPlatformInitializer initializer) : base(initializer) { }
protected override async void OnInitialized()
{
InitializeComponent();
DependencyService.Register<PicturePickerImplementation>();
await NavigationService.NavigateAsync("NavigationPage/MainPage");
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<NavigationPage>();
containerRegistry.RegisterForNavigation<MainPage>();
}
}
}
Then, you add this code in Info.plist because of the iOS security.
...
<key>NSPhotoLibraryUsageDescription</key>
<string>Picture Picker uses photo library</string>
</dict>
</plist>
Finally, you can call your services in codebehind. In this time, I used Image controller as TestImage and Button controller as PickPictureButton.
using System;
using System.IO;
using System.Drawing;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Foundation;
using Xamarin.Forms;
using TestUIImage.Services;
namespace TestUIImage.Views
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
async void Handle_Clicked(object sender, System.EventArgs e)
{
PickPictureButton.IsEnabled = false;
NSUrl nSUrl = await DependencyService.Get<IPicturePicker>().GetNSUrlAsync();
TestImage.Source = ImageSource.FromStream(() =>
{
var ms = new MemoryStream();
var imagebytes = File.ReadAllBytes(nSUrl.Path);
ms.Write(imagebytes, 0, imagebytes.Length);
ms.Seek(0, SeekOrigin.Begin);
return ms;
});
PickPictureButton.IsEnabled = true;
}
}
}
Here's some code to convert a BitmapImage to a byte[]:
public byte[] ConvertToBytes(BitmapImage bitmapImage)
{
if (bitmapImage != null)
{
MemoryStream memStream = new MemoryStream();
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
encoder.Save(memStream);
return memStream.GetBuffer();
}
return null;
}
Here's some code to convert a byte[] to a BitmapImage:
private void LoadImage()
{
var image = Services.GetImage(_employeeID);
if (image.Image != null)
{
MemoryStream strmImg = new MemoryStream(image.Image);
BitmapImage myBitmapImage = new BitmapImage();
myBitmapImage.BeginInit();
myBitmapImage.StreamSource = strmImg;
myBitmapImage.DecodePixelWidth = 200;
myBitmapImage.DecodePixelWidth = 250;
myBitmapImage.EndInit();
this.DemographicInformation.Image = myBitmapImage;
}
}
This has worked for me many times.
I have two solutions TranferService and Sender. TranferService has WCF service and IISHost to host that service. In Sender solution i have windows forms application. In that form i used button to browse and select file, text box to display selected file path, and another button(Send) to transfer that file through WCF service. But i am unable to access textbox value in the transfer solution. it shows"the name does not exist in the current context".
Code for TransferService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace TransferService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "TransferService" in both code and config file together.
public class TransferService : ITransferService
{
public File DownloadDocument()
{
File file = new File();
String path = txtSelectFilePath.Text;
file.Content = System.IO.File.ReadAllBytes(#path);
//file.Name = "ImagingDevices.exe";
return file;
}
}
}
I am getting error on this line
String path = txtSelectFilePath.Text;
code for form.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Sender
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Browse_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
txtSelectFilePath.Text = openFileDialog1.FileName;
}
}
private void Send_Click(object sender, EventArgs e)
{
TransferService.TransferServiceClient client = new TransferService.TransferServiceClient();
TransferService.File file = client.DownloadDocument();
System.IO.File.WriteAllBytes(#"C:\DownloadedFiles\" + file.Name, file.Content);
MessageBox.Show(file.Name + " is downloaded");
}
}
}
Code for ITransferService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace TransferService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "ITransferService" in both code and config file together.
[ServiceContract]
public interface ITransferService
{
[OperationContract]
File DownloadDocument();
}
[DataContract]
public class File
{
[DataMember]
public string Name { get; set; }
[DataMember]
public byte[] Content { get; set; }
}
}
Thanx a lot in advance..........
Then create a constructor to your class that receives a path as string something like this:
public class TransferService : ITransferService
{
private string _path;
public TransferService(string path) {
_path = path
}
public File DownloadDocument()
{
File file = new File();
//String path = txtSelectFilePath.Text;
file.Content = System.IO.File.ReadAllBytes(_path);
//file.Name = "ImagingDevices.exe";
return file;
}
}
and then on form.cs
TransferService.TransferServiceClient client = new TransferService.TransferServiceClient(txtSelectFilePath.Text);
I have been trying to make a personal assistant in my free time, and so far i have made him speak, but now i am trying to speak to him. Whenever i do however, he fails massively. When i say "Hello my name is Alexander" he recognizes "in the name is unresolved bush" or something else that is just not correct. am i doing something wrong or is the built in C# recognition engine just broken?
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TTS_Test
{
class Jarvis
{
private static SpeechSynthesizer synthezier;
private static String name;
public Jarvis()
{
synthezier = new SpeechSynthesizer();
synthezier.SelectVoiceByHints(VoiceGender.Male, VoiceAge.Senior);
synthezier.Volume = 100;
synthezier.Rate = 0;
}
private bool isFirstTime()
{
if (File.Exists("config"))
{
return false;
}else{
return true;
}
}
private void firstTimeSetup()
{
say("Hello, My name is Jarvis. It seems that this is your first time here. Please take some time to configure the application.");
Config config = new Config();
config.ShowDialog();
say("Thank you! I should be up and running now.");
}
public void initiate()
{
if (isFirstTime())
{
firstTimeSetup();
}
setupUserData();
say("Hello " + name+". How may i help you today?");
recognize();
}
public void setupUserData()
{
StreamReader reader = new StreamReader("config");
name = reader.ReadLine();
reader.Close();
}
public void say(string output)
{
synthezier.Speak(output);
}
public void recognize()
{
SpeechRecognitionEngine sr = new SpeechRecognitionEngine(new System.Globalization.CultureInfo("en-GB"));
sr.LoadGrammar(new DictationGrammar());
sr.InitialSilenceTimeout = TimeSpan.FromSeconds(5);
sr.SetInputToDefaultAudioDevice();
RecognitionResult result = sr.Recognize();
MessageBox.Show(result.Text);
}
}
}
You should train your computer to better understand you by going to the Control Panel\All Control Panel Items\Speech Recognition
I am recently writing a wiimote program:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WiimoteLib;
namespace WiiTester
{
public partial class Form1 : Form
{
Wiimote wm = new Wiimote();
public Form1()
{
InitializeComponent();
wm.WiimoteChanged += wm_WiimoteChanged;
wm.WiimoteExtensionChanged += wm_WiimoteExtensionChanged;
wm.Connect();
wm.SetReportType(InputReport.IRAccel, true);
}
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
WiimoteState ws = args.WiimoteState;
if (ws.ButtonState.A == true)
{
wm.SetRumble(true);
}
else
{
wm.SetRumble(false);
}
}
void wm_WiimoteExtensionChanged(object sender, WiimoteExtensionChangedEventArgs args)
{
if (args.Inserted)
{
wm.SetReportType(InputReport.IRExtensionAccel, true);
}
else
{
wm.SetReportType(InputReport.IRAccel, true);
}
}
}
}
My wiimote keeps getting disconnected and this error keeps running on wm.Connect();
Timed out waiting for status report
Is there a solution?
I have a lot of experience with this library, and your problem is most likely being caused because you are calling SetRumble so often, this code:
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
WiimoteState ws = args.WiimoteState;
if (ws.ButtonState.A == true)
{
wm.SetRumble(true);
}
else
{
wm.SetRumble(false);
}
}
Will call SetRumble constantly whether A is down or not, consider using this code instead:
bool rumbleOn = false;
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
WiimoteState ws = args.WiimoteState;
bool newRumble = (ws.ButtonState.A == true);
if (rumbleOn != newRumble)
{
rumbleOn = newRumble;
wm.SetRumble(rumbleOn);
}
}
This way the set rumble method is only called when required and not constantly sending output reports to the WiiMote which causes the Bluetooth BUS to overload.
I am trying to create a simple service in C# using VS2008 that creates a text file when the computer goes into sleep mode. My current code throws out the following error:
'SleepNotifierService.WqlEventQuery' does not contain a constructor that takes '1' arguments
Now I looked in the Object browser, and it looks like it does take in one argument. This is what the browser had to say:
public WqlEventQuery(string queryOrEventClassName)
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Management;
using System.IO;
namespace SleepNotifierService
{
public class WqlEventQuery : EventQuery { }
public partial class Service1 : ServiceBase
{
ManagementEventWatcher _watcher;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
WqlEventQuery query = new WqlEventQuery("Win32_PowerManagementEvent");
_watcher = new ManagementEventWatcher(query);
_watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
_watcher.Start();
}
protected override void OnStop()
{
_watcher.Stop();
}
void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
try
{
int eventType = Convert.ToInt32(e.NewEvent.Properties["EventType"].Value);
switch (eventType)
{
case 4:
Sleep();
break;
case 7:
Resume();
break;
}
}
catch (Exception ex)
{
//Log(ex.Message);
}
}
public void Sleep()
{
StreamWriter SW;
SW = File.CreateText("c:\\MyTextFile.txt");
SW.WriteLine("Sleep mode initiated");
SW.Close();
}
public void Resume()
{
}
}
}
Am I interpreting that object browser wrong? I'm new to creating services and C#/.NET in general so it might be something trivial.
Appreciate any help,
Tomek
You're using wrong WqlEventQuery. There's one defined in System.Management and it indeed has a one-argument constructor, but there's also your custom WqlEventQuery class.
If you want to use .NET BCL's class, you'll have to fully qualify it:
var query = new System.Management.WqlEventQuery("Win32_PowerManagementEvent");
or even prefix it with global keyword:
var query = new global::System.Management.WqlEventQuery("Win32_PowerManagementEvent");