Is it possible to capture the overlay name instead just the signature in xamarin? - xamarin.forms

I'm using Xamarin signaturepadView on capturing Signature. Also, saving the signature works fine. I also want to capture the text and stuff.
This is what I want to capture
Instead I got this

You can also use Xamarin.Essentials: Screenshot to capture the whole view of the Signature. Here's the sample code below for your reference:
private async void Button_Clicked(object sender, EcentArgs e){
if(Screenshot.IsCaptureSupported){
var screenshot = await Screenshot.CaptureAsync();
var stream = await screenshot.OpenReadAsync();
ImageScreenshot.Source = ImageSource.FromStream(() => stream);
}
}

Related

How do I get a link from FireBase? C#

I work with the C# language not java and do not yet know how to get a reference to an object in FireBaseStorage. I have the following code that should output a link from Fire Base Storage, but instead it outputs System.Threading.Tasks.Tast`1[The system.Line]
Tell me how do I get a link to a file from FireBaseStorage using FireSharp and FireBase libraries
here is my code: (C#)
FirebaseStorage storage = new FirebaseStorage("*******-****.appspot.com");
var starsRef = storage.Child("test.txt");
string link = starsRef.GetDownloadUrlAsync().ToString();
MessageBox.Show(link);
Don't know above C# that much, but whenever we do an asynchronous calls, don't we have to wait for result ? "await". Cause your ouput seems your thread is waiting for the result. System.Threading.Tasks.Tast`1[The system.Line]
Try using await before getting downloadUrl string link = await starsRef.GetDownloadUrlAsync().ToString(); and make your mehtod asynchronous in which you are writing your code.
C#
private void button28_ClickAsync(object sender, EventArgs e)
{
// Create a reference to the file we want to download
_ = getLinkAsync();
getLinkAsync();
}
public async Task getLinkAsync()
{
FirebaseStorage storage = new FirebaseStorage("firstbd-****.appspot.com");
var starsRef = storage.Child("test.txt");
string link = await starsRef.GetDownloadUrlAsync();
MessageBox.Show(link);
}

Unity: Receive Firebase Short Dynamic Link in DynamicLinkReceived callback event

I would like to use Firebase Dynamic Links for Unity (Android/iOS) so users can invite friends and be rewarded with.
Each user gets a different Short Dynamic Link in the form of https://test.page.link/abcd
The user can share this Short DynamicLink with friends.
When the invited friend comes into the app, this callback is called.
private void OnDynamicLink(object sender, EventArgs args) {
var dynamicLinkEventArgs = args as ReceivedDynamicLinkEventArgs;
Debug.LogFormat("Received dynamic link {0}",
dynamicLinkEventArgs.ReceivedDynamicLink.Url.OriginalString);
}
Unfortunately, I only get back the base link that was necessary to create the short dynamic link.
Received dynamic link https://www.example.com/referral?xxxxxxxxxx
I get an additional native output in my iOS app:
IOSNative::Native->Unity callback data:
{"m_EventName":"continueUserActivity","m_Data":"https://test.page.link/?link=https://www.example.com/referral?xxxxxxxxxx&apn=de.test.testapp&isi=123456789&ibi=de.test.testapp&cid=1579347010984123886&_osl=https://test.page.link/abcd&_fpb=AB6327276CFGHT==&_cpt=cpit&_iumenbl=1&_iumchkactval=1&_plt=2076&_uit=2692&_cpb=1"}
2020-01-14 15:30:20.455009+0100 ambassador[315:8406]
IOSNative::Native->Unity callback data:
{"m_EventName":"applicationDidBecomeActive","m_Data":""}
Now my question is how do I get the generated short dynamic link that I have shared with a friend in OnDynamicLink callback( https://test.page.link/abcd)?
I need the value behind the parameter "&_osl" as seen in additional native output. But I only get the Base Url back in Unity (https://www.example.com/referral?xxxxxxxxxx).
My solution at the end was to shorten the BaseLink with the help of DynamicLinks.GetShortLinkAsync.
//unescape url
baseLink = UnityEngine.Networking.UnityWebRequest.UnEscapeURL(baseLink);
var components = new DynamicLinkComponents(
// The base Link.
new Uri(baseLink),
// The dynamic link URI prefix.
domainUriPrefix) {
IOSParameters = new IOSParameters(PackageName) {
AppStoreId = "XXXXXXXXX"
},
AndroidParameters = new AndroidParameters(PackeName)
};
string inviteLink = string.Empty;
await DynamicLinks.GetShortLinkAsync(components, options).ContinueWith((task) => {
if (task.IsCanceled) {
Debug.LogError("GetShortLinkAsync was canceled.");
return;
}
if (task.IsFaulted) {
Debug.LogError("GetShortLinkAsync encountered an error: " + task.Exception);
return;
}
// Short Link has been created.
inviteLink = task.Result.Url.ToString();
});

Xamarin.Forms Call to message center increases in number each time

I've a problem where I send message once and Subscriber is called once but next time it is called twice and so on... Here's my code.
This is message sender
public void OnSuccess(Java.Lang.Object result)
{
UploadTask.TaskSnapshot taskSnapShot = (UploadTask.TaskSnapshot)result;
string downloadURL = taskSnapShot.DownloadUrl.ToString();
string fileName = taskSnapShot.Metadata.Name;
GBPaperReceipt.Model.ImageFile imageFile = new Model.ImageFile
{
FileName = fileName,
FilePath = downloadURL
};
MessagingCenter.Send((App)Xamarin.Forms.Application.Current, MessageStrings.ImageUploadEvent, imageFile);
//save this live storage image url in receipt table
//MessagingCenter.Send<Xamarin.Forms.Application, string>((Xamarin.Forms.Application)Xamarin.Forms.Application.Current, ChatModuleConstant.UploadMediaEvent, downloadURL);
}
This is message receiver
MessagingCenter.Subscribe<App, ImageFile>((App)Application.Current, MessageStrings.ImageUploadEvent,async (a, imageFile) =>
{
_viewModel.Receipt.ImagePath = imageFile.FilePath;
_viewModel.Receipt.ImageName = imageFile.FileName;
try
{
await DependencyService.Get<IReceiptService>().SaveReceipt(_viewModel.Receipt);
}
catch (Exception ex)
{
await DisplayAlert(
"Error!", ex.Message, "OK");
}
DependencyService.Get<ICamera>().DeletePhoto(_viewModel._imageToBeDeletedOnSaveCommand);
Dialogs.HideLoading();
Application.Current.MainPage = new NavigationPage(new DashboardPage());
});
Unsubscription
protected override void OnDisappearing()
{
base.OnDisappearing();
MessagingCenter.Unsubscribe<App, string>((App)Application.Current, MessageStrings.ErrorEvent);
MessagingCenter.Unsubscribe<App, string>((App)Application.Current, MessageStrings.ImageUploadEvent);
}
Especially when using your page inside a navigationpage, your subscription event will be added whenever the page comes into view. If you navigate back and forward a couple of times, your subscription to the messagingcenter will be added several times causing your event to double fire.
The safest way is to subscribe in the page constructor and even in that case it can be necessary to unsubscribefirst and then subscribe.
Your Appearing/Disappearing approach might work as well, however I am not entirely sure if the Appearing/Disappearing methods give you any guarantee to fire.
However, you also might try moving your unsubscriptions in front of base.OnDisappearing(), since you should unsubscribe before calling the base class to do the internal dismantling of your page.
If that doesn't work, subscribe in the constructor.

"Cannot access a disposedObject" exception in Xamarin when attempting to send a byte[] to server

The old version of this question got too long so by the end of numerous attemts to solve this issue I came up that all can be taken down to a simple question. Why does this produce a SystemObjectDisposed.
private async void PickPhotoButton_OnClicked(object sender, EventArgs e)
{
_globalStream = await DependencyService.Get<IPicturePicker>
().GetImageStreamAsync();
_globalArray = StreamToByteArray(_globalStream);
var gal = new GalleryResource()
{
Pic = _globalArray
};
MemoryObjects.CurrentGallery = gal;
var ctr = HelperMethods.GetInstance<GalleryController>();
await ctr.Post();
}
public byte[] StreamToByteArray(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
The stream arrives from the native side, I turn it into a byte array and pass it into my repository. Everyting work with a dummy byte array so something is wrong with the stream object that possibly gets closed or disposed at point.
The exception is thrown in the repository at this point:
var response = await _client.PostAsync(endPoint, _repService.ConvertObjectToStringContent(obj));
ConvertObjectToStringContent(obj) - not this part of it. From here it actually returns with a value and the byte array is seen inside the debug ie. the byte array stay with a valid lenght all way through.
The only event that does take place when we do finish picking the photo from the library is the following:
void OnImagePickerFinishedPickingMedia(object sender,
UIImagePickerMediaPickedEventArgs args)
{
UIImage image = args.EditedImage ?? args.OriginalImage;
if (image != null)
{
// Convert UIImage to .NET Stream object
NSData data = image.AsJPEG(1);
Stream stream = data.AsStream();
// Set the Stream as the completion of the Task
taskCompletionSource.SetResult(stream);
}
else
{
taskCompletionSource.SetResult(null);
}
imagePicker.DismissModalViewController(true);
}
However it doesn't seem to dispose the stream and even if it did we already got a byte array from it.
Tried even doing this inside Native code
var client = new HttpClient();
var c = new MultipartFormDataContent();
c.Add(new StreamContent(image.AsJPEG(1).AsStream()));
var response = await client.PostAsync(Settings.EndPoint + "api/gallery/", c);
Same error.
I think your problem lies somewhere in this line _byteArray = ToByteArray(_array);
ToByteArray(stream) seems to return you the byte array maybe via conversion from a stream, and this stream might still have a reference to the bytearray. And it might have become disposed.
If it's inside this method, please post it, I wanna knowww
I'm not quite experienced enough to exactly tell what it is about, but maybe my suggestions will be hitting the right spot!
Btw your code looks real clean, I like it!
So, although this issue did come up in the first place with the CrossMedia plugin https://github.com/jamesmontemagno/MediaPlugin it did the same error.
However the error only comes up if you for instance pick a photo like this:
var _mediaFile = await CrossMedia.Current.PickPhotoAsync();
So, when I did this:
var _mediaFile = await CrossMedia.Current.PickPhotoAsync(new
Plugin.Media.Abstractions.PickMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Small,
CompressionQuality = 90,
});
The error went away. No idea why.

Why does GattCharacteristic.ReadValueAsync() return 20 zero bytes?

I have the following code I'm using to connect to a TruConnect Bobcat bluetooth module (https://ack.me/FAQs/What_are_the_UUID_s_used_by_TruConnect):
public async void Start()
{
Guid RX_UUID = Guid.Parse("1cce1ea8-bd34-4813-a00a-c76e028fadcb");
Guid TX_UUID = Guid.Parse("cacc07ff-ffff-4c48-8fae-a9ef71b75e26");
Guid ServiceGuid = Guid.Parse("175f8f23-a570-49bd-9627-815a6a27de2a");
var devices = await DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(ServiceGuid));
var service = await GattDeviceService.FromIdAsync(devices[0].Id);
var TXCharacteristic = service.GetCharacteristics(TX_UUID)[0];
GattReadResult result = await TXCharacteristic.ReadValueAsync(BluetoothCacheMode.Uncached);
byte[] buffer = (result.Value.ToArray());
}
The problem is that the buffer at the end always ends up with 20 zero bytes, even though my module is not sending anything. All this despite result.Status turns out to be Success.
This is what I've boiled it down to after trying to make it run in a bigger app and getting the same result.
Another interesting thing I've noticed is that I've tried the same approach on a WindowsHubApplication and it worked. Now, in a Universal App, it doesn't.
I've also tried both Cached and Uncached modes.
Thanks in advance
Problem solved!
I've initially tried subscribing to the Characteristic.ValueChanged event but the event handler never got called. Apparently it only works if you subscribe to the event AFTER you send the GattClientCharacteristicConfigurationDescriptorValue. (and I have absolutely no idea why, maybe someone can shed some light on this, but for now it works)
public async void Start()
{
Guid RX_UUID = Guid.Parse("1cce1ea8-bd34-4813-a00a-c76e028fadcb");
Guid TX_UUID = Guid.Parse("cacc07ff-ffff-4c48-8fae-a9ef71b75e26");
Guid ServiceGuid = Guid.Parse("175f8f23-a570-49bd-9627-815a6a27de2a");
var devices = await DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(ServiceGuid));
var service = await GattDeviceService.FromIdAsync(devices[0].Id);
var TXCharacteristic = service.GetCharacteristics(TX_UUID)[0];
var RXCharacteristic = service.GetCharacteristics(RX_UUID)[0];
await TXCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
TXCharacteristic.ValueChanged += TXCharacteristic_ValueChanged; ;
}
private void TXCharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
byte[] buffer = args.CharacteristicValue.ToArray();
}
Now I get very nice 20 byte buffers filled with actual valid data.

Resources