Detect network changes in Xamarin Forms - xamarin

I want to detect when the user is online or offline.
I am using CrossConnectivity package to detect connectivity changes.
I have to connect to VPN (Sonic Wall to be exact) in order to connect to my server.
My problem is this: When I am connecting to my server, I need to switch apps in order for me to connect to my server. When I switch back to my app the function SyncFunction.SyncUser(host, database, contact, ipaddress, pingipaddress) is not executing. The connectivity changed function is not on my App.xaml.cs it is on my Main Menu Content page because I need the sync function to be executed in my main menu not the whole app. How can I fix this?
CrossConnectivity.Current.ConnectivityChanged += async (sender, args) =>
{
var appdate = Preferences.Get("appdatetime", String.Empty, "private_prefs");
if (string.IsNullOrEmpty(appdate))
{
Preferences.Set("appdatetime", DateTime.Now.ToString(), "private_prefs");
}
else
{
if (DateTime.Now >= DateTime.Parse(Preferences.Get("appdatetime", String.Empty, "private_prefs")))
{
Preferences.Set("appdatetime", DateTime.Now.ToString(), "private_prefs");
if (CrossConnectivity.Current.IsConnected)
{
var ping = new Ping();
var reply = ping.Send(new IPAddress(pingipaddress), 5000);
if (reply.Status == IPStatus.Success)
{
lblStatus.Text = "Syncing data to server";
lblStatus.BackgroundColor = Color.FromHex("#2bcbba");
await Task.Delay(5000);
SyncFunction.SyncUser(host, database, contact, ipaddress, pingipaddress);
lblStatus.Text = "Online - Connected to server";
lblStatus.BackgroundColor = Color.FromHex("#2ecc71");
}
else
{
lblStatus.Text = "Online - Server unreachable. Connect to VPN";
lblStatus.BackgroundColor = Color.FromHex("#e67e22");
}
}
else
{
lblStatus.Text = "Offline - Connect to internet";
lblStatus.BackgroundColor = Color.FromHex("#e74c3c");
}
}
else
{
await DisplayAlert("Application Error", "It appears you change the time/date of your phone. Please restore the correct time/date", "Got it");
await Navigation.PopToRootAsync();
}
}
};

