errors when adding a microsoft login page - c#

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;

Related

Xamarin forms - can't scan BLE devices

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

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
}
}

java.lang.IllegalArgumentException: No such service ComponentInfo{/com.SampleApp.AttendanceApp.ServiceClass}

I am using Xamarin Android to build an app which should allow the app to keep sending a driver's location every 15 minutes so that I can keep track of his movement. I used JobScheduler to get this done. My project is very simple now and only contains the following 3 files:
MainActivity.cs
AttendancePage.cs (Content page, interact with UI button to start the service)
ServiceClass.cs
Methods in Main Activity.cs
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
scheduler = (JobScheduler)GetSystemService(JobSchedulerService);
LoadApplication(new App()); //This line will then jump to AttendancePage.cs
}
public void ScheduleJob()
{
ComponentName componentName = new ComponentName(this, Java.Lang.Class.FromType(typeof(ServiceClass)));
JobInfo info = new JobInfo.Builder(123, componentName)
.SetPersisted(true)
.SetPeriodic(60000)
.Build();
int resultCode = scheduler.Schedule(info); //The error show when hit this line.
if (resultCode == JobScheduler.ResultSuccess)
{
Log.Info("Message", "Job Schedule!");
}
else
{
Log.Info("Message", "Job shceduling failed");
}
}
public void CancelJob()
{
scheduler.Cancel(123);
}
AttendancePage.cs
public partial class AttendancePage : ContentPage
{
MainActivity main = new MainActivity();
public AttendancePage()
{
InitializeComponent();
Title = "Attendance App";
}
//Button OnClickEvent
async void ScheduleJob(object s, EventArgs e)
{
main.ScheduleJob();
}
//Button OnClickEvent
async void CancelJob(object s, EventArgs e)
{
main.CancelJob();
}
}
ServiceClass.cs
[Service(Name = "com.SampleApp.AttendanceApp.ServiceClass", Permission = "android.permission.BIND_JOB_SERVICE")]
public class ServiceClass : JobService
{
public ServiceClass()
{
}
public override bool OnStartJob(JobParameters jobParamsOnStart)
{
doBackgroundWork(jobParamsOnStart);
return true;
}
private void doBackgroundWork(JobParameters jobParam)
{
//My code to send driver's location
TestingPage.GetGPS();
JobFinished(jobParam, false);
}
public override bool OnStopJob(JobParameters jobParamsOnStop)
{
return false;
}
}
I have added the service tag inside AndroidManifest.xml as well.
<service android:name=".ServiceClass"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true" />
I have no idea why the error is still there. The error is from the line scheduler.Schedule(JobInfo). Anyone has another possible solution? I am frustrated on solving this. Will the reason be I can't debug on the service but only can straight away run in release mode? Please help.
Froms shared code it works in Xamarin.Android project , however here is a Xamarin.Forms project . It can not work.
In AttendancePage.cs , you create a new MainActivity to invoke the native method ScheduleJob and CancelJob . This will not find the JobScheduler in native ,then it will return null .
No such service ComponentInfo{/com.SampleApp.AttendanceApp.ServiceClass}
If you want to invoke native method , you can have a try with DependencyService in Xamarin Forms .
At least need to create a Interface in Forms to invoke :
public interface IJobSchedulerService
{
//Start JobSchedule
void StartJobSchedule();
//Cancel JobSchedule
void CancelJobSchedule();
}
Then can invoke in Xamarin Forms as follow :
async void ScheduleJob(object s, EventArgs e)
{
DependencyService.Get<IJobSchedulerService>().StartJobSchedule();
}
//Button OnClickEvent
async void CancelJob(object s, EventArgs e)
{
DependencyService.Get<IJobSchedulerService>().CancelJobSchedule();
}
Now you need to implement the IJobSchedulerService in native android .Create the JobSchedulerDependcenyService:
public class JobSchedulerDependcenyService : IJobSchedulerService
{
JobScheduler jobScheduler;
public JobSchedulerDependcenyService()
{
jobScheduler = (JobScheduler)MainActivity.Instance.GetSystemService(Android.Content.Context.JobSchedulerService);
}
public void StartJobSchedule()
{
ComponentName componentName = new ComponentName(MainActivity.Instance, Java.Lang.Class.FromType(typeof(DownloadJob)));
JobInfo jobInfo = new JobInfo.Builder(1, componentName)
.SetOverrideDeadline(0)
.Build();
//var jobScheduler = (JobScheduler)GetSystemService(JobSchedulerService);
var scheduleResult = jobScheduler.Schedule(jobInfo);
if (JobScheduler.ResultSuccess == scheduleResult)
{
var snackBar = Snackbar.Make(MainActivity.Instance.FindViewById(Android.Resource.Id.Content), "jobscheduled_success", Snackbar.LengthShort);
snackBar.Show();
}
else
{
var snackBar = Snackbar.Make(MainActivity.Instance.FindViewById(Android.Resource.Id.Content), "jobscheduled_failure", Snackbar.LengthShort);
snackBar.Show();
}
}
public void CancelJobSchedule()
{
jobScheduler.CancelAll();
}
}
Here you will find the MainActivity.Instance inside it , that's a static instance defined by self in MainActivity.
public static MainActivity Instance { set; get; }
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Instance = this;
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}

