Xamarin forms - can't scan BLE devices - c#

I new in Xamarin forms and C#.
I am trying to scan BLE device using the native Xamarin forms API, the code attached. I am using the Xiomi note 5 running android 9.
using Android.Bluetooth;
using Android.Bluetooth.LE;
using Android.Runtime;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Xamarin.Forms;
namespace bletest
{
// Learn more about making custom code visible in the Xamarin.Forms previewer
// by visiting https://aka.ms/xamarinforms-previewer
[DesignTimeVisible(false)]
public class MyScanCallback : ScanCallback
{
public override void OnBatchScanResults(IList<ScanResult> results)
{
base.OnBatchScanResults(results);
}
public override void OnScanResult([GeneratedEnum] ScanCallbackType callbackType, ScanResult result)
{
base.OnScanResult(callbackType, result);
}
public override void OnScanFailed([GeneratedEnumAttribute] ScanFailure errorCode)
{
base.OnScanFailed(errorCode);
}
}
public class newbtle
{
private readonly BluetoothAdapter _ba;
private readonly BluetoothLeScanner _sc;
private readonly MyScanCallback _scCb;
public newbtle()
{
_ba = BluetoothAdapter.DefaultAdapter;
_sc = _ba.BluetoothLeScanner;
_scCb = new MyScanCallback();
}
public void BleScan()
{
if (_ba.Enable() == true)
{
_sc.StartScan(_scCb);
}
}
public void BleScanStop()
{
_sc.StopScan(_scCb);
_sc.FlushPendingScanResults(_scCb);
_ba.Disable();
}
public string GetScanMode()
{
return _ba.ScanMode.ToString();
}
public string GetStateMode()
{
return _ba.State.ToString();
}
}
public partial class MainPage : ContentPage
{
newbtle bt = new newbtle();
public MainPage()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
bt.BleScan();
}
private void Button_Clicked_1(object sender, EventArgs e)
{
bt.BleScanStop();
}
}
}
When a call is made to bt.BleScan no call back is called, when the bt.BleScan called in the second time without turning the scanner off the OnScanFailed is called with 'already active error'.
When I run the BLE explorer utility on the same mobile in the same environment it scan few BLE devices.
Any suggestion what can be the problem?
Thanks

Related

How to access local folder in an Android emulator to retrieve SQLite db?

I created a SQLite database to store data from a hypothetical application in which a user stores recipes:
using System;
using System.IO;
using DataAccesSQLite_scratch;
using SQLite;
using Xamarin.Forms;
[assembly: Dependency(typeof(SQLiteDb))]
namespace DataAccesSQLite_scratch
{
public class SQLiteDb : ISQLiteDb
{
public SQLiteAsyncConnection GetConnection()
{
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var path = Path.Combine(documentsPath, "MySQLite.db3");
return new SQLiteAsyncConnection(path);
}
}
}
and
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using SQLite;
using Xamarin.Forms;
namespace DataAccesSQLite_scratch
{
public class Recipe : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
private string _name;
[MaxLength(225)]
public string Name
{
get { return _name; }
set
{
// code below assures that if the value isn't changed, this event should not be called
if (_name == value)
return;
_name = value;
OnPropertyChanged();
}
}
}
public partial class MainPage : ContentPage
{
private SQLiteAsyncConnection _connection;
private ObservableCollection<Recipe> _recipes;
public MainPage()
{
InitializeComponent();
_connection = DependencyService.Get<SQLiteDb>().GetConnection();
}
// By convention use the "OnAppearing()" method and don't put underlying code in the constructor
protected override async void OnAppearing()
{
await _connection.CreateTableAsync<Recipe>();
var recipes = await _connection.Table<Recipe>().ToListAsync();
_recipes = new ObservableCollection<Recipe>(recipes);
recipesListView.ItemsSource = _recipes;
base.OnAppearing();
}
async void OnAdd(object sender, System.EventArgs e)
{
var recipe = new Recipe { Name = "Recipe" + DateTime.Now.Ticks };
await _connection.InsertAsync(recipe);
_recipes.Add(recipe);
}
async void OnUpdate(object sender, System.EventArgs e)
{
var recipe = _recipes[0];
recipe.Name += " UPDATED";
await _connection.UpdateAsync(recipe);
}
async void OnDelete(object sender, System.EventArgs e)
{
var recipe = _recipes[0];
await _connection.DeleteAsync(recipe);
_recipes.Remove(recipe);
}
}
}
All the methods work and are properly stored. So when I close the application and start it again, the data is persisted successfully. However, how can I access this data in my emulator? And how could I then export this data to e.g. a .csv or .json format? As can be seen, it should be in the SpecialFolder.MyDocuments. but I couldn't find it on the emulator itself.
Thanks in advance
However, how can I access this data in my emulator? And how could I then export this data to e.g. a .csv or .json format? As can be seen, it should be in the SpecialFolder.MyDocuments. but I couldn't find it on the emulator itself.
According to your sqlite database path, it is internal storage, you can not find the database file on an emulator unless it's rooted. Then you can find the database file in data/data/com.companyname/files.
Opening cmd, and enter Adb Root to root android emulator, then enter Adb shell to verify if it is successful.
If you want to export sqlite database to csv file, please take a look following thread:
Exporting SQLite Database to csv file in android

