How to access microphone in Xamarin emulator - xamarin

Is it possible or is there anyway that I can access the Microphone and use it to test my code?
I have enabled all of this in the extended controls of my emulator for microphone:
I also have these permissions in my AndroidManifest.xml:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
This is the code:
using System;
using System.ComponentModel;
using Plugin.AudioRecorder;
using Xamarin.Forms;
namespace AudioDemo
{
[DesignTimeVisible(true)]
public partial class MainPage : ContentPage
{
AudioRecorderService recorder;
AudioPlayer player;
public MainPage()
{
InitializeComponent();
recorder = new AudioRecorderService
{
StopRecordingAfterTimeout = true,
TotalAudioTimeout = TimeSpan.FromSeconds(15),
AudioSilenceTimeout = TimeSpan.FromSeconds(2)
};
player = new AudioPlayer();
player.FinishedPlaying += Finaliza_Reproducao;
}
async void Record_Clicked(object sender, EventArgs e)
{
try
{
if (!recorder.IsRecording)
{
recorder.StopRecordingOnSilence = TimeoutSwitch.IsToggled;
RecordButton.IsEnabled = false;
PlayButton.IsEnabled = false;
//Start recording
var audioRecordTask = await recorder.StartRecording();
RecordButton.Text = "Parar Gravação";
RecordButton.IsEnabled = true;
await audioRecordTask;
RecordButton.Text = "Record";
PlayButton.IsEnabled = true;
}
else
{
RecordButton.IsEnabled = false;
//stop recording ...
await recorder.StopRecording();
RecordButton.IsEnabled = true;
}
}
catch (Exception ex)
{
//blow up the app!
await DisplayAlert("Erro", ex.Message, "OK");
}
}
async void Play_Clicked(object sender, EventArgs e)
{
try
{
var filePath = recorder.GetAudioFilePath();
if (filePath != null)
{
PlayButton.IsEnabled = false;
RecordButton.IsEnabled = false;
player.Play(filePath);
}
}
catch (Exception ex)
{
//blow up the app!
await DisplayAlert("Error", ex.Message, "OK");
}
}
void Finaliza_Reproducao(object sender, EventArgs e)
{
PlayButton.IsEnabled = true;
RecordButton.IsEnabled = true;
}
}
}
This code works when I use a phone to run it, but when I just use (my laptop) emulator, it does not work.

Not able to record sound in the emulator because the android emulator doesn’t support it yet. This code should only work on the phone.
Note: The Android Emulator cannot record audio. Be sure to test your
code on a real device that can record.
This is the official document
https://developer.android.com/guide/topics/media/mediarecorder?hl=en

Related

Files Chooser for Xamarin Forms Not adding the selected image taken from camera and file

I'm creating a mobile application using Xamarin forms, As part of my implementation, I have a requirement to to show file chooser on clicking on camera icon which is loaded in webView and load the image to webView. currently file chooser is being shown, but image is not getting added.
public override bool OnShowFileChooser(Android.Webkit.WebView webView, Android.Webkit.IValueCallback filePathCallback, FileChooserParams fileChooserParams) {
Intent takePictureIntent = new Intent(MediaStore.ActionImageCapture);
if (takePictureIntent.ResolveActivity(mContext.PackageManager) != null) {
Java.IO.File photoFile = null;
try {
string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
photoFile = new Java.IO.File(folder, "image" + DateTime.Now.Millisecond + ".png");
takePictureIntent.PutExtra("PhotoPath", mCameraPhotoPath);
//photoFile = createImageFile();
//takePictureIntent.PutExtra("PhotoPath", mCameraPhotoPath);
} catch (Exception e) {
Console.WriteLine("catch the Exception" + e);
}
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.AbsolutePath;
//pictureUri = FileProvider.GetUriForFile(mContext, "asdasd", photoFile);
takePictureIntent.PutExtra(Android.Provider.MediaStore.ExtraOutput, photoFile);
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ActionGetContent);
contentSelectionIntent.AddCategory(Intent.CategoryOpenable);
contentSelectionIntent.SetType(file_type);
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[] {
takePictureIntent
};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ActionChooser);
chooserIntent.PutExtra(Intent.ExtraIntent, contentSelectionIntent);
chooserIntent.PutExtra(Intent.ExtraTitle, "File chooser");
chooserIntent.PutExtra(Intent.ExtraInitialIntents, intentArray);
//mContext.StartActivity(chooserIntent);
mContext.StartActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
private Java.IO.File createImageFile() {
// Create an image file name
string timeStamp = Android.OS.SystemClock.CurrentThreadTimeMillis().ToString();
string imageFileName = "JPEG_" + timeStamp + "_";
Java.IO.File storageDir;
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Gingerbread) {
storageDir = mContext.CacheDir;
} else {
storageDir = mContext.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures);
}
//new Java.IO.File(mContext.GetExternalFilesDir(null).AbsolutePath);
Java.IO.File imageFile = Java.IO.File.CreateTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
return imageFile;
}
At first, please add the following code into the AndroidManifest.xml to declare the permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.Read_EXTERNAL_STORAGE" />
And then request the permission in the MainActivity's construction method.
var read = await Permissions.RequestAsync<Permissions.StorageRead>();
var write = await Permissions.RequestAsync<Permissions.StorageWrite>();
Finally, please override the OnActivityResult method of the Mainactivity:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
if (data != null)
{
if (requestCode == INPUT_FILE_REQUEST_CODE)// the value of the INPUT_FILE_REQUEST_CODE
{
if (null == this.message)
{
return;
}
this.message.OnReceiveValue(WebChromeClient.FileChooserParams.ParseResult((int)resultCode, data));
this.message = null;
}
}
}

