I have been trying to develop my Windows Phone 8 app to access a paired Bluetooth device (a printer) and send over some print data.
I'm developing on Windows 8 64bit and using VS2012 Express.
Due to the Emulator not supporting Bluetooth I have been uploading the build to a Nokia Lumia 820 for testing purposes.
I have used the following two sites for references:
http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj207007(v=vs.105).aspx
http://www.geekchamp.com/articles/getting-started-with-bluetooth-in-windows-phone-8
The App finds the pair device and ouputs the printer name by the Debug command.
The code works up until the point:
await socket.ConnectAsync(selectedDevice.HostName, "1");
And then it breaks with the following exception:
********** EXCEPTION OCCURED **********
Data: System.Collections.ListDictionaryInternal
InnerException:
Message: An attempt was made to access a socket in a way forbidden by its access permissions. (Exception from HRESULT: 0x8007271D)
StackTrace: at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at mobility.PrinterSettings.<AppToDevice>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__0(Object state)
********** EXCEPTION OCCURED **********
If a remove "await" before socket.ConnectAsync(selectedDevice.HostName, "1"); then the code will continue without any errors but no Bluetooth connection is made?
I have tried every number from 1 to 30 as it states in the tutorials and I have also made sure that ID_CAP_NETWORKING is enabled in WMAppManifest.xml.
Please does anybody have any idea's?
Full code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Windows.Networking.Proximity;
using System.Diagnostics;
using Windows.Networking.Sockets;
using Microsoft.Phone.Tasks;
using System.Text;
using Windows.Storage.Streams;
namespace mobility
{
public partial class PrinterSettings : PhoneApplicationPage
{
public PrinterSettings()
{
InitializeComponent();
PrinterName.Text = App.loadString("PrinterName");
if (PrinterName.Text == null || PrinterName.Text == "")
{
PrinterName.Text = "QL420";
}
}
private void Save_Click(object sender, RoutedEventArgs e)
{
if (PrinterName.Text != null && PrinterName.Text != "")
{
App.saveString(PrinterName.Text, "PrinterName");
MessageBox.Show("Printer Name has been saved.");
}
else
{
MessageBox.Show("Error: The Printer Name appears to be missing.");
}
}
private async void AppToDevice()
{
try
{
// Configure PeerFinder to search for all paired devices.
PeerFinder.AlternateIdentities["Bluetooth:Paired"] = "";
var pairedDevices = await PeerFinder.FindAllPeersAsync();
if (pairedDevices.Count == 0)
{
MessageBox.Show("No paired devices were found.");
}
else
{
// Select a paired device. In this example, just pick the first one.
PeerInformation selectedDevice = pairedDevices[0];
// Attempt a connection
Debug.WriteLine(selectedDevice.DisplayName); // Make sure we are trying to connect to the correct device.
//Debug.WriteLine(selectedDevice.HostName.RawName);
//Debug.WriteLine(selectedDevice.HostName.IPInformation.NetworkAdapter.NetworkAdapterId.ToString());
//Debug.WriteLine(selectedDevice.ServiceName);
StreamSocket socket = new StreamSocket();
// Make sure ID_CAP_NETWORKING is enabled in your WMAppManifest.xml, or the next
// line will throw an Access Denied exception.
// In this example, the second parameter of the call to ConnectAsync() is the RFCOMM port number, and can range
// in value from 1 to 30.
await socket.ConnectAsync(selectedDevice.HostName, "1");
string newLabel = App.loadString("Template");
newLabel = newLabel.Replace("$n", "\n");
string epl = App.loadString("PrintHeader");
epl = epl + newLabel;
Debug.WriteLine(epl);
var data = GetBufferFromByteArray(Encoding.UTF8.GetBytes(epl));
//socket.OutputStream.WriteAsync(data);
MessageBox.Show("Device Found.");
}
}
catch (Exception ex)
{
if ((uint)ex.HResult == 0x8007048F)
{
var result = MessageBox.Show("Bluetooth is turned off. To see the current Bluetooth settings tap 'ok'", "Bluetooth Off", MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
{
ShowBluetoothcControlPanel();
}
}
else if ((uint)ex.HResult == 0x80070005)
{
MessageBox.Show("To run this app, you must have ID_CAP_PROXIMITY enabled in WMAppManifest.xaml");
}
else
{
MessageBox.Show(ex.Message);
Debug.WriteLine(ex.StackTrace);
Debug.WriteLine(ex.HResult);
}
}
}
private IBuffer GetBufferFromByteArray(byte[] package)
{
using (DataWriter dw = new DataWriter())
{
dw.WriteBytes(package);
return dw.DetachBuffer();
}
}
private void ShowBluetoothcControlPanel()
{
ConnectionSettingsTask connectionSettingsTask = new ConnectionSettingsTask();
connectionSettingsTask.ConnectionSettingsType = ConnectionSettingsType.Bluetooth;
connectionSettingsTask.Show();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
this.Dispatcher.BeginInvoke(() =>
{
AppToDevice();
});
}
}
}
After much playing around and resetting the phone back to its original state with no success.
I ticked "ID_CAP_PROXIMITY" in WMAppManifest.xml and it started working straight away!
It looks like the Error Code I had for "ID_CAP_PROXIMITY" was maybe wrong so here is an update in code plus a few more error messages I have come across since.
I hope this might help somebody that is having a similar issue.
catch (Exception ex)
{
if ((uint)ex.HResult == 0x8007048F)
{
var result = MessageBox.Show("Bluetooth is turned off.\nTo see the current Bluetooth settings tap 'ok'", "Bluetooth Off", MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
{
ShowBluetoothcControlPanel();
}
}
else if ((uint)ex.HResult == 0x8007271D)
{
//0x80070005 - previous error code that may be wrong?
MessageBox.Show("To run this app, you must have ID_CAP_PROXIMITY enabled in WMAppManifest.xaml");
}
else if ((uint)ex.HResult == 0x80072740)
{
MessageBox.Show("The Bluetooth port is already in use.");
}
else if ((uint)ex.HResult == 0x8007274C)
{
MessageBox.Show("Could not connect to the selected Bluetooth Device.\nPlease make sure it is switched on.");
}
else
{
//App.handleException(ex);
MessageBox.Show(ex.Message);
}
}
Related
I have a WS server and I would like to broadcast messages from that server (using another web app) to all HoloLens devices that are connected to the session.
First I have implemented a MessageWebSocket client in the Hololens app that initiated a connection with a sample public WS server echo.websocket.org just to check if the setup is right on the client side. Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if WINDOWS_UWP
using System.Threading.Tasks;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
using Windows.Web;
using System;
#endif
public class WebSocketClient : MonoBehaviour
{
void Start()
{
#if WINDOWS_UWP
int msgTime = 5;
int fadeTime = 1;
guiPhraseReporter.QueueRaport("START", msgTime, fadeTime);
MessageWebSocket ws = new MessageWebSocket();
ws.Control.MessageType = SocketMessageType.Utf8;
ws.MessageReceived += (MessageWebSocket sender, MessageWebSocketMessageReceivedEventArgs args) =>
{
guiPhraseReporter.QueueRaport("Trying to receive message...", msgTime, fadeTime);
try
{
using (DataReader dataReader = args.GetDataReader())
{
dataReader.UnicodeEncoding = UnicodeEncoding.Utf8;
string message = dataReader.ReadString(dataReader.UnconsumedBufferLength);
Debug.Log(message);
}
}
catch (Exception ex)
{
Debug.Log("Error occurred");
}
};
ws.Closed += (IWebSocket sender, WebSocketClosedEventArgs args) => {
Debug.Log("WS closed");
};
try
{
Task connectTask = ws.ConnectAsync(new Uri("ws://echo.websocket.org")).AsTask();
connectTask.ContinueWith(async _ =>
{
string message = "Hello, World!";
using (DataWriter dataWriter = new DataWriter(ws.OutputStream))
{
dataWriter.WriteString(message);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
Debug.Log("Sending Hello World");
});
}
catch (Exception ex)
{
WebErrorStatus webErrorStatus = WebSocketError.GetStatus(ex.GetBaseException().HResult);
// Add additional code here to handle exceptions.
Debug.Log(ex);
}
#endif
}
}
And it works fine, I'm able to send a message to the server, and it is echoed back and received correctly by the client.
Things however mess up when I use the actual server I'll be testing on. On my server, I have replicated the behavior from the echo.websocket.org and I echo back any message sent. I'm able to connect, the connection is not closed (Closed is never called), but I don't receive any messages.
If I test both servers using the web browser (with chrome's Smart Websocket Extension), they both work. The only difference (and only possible lead I got) is that the sample server (the one that works on Hololens) sends more headers upon connection:
vs my server:
Maybe there is some easier way to do this, but so far I didn't find any good WS wrappers that would work on UWP. Any help appreciated.
It was faulty logic on my server app after all. So there was no problem with WS communication to begin with, thank you for your time.
when I am trying to use cognitive vision library in xamarin project , I got an error message : the remote server returned an error (401)
I am using a VisionServiceClient object
this code is a code to analyze the picked picture .
I can't fix the error .
any advice , please ?
PS : is there is any problem in using free trial Api key ? this may be the cause of the error ?
and should I have a credit card to create a cognitive vision resource instance in https://portal.azure.com/#home ?
this is the main_page code :
using Microsoft.ProjectOxford.Vision;
using Microsoft.ProjectOxford.Vision.Contract;
using Plugin.Connectivity;
using Plugin.Media;
using Plugin.Media.Abstractions;
using System;
using System.IO;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace ComputerVisionSample
{
public partial class MainPage : ContentPage
{
private readonly VisionServiceClient visionClient;
public MainPage()
{
InitializeComponent();
this.visionClient =
new VisionServiceClient("my_api_key");
}
private async Task<AnalysisResult> AnalyzePictureAsync(Stream inputFile)
{
if (!CrossConnectivity.Current.IsConnected)
{
await DisplayAlert("Network error",
"Please check your network connection and retry.", "OK");
return null;
}
VisualFeature[] visualFeatures = new VisualFeature[] { VisualFeature.Adult,
VisualFeature.Categories, VisualFeature.Color, VisualFeature.Description,
VisualFeature.Faces, VisualFeature.ImageType, VisualFeature.Tags };
AnalysisResult analysisResult =
await visionClient.AnalyzeImageAsync(inputFile,
visualFeatures);
return analysisResult;
}
private async void UploadPictureButton_Clicked(object sender, EventArgs e)
{
if (!CrossMedia.Current.IsPickPhotoSupported)
{
await DisplayAlert("No upload", "Picking a photo is not supported.", "OK");
return;
}
var file = await CrossMedia.Current.PickPhotoAsync();
if (file == null)
return;
this.Indicator1.IsVisible = true;
this.Indicator1.IsRunning = true;
Image1.Source = ImageSource.FromStream(() => file.GetStream());
try
{
this.BindingContext = await AnalyzePictureAsync(file.GetStream());
}
catch (Exception ex)
{
await DisplayAlert("Error", ex.Message, "OK");
return;
}
finally
{
this.Indicator1.IsRunning = false;
this.Indicator1.IsVisible = false;
}
}
}
}
If you have a 401, that means:
you did not provide a subscription key
or you provide one, but it is not matching the region where your resource is
You are using the default endpoint/region of ComputerVision by doing this:
this.visionClient = new VisionServiceClient("my_api_key");
And you are using an old package (Microsoft.ProjectOxford.Vision was the project codename).
So, you should do the following:
1 - Switch to the latest package called Microsoft.Azure.CognitiveServices.Vision.ComputerVision, available on Nuget here
2 - Create your client by doing the following:
var visionClient = new ComputerVisionClient(new ApiKeyServiceClientCredentials("yourAPIkeyHere")))
{
Endpoint = "yourEndpointHere"
})
Endpoint format is: "https://region.api.cognitive.microsoft.com", for example for West Europe: "https://westeurope.api.cognitive.microsoft.com"
There may be some changes in the method you are calling or the parameters because of the package change, but you will now be up-to-date
I'm using Xamarin.iOS for an application using AVAudioEngine.
Sometimes I get this exception :
AVFoundation_AVAudioPlayerNode_Play
Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: _engine->IsRunning()'
This point to my code:
private Dictionary<AudioTrack, AVAudioPlayerNode> _dicPlayerNodes;
private void PlayAudio()
{
try
{
NSError err;
if (Engine.StartAndReturnError(out err))
{
foreach (var audioTrack in _dicPlayerNodes)
{
AVAudioPlayerNode node = audioTrack.Value;
node.Play();
}
}
else
{
Messenger.Publish(new AudioErrorMessage(this) { Platform = "IOS", Code = Convert.ToInt32(err.Code), Message = err.LocalizedDescription ?? err.Description });
_exceptionHandlerService.PostHockeyApp(new Exception($"{err.Code} {err.Description}"));
}
}
catch (Exception ex)
{
_exceptionHandlerService.PostExceptionAsync(ex).Forget();
}
}
I don't understand how is it possible to have this exception that engine is not running, because in my code I Start it and get error if it failed to start ... Then play it.
Also I have a try catch that's not working in this case :( so my applicaton just crashed.
Any advices or idea ?
I comes to this thread but it doesn't help me to understand:
https://forums.developer.apple.com/thread/27980
versions:
IOS version : 10.3.3
Device: ipad 2
Xamarin.ios: 11.2.0.11
Thanks
I am using the Map functionality of Windows Phone 8.1 to find a route with the following code:
MapRouteFinderResult routeResult = null;
try
{
if (true == typeOfTransport.Equals(GlobalDeclarations.TypeOfTransport.Walk))
{
routeResult = await MapRouteFinder.GetWalkingRouteAsync(startPoint, endPoint);
}
else
{
routeResult = await MapRouteFinder.GetDrivingRouteAsync(startPoint, endPoint, MapRouteOptimization.Time, MapRouteRestrictions.None, 290);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
The problem is that despite the try-catch, this MapRouteFinder.GetWalkingRouteAsync method crashes with an exception: Object not set to an instance of an object. Both startPoint and endPoint params are obviously not null, and filled with data. Why is this? And why the whole app crashes instead of catching the exception in the try-catch section?
I just started playing with bluetooth communication on WP8.
I found a example here: http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj207007(v=vs.105).aspx
But as soon as Peerfinder.Start() is hit, i get this error:
A first chance exception of type 'System.UnauthorizedAccessException' occurred in PhoneApp3.DLL
public MainPage()
{
InitializeComponent();
PeerFinder.Start();
}
async private void AppToApp_Click(object sender, RoutedEventArgs e)
{
// PeerFinder.Start() is used to advertise our presence so that peers can find us.
// It must always be called before FindAllPeersAsync.
var peers = await PeerFinder.FindAllPeersAsync();
if (peers.Count == 0)
{
Debug.WriteLine("Peer not found.");
}
else
{
Debug.WriteLine(peers.Count + " peers found");
}
}
Make sure you've added the capabilities ID_CAP_PROXIMITY and ID_CAP_NETWORKING to your application manifest.