Xamarin displayalert not showing

I have xamarin form application and i connected it signalr not running my void. I searched on internet but I can't find anything about this. And this is my code
Myhub.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR.Client;
namespace PharmClient
{
class MyHub
{
string url = "https://webapplication11-co5.conveyor.cloud/";
HubConnection Connection;
IHubProxy ProxyOFServer;
public delegate void Error();
public delegate void MessageRecieved(string _data);
public event Error CoonectionError;
public event MessageRecieved OndataRecieved;
public delegate void Completed();
public event Completed OnCompleted;
public void Connect()
{
Connection = new HubConnection(url);
ProxyOFServer = Connection.CreateHubProxy("MuHub");
Start().ContinueWith(task => { if (task.IsFaulted) { CoonectionError?.Invoke(); } else { OnCompleted?.Invoke(); } });
}
public Task Start()
{
return Connection.Start();
}
public void SendData(string data)
{
ProxyOFServer.Invoke<string>("SendMessage", data);
}
public void Recive( )
{
ProxyOFServer.On<string>("Sentdata", data => { OndataRecieved?.Invoke(data); });
}
}
}
MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using System.Threading;
namespace PharmClient
{
// 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
{
MyHub ConnectServer = new MyHub();
public MainPage()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
ConnectServer.OnCompleted += ConnectServer_OnCompleted;
ConnectServer.CoonectionError += ConnectServer_CoonectionError;
ConnectServer.Connect();
}
private void ConnectServer_OnCompleted()
{
DisplayAlert("Connected", "Good", "O");
}
private void ConnectServer_CoonectionError()
{
DisplayAlert("Failed", "Bad", "Ok");
}
private void SerchDrug_Clicked(object sender, EventArgs e)
{
Navigation.PushAsync(new SearchDrug());
}
}
}
When connection failed ConnectionError event run but Connection will be successfully OnCompleted event won't run. I am student. This is part of group work. What is problem my code any Help. I can't found anything. Thanks for attention
As your title suggest, you have an issue with displaying a dialog box.
Try going through the documentation (here) once for complete understanding, you have to await the process of displaying DisplayAlert.
Add await & async to your methods.
Try this -
private async void ConnectServer_OnCompleted()
{
await DisplayAlert("Connected", "Good", "O");
}
private async void ConnectServer_CoonectionError()
{
await DisplayAlert("Failed", "Bad", "Ok");
}
If you have some issues regarding, let me know.
You should await connection not fire and forget. Example:
private HubConnection connection;
private IHubProxy proxy;
public event EventHandler<ChatMessageObject> OnMessageReceived;
public async Task Connect()
{
try
{
await connection.Start();
await proxy.Invoke("Connect"); // example method in your backend
proxy.On("messageReceived", (int userId, string name, string message, DateTime messageDateTime) => OnMessageReceived(this, new ChatMessageObject
{
FromUserId = userId,
UserName = name,
MessageText = message,
MessageDateTime = messageDateTime
}));
}
catch (Exception ex)
{
//handle exceptions
}
}