Admob native ads with xamarin: 'Ad failed to load : 0'

This issue only occurs with my implementation of native ads. Banner ads work fine. I adapted the custom renderers from this blog to work with native ads. I used test ad unit IDs.
Here is my custom renderer for Android:
[assembly: ExportRenderer(typeof(NativeAdView), typeof(NativeRendererAndroid))]
namespace XXX.Droid
{
public class NativeRendererAndroid : ViewRenderer<NativeAdView, AdView>
{
public NativeRendererAndroid(Context context) : base(context) { }
protected override void OnElementChanged(ElementChangedEventArgs<NativeAdView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null && Control == null)
SetNativeControl(CreateAdView());
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == nameof(AdView.AdUnitId))
Control.AdUnitId = Element.AdUnitId;
}
private AdView CreateAdView()
{
var adView = new AdView(Context)
{
AdSize = new AdSize(AdSize.FullWidth, AdSize.AutoHeight),
AdUnitId = Element.AdUnitId
};
adView.LayoutParameters = new LinearLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent);
adView.LoadAd(new AdRequest.Builder().Build());
return adView;
}
}
}
And for iOS:
[assembly: ExportRenderer(typeof(NativeAdView), typeof(NativeRendereriOS))]
namespace XXX.iOS
{
public class NativeRendereriOS : ViewRenderer<NativeAdView, NativeExpressAdView>
{
protected override void OnElementChanged(ElementChangedEventArgs<NativeAdView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
SetNativeControl(CreateNativeAd());
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == nameof(NativeExpressAdView.AdUnitID))
Control.AdUnitID = Element.AdUnitId;
}
private NativeExpressAdView CreateNativeAd()
{
AdSize adSize = new AdSize();
adSize.Size = new CGSize(UIScreen.MainScreen.Bounds.Size.Width, 49);
var nativeAd = new NativeExpressAdView(adSize)
{
AdUnitID = Element.AdUnitId,
RootViewController = GetVisibleViewController()
};
nativeAd.LoadRequest(GetRequest());
Request GetRequest()
{
var request = Request.GetDefaultRequest();
return request;
}
return nativeAd;
}
private UIViewController GetVisibleViewController()
{
var windows = UIApplication.SharedApplication.Windows;
foreach (var window in windows)
{
if (window.RootViewController != null)
{
return window.RootViewController;
}
}
return null;
}
}
}
These custom renderers are very similar to the ones linked in the blog above. Perhaps there is something I need to include for native ads that is not used for banner ads?
Once I get the ad loading correctly, I would like to put it in a ListView, but for now I just have it as a View.
Edit: For clarification, when using the above custom renderers, everything builds successfully, but when the ad tries to load, 'Ad failed to load : 0' gets printed in the debug and the NativeAdView remains transparent. This is both both platforms.

Send Print Command from Xamarin.Android to bluetooth printer

