I'm building an app and I would like to track my device data session information.
For example duration, received bytes, sent bytes, bearer, access point, local IP address, protocol when connected using wifi, 3g, gprs, cell network.
If I can get all would be perfect, but getting 1 is more than enough.
I hope someone could show me some solutions or possibles APIs, if possible.
Thanks a lot in advance.
There are 3 namespaces in WP8 that provide network information: System.Net.NetworkInformation, Microsoft.Phone.Net.NetworkInformation and the new WP8 WinPRT namespace Windows.Networking.Connectivity.
While DataUsage/DataPlan APIs are available in the new WP8 namespace, they aren't supported on WP8 and only exist for Win8 API compatibility. You can use either the new WP8 APIs or WP7 APIs to enumerate over all connected interface type and check if they're WiFi/Ethernet/3G/etc:
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
foreach (var network in new NetworkInterfaceList())
{
Debug.WriteLine(network.InterfaceType);
}
}
Related
I have a Line-of-Business (LoB) Windows 8.1 Store application I developed for a client. The client side-loads it on several Windows 10 tablets. They use it in an environment where WiFi is spotty at best and they would like to get some sort of notification inside the app, regardless of what page they are on, notification that will let them know that they've lost connectivity to the network. I have created a method on my Web API that is not hitting the repository (database). Instead, it quickly returns some static information regarding my Web API, such as version, date and time of the invocation and some trademark stuff that I'm required to return. I thought of calling this method at precise intervals of time and when there's no response, assume that the Web API connectivity is lost. In my main page, the first one displayed when the application is started, I have the following stuff in the constructor of my view model:
_webApiStatusTimer = new DispatcherTimer();
_webApiStatusTimer.Tick += OnCheckWebApiStatusEvent;
_webApiStatusTimer.Interval = new TimeSpan(0, 0, 30);
_webApiStatusTimer.Start();
Then, the event handler is implemented like this:
private async void OnCheckWebApiStatusEvent(object sender, object e)
{
// stop the timer
_webApiStatusTimer.Stop();
// refresh the search
var webApiInfo = await _webApiClient.GetWebApiInfo();
// add all returned records in the list
if (webApiInfo == null)
{
var messageDialog = new MessageDialog(#"The application has lost connection with the back-end Web API!");
await messageDialog.ShowAsync();
// restart the timer
_webApiStatusTimer.Start();
}
}
When the Web API connection is lost, I get a nice popup message that informs me that the Web API is no longer available. The problem I have is that after a while, especially if I navigate away from the first page but not necessary, I get an UnauthorizedAccessException in my application.
I use the DispatcherTimer since my understanding is that this is compatible with
UI threads, but obviously, I still do something wrong. Anyone cares to set me on the right path?
Also, if you did something similar and found a much better approach, I'd love to hear about your solution.
Thanks in advance,
Eddie
First, If you are using Windows Store Apps, then you could possibly use a Background task to check poll for the status of the web api instead of putting this responsibility on your view model, its not the viewmodels concern
Second, if you are connecting from your Windows store app to your API then one successful authentication/ authorization for the first time, how and where do you store the token (assuming you are using token authentication). If you are (and ideally you should), is there a timer that you start which is set to the token expiration time? Is your local storage getting flushed somehow and loosing the aurthorization data?
Need more information.
I'd like to access my app's certificate store from another app. I have already enabled "sharedusercertificates" in the package.appmanifest file.
Windows.Storage.StorageFile selectedCertFile = await folder.GetFileAsync(fileName);
IBuffer buffer = await FileIO.ReadBufferAsync(selectedCertFile);
string certificateData = CryptographicBuffer.EncodeToBase64String(buffer);
string password = "password";
await CertificateEnrollmentManager.ImportPfxDataAsync(
certificateData,
password,
ExportOption.NotExportable,
KeyProtectionLevel.ConsentWithPassword,
InstallOptions.None,
selectedCertFile.DisplayName);
In my own app, I can list the installed certificates without a problem:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var task = CertificateStores.FindAllAsync();
task.AsTask().Wait();
var certlist = task.GetResults();
Debug.WriteLine("Cert count: {0}", certlist.Count);
LoadCertList(certlist);
}
private void LoadCertList(IReadOnlyList<Certificate> certificateList)
{
listbox1.Items.Clear();
foreach (Certificate cert in certificateList)
{
listbox1.Items.Add(cert.Subject);
}
}
If I try to access those from another app, It will not be listed.
In the Windows Phones 8.1's mail client settings, the installed certificate is missing, too. Certificates which have been installed regularly, not programmaticaly, are listed.
Is there a way to install my custom certificates to the system's certificate store? So it can be used in other apps.
I have been searching the web for days now, but I didn't find a solution.
Due to this, it should be possible.
"The sharedUserCertificates capability grants an app container read access to the certificates and keys contained in all user stores and the Smart Card Trusted Roots store. "
https://msdn.microsoft.com/en-us/library/windows/apps/hh465025.aspx
Did I miss something? Help will be much appreciated.
Dino
If you want a certificate to be accessible for other Apps, you need to enroll it using CertificateEnrollmentManager.UserCertificateEnrollmentManager.ImportPfxDataAsync rather then CertificateEnrollmentManager.ImportPfxDataAsync.
Please note that there is no way of deleting the shared certificate unless it's expired (using InstallOptions.DeleteExpired as a Parameter in ImportPfxDataAsync).
Also, the more certificates you share this way, the slower the queries against the certificate stores get.
I'm adding Azure Mobile Services authentication to a Universal Windows project. It's all set up and working properly on the server and in the Windows Store version of the app, however I can't get it to work with the Windows Phone 8.1 version of the app. I actually have two different apps that I've been working on with the same problem, so I created a test app based strictly on the steps outlined in this article. The sample app has one button on the UI that will attempt authenticate the user with Twitter when pressed.
The flow that I am seeing from the UI is:
Press the button
Screen goes black for a moment
Screen displays "Resuming..." with a spinner
InvalidOperationException gets caught
The exception details:
System.InvalidOperationException was caught
HResult=-2146233079
Message=Authentication was cancelled by the user.
Source=mscorlib
StackTrace:
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.WindowsAzure.MobileServices.MobileServiceAuthentication.<LoginAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at MobileAuthTest.MainPage.<AuthenticateAsync>d__3.MoveNext()
InnerException:
The code I am using is copied almost verbatim from the article, but I'll paste it here too:
private async void Button_Click(object sender, RoutedEventArgs e)
{
await this.AuthenticateAsync();
}
// Define a method that performs the authentication process
// using a Twitter sign-in.
private async Task AuthenticateAsync()
{
while (user == null)
{
string message;
try
{
// Change 'MobileService' to the name of your MobileServiceClient instance.
// Sign-in using Twitter authentication.
user = await App.mobileService
.LoginAsync(MobileServiceAuthenticationProvider.Twitter);
message =
string.Format("You are now signed in - {0}", user.UserId);
}
catch (InvalidOperationException)
{
message = "You must log in. Login Required";
}
var dialog = new MessageDialog(message);
dialog.Commands.Add(new UICommand("OK"));
await dialog.ShowAsync();
}
}
And this override is in App.xaml.cs:
protected override void OnActivated(IActivatedEventArgs args)
{
// Windows Phone 8.1 requires you to handle the respose from the WebAuthenticationBroker.
#if WINDOWS_PHONE_APP
if (args.Kind == ActivationKind.WebAuthenticationBrokerContinuation)
{
// Completes the sign-in process started by LoginAsync.
// Change 'MobileService' to the name of your MobileServiceClient instance.
mobileService.LoginComplete(args as WebAuthenticationBrokerContinuationEventArgs);
}
#endif
base.OnActivated(args);
}
My testing is all on a real Windows Phone 8.1 device (Nokia 920 with 8.1 update).
It's also worth pointing out that the project I'm currently trying to get this to work in is also using Xamarin.Forms for Android, iOS and Windows Phone (I wanted a comparison between Xamarin.Forms for Windows Phone and Universal apps for Windows Phone). All of the apps work, EXCEPT for the two Windows Phone apps. The Xamarin.Forms Windows Phone app is a Windows Phone Silverlight 8.1 app which acts the same as described above for the Universal WP, but fails with the error, "Authentication failed with HTTP response code 0."
I've searched around and haven't found any other cases of people encountering the same issue I am. Is there something I need to do that is so simple nobody feels the need to say it in writing?
Well, it turns out that the issue I am seeing may just be my device. I sent the sample app to another dev for testing and he had no issues. I also was able to successfully log in with both the sample app and the real app on the simulator. That isn't exactly a thorough test sample, but it's enough for me to stop banging my head on this desk.
Within Windows Phone 8 I have a solution whereby I am capturing a video and saving it to local storage using the new WPRT Windows.Storage APIs.
When I want to playback the video using a MediaElement control I appear to be stuck as it doesn't support playback from local storage (only isolated storage).
The code I am using is:
public async void MethodName(IStorageFile file){
var stream = (await file.OpenReadAsync()).AsStream();
VideoPlayer.SetSource(stream);
VideoPlayer.Play();
}
Yet when I run it I receive an exception "Stream must be of type IsolatedStorageFileStream".
I've also attempted to set the Source to a URI pointing to the file's location property, and following typical local storage URI convention - but this gets ignored.
Has anyone come across a solution to this?
Isolated Storage and Local Storage are the same location on the phone.
It looks like you need to use the Isolated Storage APIs rather than the new-fangled Windows Runtime ones in this case.
I am want to make a 'hello world' application whereby I can send some data/make a request to a server or a WCF service. A simple query, save, delete etc application. I am targeting this learning app to be on the Windows Phone 8 platform.
I have done some work in WCF and RavenDB in the past but, not sure what to do in this situation.
Can someone please give me some tips/tutorials on how to achieve this please?
I used WCF to create a Service. The Service contained an Interface which were operations that were exposed and they were implemented in a different file. I then created a windows phone app and added the Service Reference by providing a URL to the service. The code to query the service was simply:
private void button1_Click(object sender, RoutedEventArgs e)
{
ServiceReference1.Service1Client myClient = new Service1Client();
myClient.AddNumbersCompleted += new EventHandler<AddNumbersCompletedEventArgs>(myClient_AddNumbersCompleted);
myClient.AddNumbersAsync(textBox1.Text, textBox2.Text);
}
void myClient_AddNumbersCompleted(object sender, AddNumbersCompletedEventArgs e)
{
textBlock1.Text = "Answer:" + e.Result.ToString();
}