Close with timeout is not working in Console to close splashscreen

I have made a class, I make an instance of. In said instance I have these lines of code to show and close the splashscreen.
// Open (show)
public void ShowSplashScreen(bool autoClose = false)
{
splashscreen.Show(autoClose, true);
}
// Close (don't show)
public void CloseSplashScreen()
{
splashscreen.Close(TimeSpan.FromSeconds(0.3));
}
It shows up fine, but never closes, just stays there.
This is the documentation of splashscreen Close: https://learn.microsoft.com/en-us/dotnet/api/system.windows.splashscreen.close?view=netframework-4.8
[System.Security.SecurityCritical]
public void Close (TimeSpan fadeoutDuration);
Note: I am using the show method with the parameters AutoClose set to false, and TopMost set to true, this makes it not auto close as I want to close it programmatically and not subscribe to existing events.
I am running the lines of code from a Console (.NET framework) application for testing purposes before implementing it into my UI fully.
What I have tried:
Debugging and even trying to call show again before calling close.
It is definitely something going wrong with the class, as calling the class and directly manipulating the property works:
ClassSplashScreen rss = new ClassSplashScreen();
rss.splashscreen.Show(false);
rss.splashscreen.Close(TimeSpan.FromSeconds(1));
My best guess is something is hanging the UI and freezing it? But I am unsure what to do about it.
Code to run to test this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace NamespaceName
{
public class StackOverFlowCode
{
static void Main(string[] args)
{
ClassSplashScreen screen = new ClassSplashScreen();
screen.ShowSplashScreen();
screen.CloseSplashScreen();
}
}
public class ClassSplashScreen
{
public SplashScreen splashscreen { get; set; }
public ClassSplashScreen()
{
splashscreen = new SplashScreen("Resource Image Link");
}
public void ChangeSplashResource(SplashScreen resource)
{
splashscreen = resource;
}
public void ShowSplashScreen(bool autoClose = false)
{
splashscreen.Show(autoClose, true);
}
public void CloseSplashScreen()
{
splashscreen.Close(TimeSpan.FromSeconds(1));
}
}
}
The SplashScreen relies on a dispatcher but there is no one in a console application by default. If you create a System.Windows.Application, it should work as expected:
public class StackOverFlowCode
{
[STAThread]
static void Main(string[] args)
{
Application app = new Application();
app.Startup += (s, e) =>
{
ClassSplashScreen screen = new ClassSplashScreen();
screen.ShowSplashScreen();
screen.CloseSplashScreen();
};
app.Run();
}
}
public class ClassSplashScreen
{
private readonly SplashScreen splashscreen;
public ClassSplashScreen() => splashscreen = new SplashScreen("Resource Image Link");
public void ShowSplashScreen() => splashscreen.Show(false);
public void CloseSplashScreen() => splashscreen.Close(TimeSpan.FromSeconds(1));
}

errors when adding a microsoft login page