So I am pretty new to Xamarin.Android, I have managed to connect to my Bluetooth printer device using the code below, so now I want to send a print command to the printer but I have not been able to for several weeks now. Searched the internet but I have not been able to find a solution. Any assistance will be greatly appreciated
Button btnConnect;
TextView txtView;
Button btnPrint;
BluetoothSocket socket;
BluetoothAdapter adapter;
BluetoothDevice bluetoothDevice;
private byte[] buffer;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.BrianPeek);
FindViews();
HandleEvents();
buffer = new byte[1024];
}
private void HandleEvents()
{
btnConnect.Click += BtnConnect_Click;
btnPrint.Click += Print_Click;
}
private void Print_Click(object sender, EventArgs e)
{
// Variables
string ipAddress = "192.168.1.100";
int portNumber = 9100;
List<string> myText = new List<string>() { "Line1", "Line2" };
// Try to find the platform specific services
// var printer = DependencyService.Get<DSInterfaces.IPrinter>();
var printer = new Printer();
if (printer == null) {
// Do not proceed if no services found for the platform
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Printer");
alert.SetMessage("Error");
alert.Show();
}
try
{
// Call themethod, declare by the IPrinter interface
printer.Print(ipAddress, portNumber, myText);
}
catch (Exception ex)
{
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Printer");
alert.SetMessage("Failed to print redemption slip\nReason "+ex.Message);
alert.Show();
// Exception here could mean difficulties in connecting to the printer etc
//await DisplayAlert("Error", $"Failed to print redemption slip\nReason: {ex.Message}", "OK");
}
}
private async void BtnConnect_Click(object sender, EventArgs e)
{
adapter = BluetoothAdapter.DefaultAdapter;
if(adapter == null) {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Bluetooth");
alert.SetMessage("No Bluetooth Adapter Found");
alert.Show();
}
if (!adapter.IsEnabled) {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Bluetooth");
alert.SetMessage("Bluetooth Adapter is not set!");
alert.Show();
}
bluetoothDevice = (from bd in adapter.BondedDevices
where bd.Name == "MTP-II"
select bd).FirstOrDefault();
if (bluetoothDevice != null) {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Bluetooth");
alert.SetMessage("Bluetooth device " + bluetoothDevice.Name );
alert.Show();
//Connect Bluetooth Device
socket = bluetoothDevice.CreateRfcommSocketToServiceRecord(UUID.FromString("00001101-0000-1000-8000-00805f9b34fb"));
await socket.ConnectAsync();
//after connection, communication occurs through input and output stream
// Read data from the device
await socket.InputStream.ReadAsync(buffer, 0, buffer.Length);
// Write data to the device
await socket.OutputStream.WriteAsync(buffer, 0, buffer.Length);
} else {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Bluetooth");
alert.SetMessage("The device is not found");
alert.Show();
}
}
private void FindViews()
{
btnConnect = FindViewById<Button>(Resource.Id.btnConnectBlue);
txtView = FindViewById<TextView>(Resource.Id.txtText);
btnPrint = FindViewById<Button>(Resource.Id.btnConnectPrint);
}

Scanner is null and not accessible

