Xamarin BluetoothLE Plugin not working - xamarin

I created a new Xamarin.Forms app to test basic Bluetooth functionality. I downloaded this plugin into both the Android project and the shared project:
https://github.com/aritchie/bluetoothle
I wrote this function in the shared project and am calling it from the OnCreate of my launch activity in my Android project:
public static async Task BroadcastBluetooth()
{
// (I do not await this function when I call it)
try
{
await Task.Delay(5000); // just to make sure we give enough time for all initialization to complete
_server = CrossBleAdapter.Current.CreateGattServer();
// exception thrown on this line
await _server.Start(new AdvertisementData
{
LocalName = "TestServer",
ServiceUuids = new List<Guid>()
});
}
catch (Exception e)
{
}
}
It throws this exception:
{System.NullReferenceException: Object reference not set to an
instance of an object. at
Plugin.BluetoothLE.Server.GattServer.StartAdvertising
(Plugin.BluetoothLE.Server.AdvertisementData adData) [0x00095] in
C:\dev\acr\bluetoothle\Plugin.BluetoothLE.Android\Server\GattServer.cs:135
at Plugin.BluetoothLE.Server.GattServer.Start
(Plugin.BluetoothLE.Server.AdvertisementData adData) [0x00011] in
C:\dev\acr\bluetoothle\Plugin.BluetoothLE.Android\Server\GattServer.cs:70
at App2.App+d__7.MoveNext () [0x00097] in
C:\Projects\app2\App2\App2\App.xaml.cs:49 }
I'm only doing something really basic so I must be missing something? The exception is referencing a directory path of the plugin's developer's machine (C:\dev\acr...) so either this plugin is broken or I'm doing something really wrong?

I am using the same plugin in a current project of mine and it is working fine. So I doubt the issue is within the plugin.
Some thoughts about what could cause the issue:
Are you testing this code on a real device that is capable of performing BLE Advertisement?
Do you have set the permissions accordingly in your android project?
Does BLE Advertising work when you use the native android apis?
It also would be helpful, if you could attach a repository with which I can reproduce the issue.

Related

How to import Activity of NfcFCardEmulation.EnableService from Xamarin common project, not Android project?

I'm developing an app using Xamarin's HCE feature.
The project structure is as follows.
hceSample
hceSample.Android
hceSample.iOS
I am implementing hce simulation code called hceService in hceSample, not hceSample.Android.
A function called Enable_Card exists in the hce service, and you want to use the NfcFCardEmulation.EnableService function in that function.
Activity and ComponentName are requested as parameters of the function.
The ComponentName area was handled easily, but I don't know how to get the Activity. Please advise.
This is the contents of enable_Card function of hceService.
private Activity activity = null;
private bool enable_Card(cardModel card)
{
try
{
sid = card.cardSN;
tag = "Felica";
emulation.EnableService(, componentName); //<- How to get Activity??
emulation.SetNfcid2ForService(componentName, sid);
return true;
}
catch
{
return false;
}
}
This is my first time asking a question on Stackoverflow.
I would appreciate it if you could point out any missing or incorrect parts.
I trying this
activity = Xamarin.Essentials.Platform.CurrentActivity; //<- this function is not found!
Added missing information!
The namespace of the Enable_Card function is located in hceSample.Service.
Are you using the NfcFCardEmulation.EnableService(Activity, ComponentName) Method, right?
The method is an android api from android sdk,you cannot use it directly in xamarin.form(yours is hceSample) project.
If you want to call the function in xamarin form project(hceSample) from native platform(hceSample.Android, or hceSample.iOS),you can use Xamarin.Forms DependencyService to achieve this.
The DependencyService class is a service locator that enables Xamarin.Forms applications to invoke native platform functionality from shared code.
For more information about DependencyService, you can check document Xamarin.Forms DependencyService. And there is a sample included in above document,which is helpful for you to understand DependencyService.
Note:
We recognize that hardware service is the right and ideal way to
implement in each OS project. However, I'm curious if there is a way
to code Android and iOS at the same time
Since the api you used is from android sdk, you can call it in native android or use DependencyService to call it on xamarin.form(yours is hceSample) project.
If you call it on xamarin.form(yours is hceSample) project, you also need to find the the corresponding function or interface in iOS.

Xamarin.Android Java bindings library runtime failure accessing native library