Is it possible to show DisplayAlert on startup (Xamarin.Forms)

In my mobile application (xamarin forms), I'm getting data from internet so it needs internet connection. Since I have a dictionary which I initialize in App.xaml.cs and I use data from internet, I need to check for internet connection. I have seen this question where OP asks for something similar, but the answer doesn't work for me since I need to check for internet connection whenever app launches, not after MainPage is launched. For example, Clash of Clans. Whenever the app launches, the app checks for internet connection and if there's no connection, it displays a alert to user repetitively until there's a connection.
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Collections.Generic;
using HtmlAgilityPack;
using System.Text.RegularExpressions;
using System;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace Multi
{
public partial class App : Application
{
static GroupStage groupstage = new GroupStage();
public static HtmlWeb web = new HtmlWeb();
public static HtmlDocument doc = LoadUrlAndTestConnection();
//The reason why I have put a method is because I wanted to try if I can use try-catch to display alert, however this didn't work.
public static HtmlDocument LoadUrlAndTestConnection()
{
bool con = true;
while (con)
{
try
{
doc = web.Load(someURL);
}
catch (Exception ex)
{
var sth = new ErrorPage();
sth.InternetErrorDisplay();
con = true;
continue;
}
con = false;
}
return docSK;
}
public static Dictionary<string, Country> _countries = new Dictionary<string, Country>
{
["Australia"] = new Country(1, "Australia", false, "AU", "ausFlag.png", 3, groupstage, GetScore("Australia", 3)),
public static string[] GetScore(string name, int GroupID)
{
//Gets the score data from internet
}
public App()
{
InitializeComponent();
TwitchClass.MainAsync().Wait();
MainPage = new OpeningPage();
}
protected override void OnStart()
{
}
protected override void OnSleep()
{
}
protected override void OnResume()
{
}
}
}
//GetScore method requires internet connection as it gets the score data from internet.
and the InternetErrorDisplay method is,
public void InternetErrorDisplay() => DisplayAlert("Connection Error", "Could not detect internet connection. This application requires access to internet.", "Retry");
Is it possible to have this behaviour in xamarin forms app? How can I achieve it?
Yes, why should it not be possible?
Here is an example which uses async/await
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Threading.Tasks;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace LoadingSample
{
public partial class App : Application
{
public App()
{
InitializeComponent();
//MainPage = new MainPage();
}
protected override async void OnStart()
{
// shows Loading...
MainPage = new LoadPage();
await Task.Yield();
// Handle when your app starts
// Just a simulation with 10 tries to get the data
for (int i = 0; i < 10; i++)
{
await Task.Delay(500);
// await internet_service.InitializeAsync();
await MainPage.DisplayAlert(
"Connection Error",
"Unable to connect with the server. Check your internet connection and try again",
"Try again");
}
await Task.Delay(2000);
// after loading is complete show the real page
MainPage = new MainPage();
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}

24 hours TimePicker with Focused and Unfocused events

I tried implementing 24 Hour Time Picker as given here 24 Hour TimePicker in XF project.
But it doesn't fire the Focus and Unfocused event on Android. Has anyone implemented this?
Here is a completed sample: https://github.com/brminnick/24HourTimePicker
Explanation
The author of this custom control forgot to fire Focused and Unfocused in the Android Custom Renderer.
We can fire these events by calling ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, [true/false]); from the Android Custom Renderer when FocusChanged fires.
This custom Android control also doesn't clear focus once the time is set, so we'll add ClearFocus() to OnTimeSet too.
Xamarin.Forms 2.4 Code
Because the sample was written in Xamarin.Forms v2.4, here's the answer if you are continuing with Xamarin.Forms v2.4.
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using TimePickerDemo.CustomControls;
using TimePickerDemo.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CustomTimePicker24H), typeof(CustomTimePicker24HRenderer))]
namespace TimePickerDemo.Droid
{
public class CustomTimePicker24HRenderer : ViewRenderer<Xamarin.Forms.TimePicker, Android.Widget.EditText>, TimePickerDialog.IOnTimeSetListener, IJavaObject, IDisposable
{
private TimePickerDialog dialog = null;
IElementController ElementController => Element as IElementController;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TimePicker> e)
{
base.OnElementChanged(e);
this.SetNativeControl(new Android.Widget.EditText(Forms.Context));
this.Control.Click += Control_Click;
this.Control.Text = DateTime.Now.ToString("HH:mm");
this.Control.KeyListener = null;
this.Control.FocusChange += Control_FocusChange;
}
void Control_FocusChange(object sender, Android.Views.View.FocusChangeEventArgs e)
{
if (e.HasFocus)
{
ShowTimePicker();
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true);
}
else
{
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
}
}
void Control_Click(object sender, EventArgs e)
{
ShowTimePicker();
}
private void ShowTimePicker()
{
if (dialog == null)
{
dialog = new TimePickerDialog(Forms.Context, this, DateTime.Now.Hour, DateTime.Now.Minute, true);
}
dialog.Show();
}
public void OnTimeSet(Android.Widget.TimePicker view, int hourOfDay, int minute)
{
var time = new TimeSpan(hourOfDay, minute, 0);
this.Element.SetValue(Xamarin.Forms.TimePicker.TimeProperty, time);
this.Control.Text = time.ToString(#"hh\:mm");
this.ClearFocus();
}
}
}
Xamarin.Forms 2.5+ Answer
Xamarin.Forms v2.5 deprecated Forms.Context and also requires an overloaded constructor to be used for Custom Renderers.
To replace Forms.Context, we'll need to install the Plugin.CurrentActivity NuGet Package.
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using TimePickerDemo.CustomControls;
using TimePickerDemo.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CustomTimePicker24H), typeof(CustomTimePicker24HRenderer))]
namespace TimePickerDemo.Droid
{
public class CustomTimePicker24HRenderer : ViewRenderer<Xamarin.Forms.TimePicker, Android.Widget.EditText>, TimePickerDialog.IOnTimeSetListener, IJavaObject, IDisposable
{
private TimePickerDialog dialog = null;
public CustomTimePicker24HRenderer(Context context) : base(context)
{
}
Context CurrentContext => Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity;
IElementController ElementController => Element as IElementController;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.TimePicker> e)
{
base.OnElementChanged(e);
this.SetNativeControl(new Android.Widget.EditText(CurrentContext));
this.Control.Click += Control_Click;
this.Control.Text = DateTime.Now.ToString("HH:mm");
this.Control.KeyListener = null;
this.Control.FocusChange += Control_FocusChange;
}
void Control_FocusChange(object sender, Android.Views.View.FocusChangeEventArgs e)
{
if (e.HasFocus)
{
ShowTimePicker();
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true);
}
else
{
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
}
}
void Control_Click(object sender, EventArgs e)
{
ShowTimePicker();
}
private void ShowTimePicker()
{
if (dialog == null)
{
dialog = new TimePickerDialog(CurrentContext, this, DateTime.Now.Hour, DateTime.Now.Minute, true);
}
dialog.Show();
}
public void OnTimeSet(Android.Widget.TimePicker view, int hourOfDay, int minute)
{
var time = new TimeSpan(hourOfDay, minute, 0);
this.Element.SetValue(Xamarin.Forms.TimePicker.TimeProperty, time);
this.Control.Text = time.ToString(#"hh\:mm");
this.ClearFocus();
}
}
}

Categories