I am attempting to read a QRCode in Xamarin.Forms. I have a shared project in XF. I have added the nuget packages for ZXing.Net. Everything works in the iOS project. I am getting an error in the Android project. The errors that I get via Android SDK Monitor, it indicates that there is a problem with the scanner being null and not being accessible. I am guessing that there is something that I have not set up correct on the Android side. Does anyone see anything improper in my code? Thanks for your time.
ScanPage class:
public class ScanPage : ContentPage
{
ZXing.Net.Mobile.Forms.ZXingScannerView zxing;
ZXingDefaultOverlay overlay;
bool isConnected = false;
string basicUrl = "golfeventscores.azurewebsites.net";
public ScanPage ()
{
zxing = new ZXing.Net.Mobile.Forms.ZXingScannerView
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
AutomationId = "zxingScannerView",
};
zxing.OnScanResult += async (ZXing.Result result) => {
zxing.IsAnalyzing = false;
zxing.IsScanning = false;
var teamToken = result.Text;
//MessagingCenter.Send<string>(teamToken, "SelectTeamMembers");
isConnected = await Plugin.Connectivity.CrossConnectivity.Current.IsRemoteReachable(basicUrl);
if (isConnected)
{
await GetTeamData(teamToken);
}
else
{
await DisplayAlert("Connectivity", "There is a problem with internet connectivity. Please try and reload this screen.", "Ok");
}
};
overlay = new ZXingDefaultOverlay
{
TopText = "Hold your phone up to the barcode",
BottomText = "Scanning will happen automatically",
ShowFlashButton = zxing.HasTorch,
AutomationId = "zxingDefaultOverlay",
};
overlay.FlashButtonClicked += (sender, e) => {
zxing.IsTorchOn = !zxing.IsTorchOn;
};
var grid = new Grid
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
};
grid.Children.Add(zxing);
grid.Children.Add(overlay);
// The root page of your application
Content = grid;
}
protected override void OnAppearing()
{
base.OnAppearing();
zxing.IsScanning = true;
}
protected override void OnDisappearing()
{
zxing.IsScanning = false;
base.OnDisappearing();
}
async System.Threading.Tasks.Task GetTeamData(string Token)
{
try
{
var scanResult = await WebServices.ws.TokenLookup(Token);
if (scanResult.Result == true)
{
if (scanResult.IsScoreBoard == true)
{
var uri = new System.Uri(scanResult.ScoreboardUrl);
Device.BeginInvokeOnMainThread(() =>
{
Device.OpenUri(uri);
Navigation.PopToRootAsync();
});
}
if (scanResult.IsCharity == true)
{
if (scanResult.TeamPlayers.Count > 0)
{
var player = scanResult.TeamPlayers.First();
var playerId = player.PlayerTeamId;
var urlResult = await WebServices.ws.ServerUrl(Token, playerId);
if (urlResult.ValidRequest && (!String.IsNullOrEmpty(urlResult.Url)))
{
var uri = new System.Uri(urlResult.Url);
Device.OpenUri(uri);
await Navigation.PopToRootAsync();
}
}
else{
await DisplayAlert("Scanning", "There was a problem downloading the Charity Team Info.", "OK");
}
}
else
{
if (scanResult.IsLargeGame != true)
{
var select = new Pages.SelectTeamMembers(Token);
await Navigation.PushAsync(select);
}
else
{
await DisplayAlert("Large Game", "Don't have the large team game setup with scanning.", "Ok");
}
}
}
else
{
await DisplayAlert("Server Problem", "There was some type of server error. Please try again or call Wally.", "Ok");
}
}
catch(System.Exception sysExc)
{
//nothing seems to be caught
}
}
}
MainActivity.cs contents:
[Activity (Label = "TD Scan", Icon = "#drawable/icon", Theme="#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate (Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate (bundle);
global::Xamarin.Forms.Forms.Init (this, bundle);
ZXing.Net.Mobile.Forms.Android.Platform.Init();
LoadApplication (new GolfGameScanApp.App ());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
ZXing.Net.Mobile.Android.PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Have you defined all in Android Project?
Xamarin Forms
For Xamarin Forms there is a bit more setup needed. You will need to initialize the library on each platform in your platform specific app project.
Android
On Android, in your main Activity's OnCreate (..) implementation, call:
ZXing.Net.Mobile.Forms.Android.Platform.Init();
ZXing.Net.Mobile for Xamarin.Forms also handles the new Android permission request model for you, but you will need to add the following override implementation to your main Activity as well:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
global::ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult (requestCode, permissions, grantResults);
}
The Camera permission should be automatically included for you in the AndroidManifest.xml however if you would like to use the Torch API's you will still need to add the Flashlight permission yourself. You can do this by using the following assembly level attribute:
[assembly: UsesPermission (Android.Manifest.Permission.Flashlight)]

Sharing an image in Windows Phone 8.1

I'd like to share an image in my app. However, the image is not located in a folder but it is "taken dynamically". Basically i have an Image object
Image i = new Image() { Source = await CreateBitmapFromElement(stackpanel1) };
where CreateBitmapFromElement is defined as follows
private async Task<RenderTargetBitmap> CreateBitmapFromElement(FrameworkElement uielement)
{
try
{
var renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(uielement);
return renderTargetBitmap;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
}
return null;
}
The Windows Phone Share Contract allows to share images located in the Picture Library (for example), but what should i use in this case?
protected override void OnNavigatedTo(NavigationEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested += OnShareDataRequested;
base.OnNavigatedTo(e);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested -= OnShareDataRequested;
base.OnNavigatedFrom(e);
}
private void OnShareDataRequested(DataTransferManager sender, DataRequestedEventArgs _dataRequestedEventArgs)
{
DataRequest request = _dataRequestedEventArgs.Request;
request.Data.Properties.Title = "KeyTreat Sticker";
request.Data.Properties.Description = "KeyTreat Sticker: " + StickerName;
// Because we are making async calls in the DataRequested event handler,
// we need to get the deferral first.
DataRequestDeferral deferral = request.GetDeferral();
// Make sure we always call Complete on the deferral.
try
{
request.Data.SetStorageItems(storageItemsObject);
request.Data.Properties.Thumbnail = RandomAccessStreamReference.CreateFromFile(StorageFileObject);
request.Data.SetBitmap(RandomAccessStreamReference.CreateFromFile(StorageFileObject));
}
finally
{
deferral.Complete();
}
}

Resources