Detecting connectivity change across a VPN is not easy.
A workaround solution is to use a webservice as ping.
If you have a backend with API, this "ping" can be executed regularly to ensure the network AND the API are accessible.
This solution is to be used in addition to the connectivity check
Subscribe to connectivity changed
When conectivity looks OK, check the "ping service"
Typically in a mob app, this "ping endpoint" can be something like "/about".
Moreover, this specific service can be use to perform the compatibility version check beetween App Mob version and API version.
(look also Xamarin.Essentials to replace CrossConnectivity by Xamarin.Essentials: Connectivity, https://learn.microsoft.com/fr-fr/xamarin/essentials/connectivity?context=xamarin%2Fxamarin-forms&tabs=android)

Related

Trouble with connecting to wifi in code in Xamarin

I've been trying to connect to a specific wifi through code, but with no succcess.
This is what i've come up with:
public void ConnectToWifi(string ssid, string password)
{
WifiManager wifiManager = (WifiManager)Android.App.Application.Context.GetSystemService(Context.WifiService);
if (!wifiManager.IsWifiEnabled)
{
wifiManager.SetWifiEnabled(true);
}
string formattedSsid = $"\"{ssid}\"";
string formattedPassword = $"\"{password}\"";
WifiConfiguration wifiConfig = new WifiConfiguration
{
Ssid = formattedSsid,
PreSharedKey = formattedPassword
};
var addNetwork = wifiManager.AddNetwork(wifiConfig);
WifiConfiguration network = wifiManager.ConfiguredNetworks.FirstOrDefault(n => n.Ssid == ssid);
if (network == null)
{
Console.WriteLine($"Cannot connect to network: {ssid}");
return;
}
wifiManager.Disconnect();
bool enableNetwork = wifiManager.EnableNetwork(network.NetworkId, true);
}
I've added permissions.
When testing it does turn the wifi on atleast, so i know it works until that point. What seems not to be working is the AddNetwork part.
I appreciate any help i can get!
You are missing one key method - reconnect(). You can read more about it in the WifiManager's docs here
The important part of the documentation is:
Reconnect to the currently active access point, if we are currently disconnected.
So, what you need to do it after you have disconnected and enabled your new network, call in the end this and you will be good to go:
wifiManager.Disconnect();
wifiManager.EnableNetwork(network.NetworkId, true);
wifiManager.Reconnect(); // This is the missing method
NB: Keep in mind that most of the WifiManager's code that you are using is being obsolete starting Android 10. So, if you want to target Android 10, then you will need to write an additional code for the connectivity for devices with Android 10+.

PostAsync hanging in Xamarin Forms works on emulator but hangs on actual Mobile phone

I have Xamarin Forms project where I'm trying to POST and GET data to/from a Web API but when I'm making an async/await call, it works on the emulator (not without its original problems!) but when I try it on my actual phone mobile (Samsung S8+), it just hangs indefinitely.
Note that I'm only concentrating on the Android part right now, not iOS, not that the problem should make any difference in either.
This is the code I'm using:
IDataService.cs
Task<TResponse> PostDataAsync<TRequest, TResponse>(string uri, TRequest data)
where TRequest : class
where TResponse : class;
DataService.cs:
public async Task<TResponse> PostDataAsync<TRequest, TResponse>(string
additionalUri, TRequest data)
where TRequest : class
where TResponse : class
{
return await WebClient
.PostData<TRequest, TResponse>
(string.Concat(this.Uri, additionalUri), data);
}
WebClient.cs
using (var client = new HttpClient())
{
var jsonData = JsonConvert.SerializeObject(data);
using (var response = await client.PostAsync(
uri,
new StringContent(jsonData,
Encoding.UTF8,
"application/json" )))
{
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<TResponse>(content);
}
}
}
Method 1:
LoginPageViewModel.cs
public DelegateCommand SignInCommand => _signInCommand ??
(this._signInCommand = new DelegateCommand(SignInCommandAction));
private async void SignInCommandAction()
{
try
{
....
var user = await this._dataService
.PostDataAsync<LoginRequestDto,
LoginResponseDto>(#"Accounts/Login", loginRequestDto);
....
}
...
}
Method2:
LoginPageViewModel.cs
public DelegateCommand SignInCommand => _signInCommand ??
(this._signInCommand =
new DelegateCommand(async () => await SignInCommandAction()));
private async Task SignInCommandAction()
{
try
{
....
var user = await this._dataService
.PostDataAsync<LoginRequestDto,
LoginResponseDto>(#"Accounts/Login", loginRequestDto);
....
}
...
}
The PostDataAsync works with both methods when I call my local web API i.e. http://10.0.2.2/MyApp/api/ but both methods still hangs when calling external my web service from web provider i.e. http://myapp-123-site.atempurl.com/api/ which is a temp url for testing purpose.
The same apply to my GetDataAsync which is not demonstrated in question but I just thought I'd mention it.
Based on the above, you would think that my async/await code is correct since it works when calling the local web api but then what's causing it to hang when calling the remote web api.
As mentioned, I did enable my INTERNET permission in the manifest.
Any suggestions welcomed?
Thanks.
UPDATE-1:
Note that I've just tried to call a GET opertation within the same function and this is working in the emulator but hanging with the actual mobile.
using (var client = new HttpClient())
{
using (var response = await client.GetAsync(uri))
{
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
return Newtonsoft.Json.JsonConvert
.DeserializeObject<TResponse>(content);
}
}
}
UPDATE-2:
This is somehow working and I have no idea why! The only thing that comes to mind is that I upgraded my libraries. This included PRISM which may have been at the source of the problem but I have no idea.
Sorry I can't provide more details. I could role back my code and try to see if it's hanging again but I just don't have the time to go and experiment some more considering the amount of time I've already spent on this. Sorry.
The requested url is an IP or a domain name.
If it is ip, only the IP of the public network can be accessed by devices on multiple network segments.
If it is a domain name, it needs to support the domain name resolution service.
If you do not have these environments for a while, you need the IP of the device and the IP of the server on the same network segment.
The PostDataAsync works with both methods when I call my local web API i.e. http://10.0.2.2/MyApp/api/ but both methods still hangs when calling external my web service from web provider i.e. http://myapp-123-site.atempurl.com/api/ which is a temp url for testing purpose.
From this phenomenon , the reason should be the temp url. From this domain name (myapp-123-site.atempurl.com) can not find the right local IP (10.0.2.2).And when you test in local network , I guess this will work.However the network of actual mobile can be not the same with local network , such as using 3G/4G network , then this will not working.

PNRP stops working windows 10 1803

I had some code that uses PNRP to discover peers on network. Everything works fine since Windows 10 update 1803.
public void Init()
{
try
{
_ServiceUrl = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => address.AddressFamily == AddressFamily.InterNetwork).Select(address => _Address = address).Select(address => $"net.tcp://{address}:{Port}/SiemensVR").FirstOrDefault();
if (string.IsNullOrEmpty(_ServiceUrl)) return;
_LocalProxy = new PeerProxy(_EventAggregator, this);
_Host = new ServiceHost(_LocalProxy, new Uri(_ServiceUrl));
var binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.None;
_Host.AddServiceEndpoint(typeof(IPeerContract), binding, new Uri(_ServiceUrl));
_Host.Open();
_PeerName = new PeerName(PEER_NAME_ID, PeerNameType.Unsecured);
_PeerNameRegistration = new PeerNameRegistration(_PeerName, Port) { Cloud = Cloud.AllLinkLocal };
_PeerNameRegistration.Comment = _UserId.ToString();
_PeerNameRegistration.Start();
ResolvePeers();
}
finally { }
}
private async void ResolvePeers()
{
var resolver = new PeerNameResolver();
resolver.ResolveProgressChanged += OnResolveProgressChanged;
resolver.ResolveCompleted += (s, e) =>
{
Console.WriteLine("Completed");
};
resolver.ResolveAsync(_PeerName, this);
await Task.Delay(1000);
resolver.ResolveAsyncCancel(this);
}
Does MS have replace PNRP by something ?
I already tested to activate pnrp services, reinstall teredo tunneling and more.
Microsoft has deprecated and is in the process of removing PNRP.
You're out of luck, since its service and client APIs are being removed completely.
See https://learn.microsoft.com/en-us/windows/deployment/planning/windows-10-deprecated-features
Having the same issue here... Let me know if you find any resolution.
Previously, our application works fine, but on 1803 it doesn't work anymore. I can see the cloud start to synchronize and then each peer just ends up going to status alone.
Same issue, I found a Microsoft note to set the following services to Automatic Delayed Start:
Computer Browser (Browser) <- Set to Automatic, not delayed start
Function Discovery Provider Host (FDPHost)
Function Discovery Resource Publication (FDResPub)
Network Connections (NetMan)
UPnP Device Host (UPnPHost)
Peer Name Resolution Protocol (PNRPSvc)
Peer Networking Grouping (P2PSvc)
Peer Networking Identity Manager (P2PIMSvc)
But it didn't resolve the issue.
Any progress in resolving this?