I'm using this step by step guide (https://blog.xamarin.com/authenticate-mobile-apps-using-microsoft-authentication-library/) to implement a microsoft login page to my app in which users have to login with a microsoft account. But I've gotten to step 3 and can't find a way to get rid of the errors.
Code in XAML:
<StackLayout HorizontalOptions="Center" VerticalOptions="Center">
<Button Text="Login" x:Name="LoginButton"/>
</StackLayout>
</ContentPage.Content>
Code in code behind (C#):
using System;
using System.Collections.Generic;
using Microsoft.Identity.Client;
using Xamarin.Forms;
namespace RoseySports
{
public partial class Login : ContentPage
{
public IPlatformParameters PlatformParameters { get; set; }
public Login()
{
InitializeComponent();
LoginButton.Clicked += LoginButton_Clicked;
}
protected override void OnAppearing()
{
App.ClientApplication.PlatformParameters = PlatformParameters;
base.OnAppearing();
}
private async void LoginButton_Clicked(object sender, EventArgs e)
{
try
{
AuthenticationResult ar = await App.ClientApplication.AcquireTokenAsync(App.Scopes);
WelcomeText.Text = $"Welcome {ar.User.Name}";
}
catch (MsalException ex)
{
WelcomeText.Text = ex.Message;
}
}
}
}
Code in App.xaml.cs:
using Xamarin.Forms;
using Microsoft.Identity.Client;
namespace RoseySports
{
public partial class App : Application
{
public static PublicClientApplication ClientApplication { get; set; }
public static string[] Scopes = { "User.Read" };
public App()
{
InitializeComponent();
ClientApplication = new PublicClientApplication("your-app-id");
var content = new Login();
MainPage = new NavigationPage(content);
MainPage = new Login_Page();
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}
And here is the screenshot with all the errors:error 1error 2error 3error 4
Also, could someone please explain to me where I should put this code in:
[assembly: ExportRenderer(typeof(Login), typeof(LoginPageRenderer))]
namespace MSALForForms.iOS
{
class LoginPageRenderer : PageRenderer
{
Login _page;
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
_page = e.NewElement as Login;
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
_page.PlatformParameters = new PlatformParameters(this);
}
}
}
You should add Microsoft.IdentityModel.Clients.ActiveDirectory as you're missing this reference as per the screenshot errors. You can get this by added by NuGet package in VS.
Right Click on References and click on "Manage NuGet Packages"
On Browse tab, type 'Microsoft.IdentityModel.Clients.ActiveDirectory' and install it by adding package.
Now use this namespace in your project. as - using Microsoft.IdentityModel.Clients.ActiveDirectory;

How to get finger positions in Leap Motion using C#

I want to get finger positions in Leap motion using c#.I'm new to leap motion controller. So i Couldn't find any example code for detecting finger positions, but i tried to come up with some code. I think it has lot of errors.
So, how to get finger positions in Leap Motion using C#?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Leap;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form, ILeapEventDelegate
{
private Controller controller;
private LeapEventListener listener;
public Form1()
{
InitializeComponent();
this.controller = new Controller();
this.listener = new LeapEventListener(this);
controller.AddListener(listener);
}
delegate void LeapEventDelegate(string EventName);
public void LeapEventNotification(string EventName)
{
if (!this.InvokeRequired)
{
switch (EventName)
{
case "onInit":
MessageBox.Show("onInit");
break;
case "onConnect":
MessageBox.Show("onConnect");
break;
case "onFrame":
MessageBox.Show("onFrame");
break;
}
}
else
{
BeginInvoke(new LeapEventDelegate(LeapEventNotification), new object[] {
EventName });
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
public interface ILeapEventDelegate
{
void LeapEventNotification(string EventName);
}
public class LeapEventListener : Listener
{
ILeapEventDelegate eventDelegate;
public LeapEventListener(ILeapEventDelegate delegateObject)
{
this.eventDelegate = delegateObject;
}
public override void OnInit(Controller controller)
{
this.eventDelegate.LeapEventNotification("onInit");
}
public override void OnConnect(Controller controller)
{
this.eventDelegate.LeapEventNotification("onConnect");
}
public override void OnFrame(Controller controller)
{
this.eventDelegate.LeapEventNotification("onFrame");
}
public override void OnExit(Controller controller)
{
this.eventDelegate.LeapEventNotification("onExit");
}
public override void OnDisconnect(Controller controller)
{
this.eventDelegate.LeapEventNotification("onDisconnect");
}
}
}
Your code looks like it is derived from the documentation example. However, you have left out the actual event handlers so nothing will ever happen.
You will see in the linked example that there is a newFrameHandler function. You can change that to access the finger positions in the frame object, which is a snapshot of the tracked hands at a moment in time.
void newFrameHandler(Frame frame)
{
foreach(Finger in frame.Fingers){
Vector fingerPosition = finger.TipPosition;
//Do something with this information...
}
}
You can similarly get the hands and then access each hand's fingers, which often is the more natural approach:
foreach(Hand hand in frame.Hands){
foreach(Finger in hand.Fingers){
Vector fingerPosition = finger.TipPosition;
//Do something with this information...
}
}

Categories