TL;DR: I am looking for a way to find and extract a native shared library (.so) file from an Android device that is running a vendor-specific custom Android build. I need this file as the missing piece in a Xamarin.Android Java bindings library.
I am attempting to create a Xamarin.Android bindings library for a Java SDK that exposes laser barcode scanning APIs on Famoco's Android devices. These devices run a vendor-specific Android build, which supports some special features, such as centralized device management.
I followed the usual procedures to create the bindings library, without using any custom transforms or additions, and there were no compiler errors.
Here is the factory method, generated within the bindings library, that attempts to create a new BarCodeReader instance:
[Register ("open", "(ILandroid/content/Context;)Lcom/zebra/adc/decoder/BarCodeReader;", "")]
public static unsafe global::Com.Zebra.Adc.Decoder.BarCodeReader Open (int readerId, global::Android.Content.Context context)
{
const string __id = "open.(ILandroid/content/Context;)Lcom/zebra/adc/decoder/BarCodeReader;";
try {
JniArgumentValue* __args = stackalloc JniArgumentValue [2];
__args [0] = new JniArgumentValue (readerId);
__args [1] = new JniArgumentValue ((context == null) ? IntPtr.Zero : ((global::Java.Lang.Object) context).Handle);
var __rm = _members.StaticMethods.InvokeObjectMethod (__id, __args);
return global::Java.Lang.Object.GetObject<global::Com.Zebra.Adc.Decoder.BarCodeReader> (__rm.Handle, JniHandleOwnership.TransferLocalRef);
} finally {
}
}
The above code fails while executing the following line:
var __rm = _members.StaticMethods.InvokeObjectMethod (__id, __args);
An exception is thrown: No implementation found for void com.zebra.adc.decoder.BarCodeReader.native_setup(java.lang.Object, int, java.lang.Object).
I learned from the troubleshooting guidelines that this type of failure is typically caused by the inability to resolve a required native library.
In an attempt to confirm this as the cause, I used JD-GUI to decompile the Famoco JAR, from which I extracted the following snippets of the implementation code:
// This is the underlying Java implementation of the above bindings library factory method
public static BarCodeReader open(int readerId, Context context)
{
return new BarCodeReader(readerId, context);
}
// This is the BarCodeReader constructor that is called by the factory method
BarCodeReader(int readerId, Context context)
{
this.mEventHandler = null;
this.mAutoFocusCallback = null;
this.mDecodeCallback = null;
this.mErrorCallback = null;
this.mPreviewCallback = null;
this.mSnapshotCallback = null;
this.mVideoCallback = null;
this.mZoomListener = null;
Looper aLooper = Looper.myLooper();
if (null == aLooper) {
aLooper = Looper.getMainLooper();
}
if (aLooper != null) {
this.mEventHandler = new EventHandler(this, aLooper);
}
native_setup(new WeakReference(this), readerId, context);
}
// This method is called by the above constructor, but fails because no implementation exists
private final native void native_setup(Object paramObject, int paramInt);
It seems to me that the above runtime error is occurring because the private method native_setup is not implemented within the Java code, but separately within a native library that is not referenced anywhere within my bindings library project. Does this seem like a reasonable diagnosis?
Unfortunately, I didn't find any .so (native library) files within the SDK kit supplied by Famoco. I have contacted their support team, who stated that it is not necessary to link an .so file when consuming their SDK JAR. Famoco are not keen to support cross-platform apps on their devices, but they did confirm that they have other customers using Xamarin, who appear to have solved this problem. Unfortunately, Famoco support don't seem able to tell me how to achieve this.
Could it be that the required native library already exists on the device (deployed as part of the custom Android build)? To verify this hypothesis, I installed the Famoco sample laser scanning app, which runs correctly, even though there is no sign of a .so file within its project source kit.
If so, is it feasible to find and extract the .so file from the Android environment and how should I do this?
Yes, the libbarcodereader44.so file should be preinstalled on the custom device. It may be either in the /system/lib or in the /vendor/lib directory. You must load this library from your code before calling the open () method. Here you can find more details about the Famoco SDK.

How do I deal with a possible exception in a Xamarin Forms application deployed to iOS or Android?

