As I already wrote the small demo apps for wireless printing of Label and Receipts for Android and Windows Phone 8, I now wrote such demo for Windows UWP. The application was tested on a Windows 10 Phone running Windows 10 Iot Enterprise Edition.
The code is based on the Windows Universal Sample app BTRFCommChat, but uses a different, single page layout.
The layout is based on a grid with a defined number of columns and rows. All rows are set to auto-adjust their height.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
Then the grid columns contain stackpanel
s with GUI elements. To guide through the use of the demo application, these stackpanels are shown or hidden depending on the state of the demo. For example, the first state is to select a printer. In this state, only the “List Printers” button and the empty list is shown. After connecting a printer by tapping its name in the list, the stackpanel
with “List Printers” and the list is collapsed (hidden).
As said, the code is based on the BTRFCommChat
example. The first step was to change the BT service descriptor for the BT discovery to “RfcommServiceId.SerialPort
”:
dataServiceDeviceCollection = await DeviceInformation.FindAllAsync
(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));
if (dataServiceDeviceCollection.Count > 0)
{
DeviceList.Items.Clear();
foreach (var dataServiceDevice in dataServiceDeviceCollection)
{
DeviceList.Items.Add(dataServiceDevice.Name);
}
DeviceList.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
When a device is tapped, the application tries to create a socket connection:
try
{
await dataSocket.ConnectAsync(dataService.ConnectionHostName, dataService.ConnectionServiceName);
dataWriter = new DataWriter(dataSocket.OutputStream);
Panel_SelectPrinter.Visibility = Visibility.Collapsed;
PanelSelectFile.Visibility = Visibility.Visible;
panelDisconnect.Visibility = Visibility.Visible;
DataReader dataReader = new DataReader(dataSocket.InputStream);
ReceiveStringLoop(dataReader);
}
Then a list of prepared demo print files is shown. The list is built from all files deployed with the application within the files folder:
private async void FilesListbox_Loaded(object sender, RoutedEventArgs e)
{
try
{
FilesListbox.Items.Clear();
var folder = await StorageFolder.GetFolderFromPathAsync
(Windows.ApplicationModel.Package.Current.InstalledLocation.Path + @"\files");
IReadOnlyList<StorageFile> files = await folder.GetFilesAsync();
foreach (StorageFile f in files)
FilesListbox.Items.Add(f.Name);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("ListFiles: " + ex.Message);
}
}
If the user selected a file and taps the “Print” button, the file is sent via the bluetooth socket connection to the printer:
private async void SendFile()
{
try
{
if (FilesListbox.SelectedIndex == -1)
return;
string filename = FilesListbox.SelectedItem.ToString();
var fileToRead = await StorageFile.GetFileFromApplicationUriAsync
(new Uri("ms-appx:///files/" + filename, UriKind.Absolute));
byte[] buffer = new byte[1024];
int readcount = 0;
using (BinaryReader fileReader = new BinaryReader(await fileToRead.OpenStreamForReadAsync()))
{
int read = fileReader.Read(buffer, 0, buffer.Length);
while (read > 0)
{
readcount += read;
Stream streamWrite = dataSocket.OutputStream.AsStreamForWrite();
streamWrite.Write(buffer, 0, read);
streamWrite.Flush();
read = fileReader.Read(buffer, 0, buffer.Length);
}
}
NotifyUser("sendFile " + readcount.ToString(), NotifyType.StatusMessage);
await dataWriter.StoreAsync();
}
catch (NullReferenceException ex)
{
NotifyUser("Error: " + ex.HResult.ToString() + " - " + ex.Message,
NotifyType.StatusMessage);
}
catch (IOException ex)
{
NotifyUser("Error: " + ex.HResult.ToString() + " - " + ex.Message,
NotifyType.StatusMessage);
}
catch (Exception ex)
{
NotifyUser("Error: " + ex.HResult.ToString() + " - " + ex.Message,
NotifyType.StatusMessage);
}
}
That’s it.
The source code available at github. The application has also been certified and is available in Windows Store.