Opentok | Get online users

This is my code for opentok connect. How to know when other user connected or disconnected to the session ? So i can populate my online friends list like social network site. Then i can initiate a chat with them.
function connect() {
OT.on("exception", exceptionHandler);
// Un-comment the following to set automatic logging:
OT.setLogLevel(OT.DEBUG);
if (!(OT.checkSystemRequirements())) {
alert("You don't have the minimum requirements to run this application.");
} else {
session = OT.initSession(sessionId); // Initialize session
session.connect(apiKey, token);
// Add event listeners to the session
session.on('sessionConnected', sessionConnectedHandler);
session.on('sessionDisconnected', sessionDisconnectedHandler);
session.on('connectionCreated', connectionCreatedHandler);
session.on('connectionDestroyed', connectionDestroyedHandler);
session.on('streamCreated', streamCreatedHandler);
session.on('streamDestroyed', streamDestroyedHandler);
session.on("signal", signalEventHandler);
}
}
function sessionConnectedHandler(event) {
// i am connected .... do something after connected
document.getElementById("User_name").innerHTML = user_name;
document.getElementById("disconnectLink").style.display = 'block';
//startPublishing();
}
The function connectionCreatedHandler will get called each time another user connects, and connectionDestroyedHandler will get called each time a user disconnects.
For a sample app that has a "Buddy List" like functionality, see Presence Kit. Demo: http://presencekit-php.herokuapp.com/

Can't singin into SkyDrive account. WP7

I am making SkyDrive integration in my app for Windows phone. Every time after login screen in signInButton_SessionChanged it gives me e.Status = Unknown with e.Error = "".
I tried download some examples for SkyDrive integration
http://rabeb.wordpress.com/2012/01/07/using-skydrive-in-your-windows-phone-applications-part-1/
, but it gives the same result.
private void signInButton1_SessionChanged(object sender, Microsoft.Live.Controls.LiveConnectSessionChangedEventArgs e)
{
if (e.Status == LiveConnectSessionStatus.Connected)
{
session = e.Session;
client = new LiveConnectClient(session);
infoTextBlock.Text = "Signed in.";
}
else
{
infoTextBlock.Text = "Not signed in.";
client = null;
}
}
I tried to change App ID ond Live account also, but nothing helps. Please help.
This can happen if in application settings at Live Connect Developer Center you haven't specified that it is a Mobile client app:

Resources