I have a finished application which I would like to make available to run on the iOS and Android platforms.  I have tested the application as much as possible and it works without problem.  But I know there is always the chance that something might go wrong and I could get an exception.
My question is how can I deal with this or what should I do. What happens on the phone, if a Forms application is deployed and there is an exception.
Would appreciate any advice or even links as to how this is handled.
If an exception is thrown and not handled by your code, the app will stop working (i.e. crash).
In order to handle these crashes we are using MS AppCenter (the successor to HockeyApp/Xamarin AppInsights).
You'll have to create a project there (one for each platform), and add the NuGet package to your projects. Afterwards you can initialize it with
AppCenter.Start("ios={Your App Secret};android={Your App Secret}",
typeof(Crashes)); // you'll get the app secrets from appcenter.ms
Crashes will be logged to AppCenter now and you'll be informed whenever there is a new crash.
Please note that it's best practice (if not required by law), that you ask the user for consent before sending the crash report (see here). You are using the delegate Crashes.ShouldAwaitUserConfirmation for that matter. You could for example show an action sheet with Acr.UserDialogs
private bool AwaitUserConfirmation()
{
// you should of course use your own strings
UserDialogs.Instance.ActionSheet(
new ActionSheetConfig
{
Title = "Oopsie",
Message = "The app crashed. Send crash to developers.",
Options = new List<ActionSheetOption>
{
new ActionSheetOption("Sure", () => Crashes.NotifyUserConfirmation(UserConfirmation.Send)),
new ActionSheetOption("Yepp, and don't bug be again.", () => Crashes.NotifyUserConfirmation(UserConfirmation.AlwaysSend)),
new ActionSheetOption("Nope", () => Crashes.NotifyUserConfirmation(UserConfirmation.DontSend))
}
});
return true;
}

NotlmplementedException in Xamarin.Forms (PCL) project

I'm programming in Xamarin.Forms (PCL), and I have seen many post but none one works for me. I'm using the plugin PhoneCall.Forms.Plugin
I made a method to call with a button that contains the next code
try
{
var PhoneCallTask = CrossMessaging.Current.PhoneDialer;
if (PhoneCallTask.CanMakePhoneCall)
{
PhoneCallTask.MakePhoneCall("+528331607211", "Laura");
}
else
{
DisplayAlert("Llamada", "No se puede hacer llamada", "Ok");
}
}
It throws an error:
System.NotlmplementedException: This functionality is not implemented in the portable version of this assembly. You should reference the NuGet package from your main application project in order to reference the platform-specific implementation.
Have you tried the Messaging plugin?
Like said by Jason here.
Try:
Device.OpenUri(new Uri("tel:528331607211"));
If you are using this plugin (I'm not sure if this is the specific one you're using or not), then you need to make the phone call using a Dependency service (This is explained in the plugin readme).
Make a method in your PCL project to call the dependancy service:
private void QCall(string number)
{
var notificator = DependencyService.Get<IPhoneCall>();
notificator.MakeQuickCall (number);
}
In each platform specific project, initialize the plugin. For Android, this will be done in the OnCreate method of your MainActivity, and for iOS in AppDelegate in the FinishedLaunching method. Add the following line to each after the initialization of Xamarin.Forms:
PhoneCallImplementation.Init();
Then when you call QCall() in your PCL project it will run the code necessary for the specific platform the user is on.

Visual Studio android emulator httprequest fails

So I've been working on a xamarin PCL project targeting android and windows store app and I've had this issue for about two weeks now. One of the very first things this app does is to make an http request to a yahoo service when the user tries to search for something.
Now, on the windows store app project, this works just fine. However, whenever I'm debugging the android project, this fails miserably. It times out and I get a TaskAbortedException.
I've navigated with the browser within the android emulator to the restful service url and I do get a response in the browser but nothing when I make the http request. I have tried everything I could think of but no cigar. I have researched this for weeks now and I have yet to find an answer. It should be noted that I'm making the request within the PCL project with HttpClient.
Here's the code where this happens:
var queryUrl = string.Format(QUERY_URL_TEMPLATE, TickerSearch);
try
{
var requestTask = httpClient.GetStringAsync(queryUrl);
requestTask.ContinueWith(t =>
{
var responseDto = JsonConvert.DeserializeObject<TickerSearchResultDto>(t.Result);
TickerSearchResults = responseDto.ResultSet.Result;
});
}
catch (Exception ex)
{
}
Any help is greatly appreciated.

Resources