Nov 292016
 

Hi everyone,

Over the years, there has been a lot of confusion regarding our SDK samples. In the past, to get our samples, you needed to download an “SDK Installer” from www.dymo.com. The “SDK Installer” name was a bit misleading as the installer only contained samples, no binaries. As you know, all the binaries required for our SDKs are installed as part of DLS. So in order to clear things up, we’ve consolidated all of our samples into one ZIP file. This ZIP file contains the following:

  • DYMO Framework Samples for C# and C++
  • DYMO SDK High-Level COM Samples for C++, C#, VB, and ASP.NET
  • DYMO SDK Low-Level COM Samples for C++
  • Documentation for both the DYMO Framework & DYMO SDK

This ZIP file can be downloaded here: SDKSamples.zip. Please note that all of the samples in the ZIP file are intended for use in Visual Studio 2015 and using .NET 4.5.1 where applicable.

We also have a number of JavaScript samples that can be explored. While we do not provide the source for these samples directly, you are free to use the dev tools within your favorite web browser to check out the source code for these samples.

  • Print Me That Label – a simple JavaScript sampled that can be used to check if DLS is installed properly and the JS SDK is functioning correctly
  • Preview and Print Label – see a preview of a label in the browser and print the label
  • Print 2 Labels – example of multiple label printing
  • QR Code – barcode printing example
  • Spreadsheet – example of printing multiple labels from an online data source

Furthermore, we have a a diagnostic sample that can be used to ensure your dev/client environment is setup correctly.

  • Check Environment – runs a quick check of your setup and brings to your attention any potential problems

Happy coding!

Aug 082016
 

Working with DYMO Label Web Service


Download Word Version of this post

Download PDF Version of this post

What is the DYMO Label Web Service?

 

In the past, developers had to provide a browser-specific plug-in for each major web browser.  Nowadays, most browsers have phased out native plug-in support.  Google, for example, stopped supporting Chrome their NPAPI browser extension in September 2015.  In response, we released the DYMO Web Service as a new cross-browser solution allowing third-party developer applications the ability to interface with the DLS SDK in a seamless, browser-agnostic fashion.  It handles all printer-related requests from the JavaScript Library that the DYMO Label Framework browser plug-ins used to perform.

(For more information on the framework, please visit http://developers.dymo.com/2015/08/20/dymo-label-framework-javascript-library-2-0-open-beta/.)

 

How do I install the DYMO Label Web Service?

 

First, download the appropriate installer for your OS.  You can find them at the following URL:

http://www.dymo.com/en-US/online-support/

 

Windows

Double-click on the installer and follow the directions provided by the install wizard.

Mac

Double-click on the DMG file to mount it.  Select the newly mounted volume and double-click on the PKG file found within it.  Then follow the directions provided by the install wizard.

How can I tell if I have DYMO Label Web Service installed?

 

The DYMO Label Web Service is installed as long as you have installed DYMO Label Software 8.5.3 or newer using the express “Express” mode.

If you choose to install DYMO Label Software in “Custom” mode, be sure to select the DYMO Label Web Service component as follows:

select_components_to_install

Custom select components to install

 

 

 

 

 

 

If installed, there will be an executable file named DYMO.DLS.Printing.Host.exe within the DLS working folder (normally found within the C:\Program Files (x86)\DYMO\DYMO Label Software folder on Windows and the /Library/Frameworks/DYMO/SDK folder on Mac).

 

 

Executable location (Windows)

Executable location (Windows)

 

How can I tell if the DYMO Label Web Service is running?

You should see the DLS application icon within the system tray.  Right-click this icon to display a context menu.  The menu displays the web service’s status (i.e., “Started on port 41951” or “Stopped”).

The following shows what it looks like on Windows.

DLS icon and context menu (Windows)

DLS icon and context menu (Windows)

 

On Mac, the DLS application icon and context menu will appear within the system tray like this:

DLS icon and context menu (Mac)

DLS icon and context menu (Mac)

I do not see it in the system tray.  How can I start it?

 

Windows

You can start the web service again by navigating to the DLS working folder and running the executable named DYMO.DLS.Printing.Host.exe.

Mac

Open a Finder window, navigate to the /Library/Frameworks/DYMO/SDK/ folder, and click on the DYMO.DLS.Printing.Host.app icon.

Open a terminal prompt and enter the following command:

launchctl start com.dymo.dls.webservice

 

How can I start or stop the DYMO Label Web Service?

You can start or stop the web service at any time by open right clicking on the service’s icon in the system tray and choosing the Start service and Stop service menu items, respectively.  Although API functions will not execute after stopping the service, the service icon will remain in the system tray after stopping it.

 

How can I configure the DYMO Label Web Service?

 

Clicking the Configure menu item will cause a configuration window to appear.  This allows you to change the language and listening port.  The web service will normally try to use the first available port within the 41951-41960 range.  You can override this behavior by checking the Use single port checkbox, which makes the service only try using the specified port only. You cannot specify a port number that does not fall within the specified range.  The service will not try using any other port if an error occurs while using this option.

Web Service configuration dialog (Windows)

Web Service configuration dialog (Windows)

 

 

Web Service configuration dialog (Mac)

Web Service configuration dialog (Mac)

 

 

How can I tell if the DYMO Label Web Service is functioning properly?

Click the Diagnose menu item within the context menu while the service is running.  If the self-test succeeds, a dialog box will appear asking you to open a test page in your browser to see if SSL certificate is working.

 

Diagnose successful (Windows)

Diagnose successful (Windows)

Diagnose successful (Mac)

Diagnose successful (Mac)

 

Click the Yes button to open your default web browser.  The browser should display a page indicating the web service is running correctly.  The page address should be something to the following effect:

https://localhost:41951/DYMO/DLS/Printing/Check

The port number may vary from machine to machine.

 

Web Service is up and running configuration

Web Service is up and running configuration


 

How do I use the DYMO Label JavaScript Library?

 

Getting Started

You need to link to the DYMO Label Framework’s JavaScript library in order to use the DYMO Label Web Service via web pages.  You accomplish this by using the following code snippet:

 <script src="dymo.label.framework.js" type="text/javascript" charset="UTF-8"></script>

Your code then needs to call the following initialization method while providing it a callback to be invoked by the library when initialization completes:

 dymo.label.framework.init(startupCode);

The library invokes this callback whether or not initialization completes successfully.

 

Do I need to change my code to work with the new DYMO Label JavaScript Library?

Although it may work with old unmodified code in some cases, it is highly recommended to make a few changes to avoid future problems.

The biggest change to the JavaScript Library is the move from a synchronous architecture to an asynchronous one.  This move has several advantages, improved UI responsiveness and shorter discovery time while scanning the available port range.  Synchronous AJAX calls are already marked deprecated in most major web browsers, so we recommend switching to asynchronous JavaScript Library initialization as soon as possible.

 

What will happen if I leave my old code unchanged?

If you do not update your code to make use of asynchronous calls, the JavaScript Library will fall back to the synchronous behavior upon accessing the library for the first time when a page is loaded.  It will synchronously try to scan the first port.  This is either the default port or the last known working one (i.e., the cached port number).  The library will use web service-based functionality if it successfully connects to the port.  Otherwise, it will fall back to using native plug-ins.  All subsequent calls to the library will continue to reuse whatever method succeeded until you reload the page.

 

What do I need to change in my code to make it properly work with new the JavaScript library?

 

The library now makes use of a new initialization method to perform asynchronous initialization through use of a callback method.  Since the library performs initialization in the background, calling an SDK function prior to initialization results in an error.  Your code should be updated to call the new dymo.label.framework.init() method while providing it a callback to be invoked by the library when initialization completes.  Please note the library invokes this callback whether or not initialization completes successfully.

Any code initialization involving calls to the JavaScript Library is typically located inside an event handler (i.e., window.onload).  Below is typical JavaScript code demonstrating how to do this with the old synchronous architecture:

function startupCode() {
/* access DLS SDK */
}

window.onload = startupCode;

This code will not work correctly under the new asynchronous architecture.  It should be changed to call an intermediate “helper” method that firsts calls new init() method accepting your callback as a parameter.  The library invokes the callback containing your original startup code after library initialization completes.  Below is the updated JavaScript code that uses asynchronous initialization:

function startupCode() {
/* access DLS SDK */
}
function frameworkInitHelper() {
// init, then invoke a callback

dymo.label.framework.init(startupCode);
}

window.onload = frameworkInitHelper;

If initialization is asynchronous, are other methods asynchronous as well?

The short answer is, “Yes!”  As stated previously, synchronous AJAX requests are deprecated, so our new JavaScript library contains new asynchronous equivalents for every method that calls the web service.  These methods have the same names as their counterparts in the former architecture along with the Async suffix appended to them.  They take the same number of parameters with corresponding types as well.  The only major difference is that the new methods return a Promise object instead of the actual return value.  You make use of this object by providing its then() method your callback function and one argument which receives the actual return value when the asynchronous method completes.

 dymo.label.framework.getPrintersAsync().then(function(printers) {
// printers list (same list the getPrinters() returns)
});

 

How do I make use of Promise objects in asynchronous programming?

Asynchronous JavaScript programming is not covered here. Please refer Google’s documentation on Promise object usage and errors handling:
https://developers.google.com/api-client-library/javascript/features/promises

How can I tell if the JavaScript library is currently using the web service?

The dymo.label.framework.checkEnvironment() method returns a CheckEnvironmentResult object along with multiple parameters (please refer to existing documentation on checkEnvironment() method).  The new JavaScript library contains an additional property within this object called isWebServicePresent.  You can use this property to determine if the web service is actually used.

As with all other SDK-related methods, do not call checkEnvironment() until init() finishes initializing. Synchronous library initialization and web service discovery will occur if it is called before init() completes.

Basic Service API Functions

 

The following is a list of basic API functions provided by the DYMO Label JavaScript Library.

dymo.label.framework.getPrinters()

Purpose:  Returns a list of installed DYMO printers
Parameters:  None.
Example:

printers = dymo.label.framework.getPrinters();
for(var i = 0; i < printers.length; i++)
{
var printer = printers[i];
console.log(printer);
}

dymo.label.framework.openLabelFile(labelUri)

Purpose:  Returns a document object model (DOM) for label file.
Parameters: 

labelUri – label file Uri

Example:

 var labelUri = "file:///Volumes/DATA/DieCut.label";
var label = dymo.label.framework.openLabelFile(labelUri);
console.log(label.toString());

Comments:

It is necessary to use the label.getLabelXml() or label.toString() functions to obtain XML representations of a label.

 

dymo.label.framework.renderLabel(labelXml, paramXml, printerName)

 

Purpose:  Returns a graphic representation of the label (PNG) encoded in base64 format.
Parameters: 

labelXml – DOM or XML representation of the label

paramXml – render parameters

printerName – printer name

Example:

 var image = document.createElement('img');
var labelXml = dymo.label.framework.openLabelFile(labelUri).getLabelXml();
var pngData = dymo.label.framework.renderLabel(labelXml, "", printerName);
image.src = "data:image/png;base64," + pngData;

dymo.label.framework.printLabel(printerName, paramXml, labelXml, labelSetXml)

 

Purpose:  Prints a label on the specified printer.
Parameters:

printerName – printer name

paramXml – printing parameters

labelXml – DOM or XML representation of the label

labelSetXml – data set for label objects

Example:

 var paramsXml = dymo.label.framework. createLabelWriterPrintParamsXml ({ copies: 2 });
var labelSetXml = new dymo.label.framework.LabelSetBuilder();
var record = labelSet.addRecord();
record.setText("Address", "Test Address String");
dymo.label.framework.printLabel(printerName, paramsXml, labelXml, labelSetXml);

 

TROUBLESHOOTING

 

What is Trace functionality?

Our JavaScript Library now includes trace functionality that may help you debug your code.  You can enable it by adding the following code vline before calling the init() method:

dymo.label.framework.trace = 1;
dymo.label.framework.init(callback);

When using this code, you will see which steps the library takes every time it attempts to initialize (i.e., synchronous vs asynchronous initialization, port number if web service is discovered, fallback implementation selection, etc.).

Below is sample trace output when init() is called and the web service is present:

checkEnvironment > cachedWebPort : 41951
checkEnvironment > trying async service discovery
_createFramework > return _framework : undefined (async)
onEnvironmentChecked > checkResult isBrowserSupported : true, isFrameworkInstalled: true, isWebServicePresent: true
chooseEnvironment > WebServicePresent

The following is an example for case when init() is not called but the web service is running (fallback mode for legacy user code):

checkEnvironment > cachedWebPort : 41951
checkEnvironment > trying sync service discovery
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user’s experience.
checkEnvironment > web service found at port :41951
onEnvironmentChecked > checkResult isBrowserSupported : true, isFrameworkInstalled: true, isWebServicePresent: true
chooseEnvironment > WebServicePresent

This sample output demonstrates the case when the web service is not running (fallback mode for legacy plug-ins).  Here the init() method was called; not calling the init() method will eventually lead to same fallback behavior but will additionally result in a hung UI during the initialization phase):

checkEnvironment > cachedWebPort : undefined
checkEnvironment > trying async service discovery
_createFramework > return _framework : undefined (async)
checkLegacyPlugins > WIN platform
checkLegacyPlugins > non-IE
checkLegacyPlugins > ‘application/x-dymolabel’
onEnvironmentChecked > checkResult isBrowserSupported : true, isFrameworkInstalled: true, isWebServicePresent: false
chooseEnvironment > WIN

 

How do I perform error logging?

Improper DYMO Label SDK usage or multiple unexpected external factors may result in errors.  You may need to retrieve logging data in these cases to help resolve problems.

Network and web service errors

To see communication errors and service fault messages, you will need to open Developer Tools (invoked by F12 key in most browsers) and open “Network” tab. If you see erroneous response in the list, you can click it and look for details in adjacent window (look and position is browser-specific). Response body would normally contain error description.

Web service log

The log file is located at %LocalAppData%\DYMO\DLS8\DLSWebService.log

If you are performing some specific tests, we recommend you delete the existing log before making a test run to eliminate any unnecessary log messages.

Aug 032016
 

There has been a lot of confusion out there among our developers as to whether they should use the DLS installer or the SDK installer within apps that make use of our DYMO printers.

Let’s try to clear this up as it isn’t immediately obvious what each installer is used for.

Our DLS installer contains everything needed to integrate printing functionality within your app.  This is what needs to be installed in order for your apps to work.

The SDK installer, on the other hand, contains documentation and samples that describe how to make use of the functionality found within the DLS SDK.  The “SDK installer” isn’t really named appropriately and will probably be renamed in future releases for the sake of clarity.

The DLS installers for both Windows and Mac can be found at the following URL:

http://www.dymo.com/en-US/online-support/dymo-user-guides

The SDK installers for both Windows and Mac can be found here:

http://www.dymo.com/en-US/online-support/online-support-sdk

 

Hopefully, that clears things up a bit.

Aug 202015
 

We are proud to announce the Open Beta of the new DYMO Label Framework JavaScript Library 2.0. This solution uses a new communication mechanism that will work on all browsers. This means that we have removed the dependency of browser specific plugins like NPAPI and Active-X. The current DYMO Label Framework API is fully supported.

Requirements

The new init method

Since the new communication protocol needs to discover the port that the DYMO service is listening on, a new method was introduced, dymo.label.framework.init(callback). This method performs a scan of a range of ports to look for the DYMO service. This method needs to finish before any other DYMO Framework API calls are made. To accomplish this, the method takes a callback method that will be called as soon as the dymo.label.framework.init method finishes.

Backward Compatibility Mode

If the dymo.label.framework.init method is not called (i.e. no user code has been changed) then the Framework goes into backward compatibility mode. It will try to scan the first port in the defined range and if it finds the service, the new communication protocol will be used. If it fails, it will fall back to the previous implementation that uses native plugins (NPAPI/Active-X).

Init Example

Typical startup code where a method is subscribed to an onload event:

function startupCode() {
    /* access DYMO Label Framework Library */
}
window.onload = startupCode;

The code should be changed to call a shim that will initialize the DYMO Framework before calling the rest of the startup code.

function startupCode() {
    /* access DYMO Label Framework Library */
}
function frameworkInitShim() {
    dymo.label.framework.init(startupCode); //init, then invoke a callback
}
window.onload = frameworkInitShim;

Tracing

We have added a new tracing feature. This can be used to help debug issues with the new service. The property is called dymo.label.framework.trace. When set to true, it will put tracing messages in the browser developer console. You should set the trace property before calling the dymo.label.framework.init method:

Tracing Example

dymo.label.framework.trace = 1; //true
dymo.label.framework.init(startupCode);

Known Limitations

  • The port number that the service binds to is not user definable. We tried to use a range of ports that are not typically used but there could be port conflicts.
  • HTTPS: Because the service currently uses insecure (http) requests, some browsers may have some issues. For example, Firefox will block insecure XHR requests when a page is loaded through HTTPS. So in order to enable it, the user has to click icon in the address bar and enable insecure requests within a secure connection.
  • As stated in the requirements, a Microsoft patch is typically required on Windows 8 and greater.
  • MacOSX support is not included in this Beta, we are working on it now and we will post more news about this version soon.
  • As with DLS, we do not support Windows Server configurations.

To Do

  • A new version of the DYMO Label Software 8.5.2 will become available. This version will include the new Framework implementation and will be considered the Release version of the new Framework. This is expected to be released near the end of September.
  • Service Configuration (Port Number): Currently, the service will bind to the first available port within a given range. We will add a parameter that will allow a user to assign a particular port within the given range.
  • Investigate the best way to work over HTTPS without issues
  • We are implementing asynchronous versions of existing API methods
  • Take constructive feedback and bug reports from our Beta Customers. We will be releasing new versions of the Beta as we respond to issues found in the field.

Update 08/28/2015

If the Web Service fails to install, try and turn off your Anti-virus software before installing.

 

Update 09/09/2015

We apologize for the delay of the next version of the Beta.  We’ve have been working on full HTTPS support, for which testing is ongoing, we found some issues and want to fix them before releasing.  We’ve also reproduced the service not recognizing networked printers.  We are investigating the possible solutions since it appears to be a limitation of what the service has access to.  We’ll keep you informed of any developments.

Dec 162011
 

The previous post demonstrated different ways of printing QR-code from a .NET application. This blog post will demonstrate how to achieve the same goal from a web application. The complete sample is available here. The corresponding JavaScript is here.

Prerequisites

First, make sure the latest DYMO Label software is installed. It is always available on DYMO web-site, at the time of writing it is version 8.3.1.

Use Barcode Object

The easiest way to print QR-code is to use built-in support for QR-code in DYMO Label Framework. First, design your label using DYMO Label software. Unfortunately, DYMO Label itself does not have ability to specify QR-code barcode type in the UI yet. So, add the Barcode object to the label and put it into desired position. Don’t specify the barcode symbology, use the default Code39. Save the label in to a file, open the file in any XML editor and change thetag to “QRCode”.

<BarcodeObject>
    <Name>Barcode</Name>
    <ForeColor Alpha="255" Red="0" Green="0" Blue="0" />
    <BackColor Alpha="0" Red="255" Green="255" Blue="255" />
    <LinkedObjectName></LinkedObjectName>
    <Rotation>Rotation0</Rotation>
    <IsMirrored>False</IsMirrored>
    <IsVariable>False</IsVariable>
    <Text></Text>
   <Type>QRCode</Type>
    <Size>Large</Size>
    <TextPosition>None</TextPosition>
    <TextFont Family="Arial" Size="8" Bold="False" Italic="False" Underline="False" Strikeout="False" />
    <CheckSumFont Family="Arial" Size="8" Bold="False" Italic="False" Underline="False" Strikeout="False" />
    <TextEmbedding>None</TextEmbedding>
    <ECLevel>0</ECLevel>
    <HorizontalAlignment>Left</HorizontalAlignment>
    <QuietZonesPadding Left="0" Top="0" Right="0" Bottom="0" />
</BarcodeObject>

See Barcode.label from the sample. After the label is ready, the actual steps to print it is quite easy: open the label, set desired data, print. Here is a snippet from the sample:

printButton.onclick = function()
{
    try
    {
        if (!barcodeLabel)
            throw "Load label before printing";

        if (!printersSelect.value)
            throw "Select printer.";

        barcodeLabel.setObjectText('Barcode', 'http://developers.dymo.com');
        barcodeLabel.print(printersSelect.value);
    }
    catch(e)
    {
        alert(e.message || e);
    }
}

First, we check that the label is loaded and the printer is selected. Next, the barcode data is set to be the blog’s URL. And finally, the label is printed.

Use Image Object

Printing QR-code by using Barcode object is easy. The only drawback, it is hard to control the actual barcode size. tag can be used for that but it support only three predefined sizes Small/Medium/Large, but still the overall size will depend on the actual barcode data. The longer the data string, the larger is the barcode. So, the idea is to use some library to generate QR-code image of desired size, and then print it using the Image object. As before, design a label using DYMO Label software. Put an Image object on the label where the barcode should be printed. Set the Image objet size to the desired barcode size. When specifying the barcode image size in pixels calculate it based on the printer resolution, that is 300 dpi for LabelWriter printers and 180 dpi for Tape printers. For example, if you want the barcode to be 1” in size, specify the barcode image size as 300×300 pixels. See BarcodeAsImage.label from the sample project.

Image object accepts image data as a string that contains base64-encoded png stream. The question is, how to get/generate this string. Again, there are several ways of doing that.

Generate and base64-encode QR-code image on the server-side

One way is to generate QR-code image on the server using some library. Then encode the image using base64 and return it to the client as a string. Finally, on the client side, call setObjectText on the Image object and print.

printAsImageButton.onclick = function()
{
    try
    {
        if (!barcodeAsImageLabel)
            throw "Load label before printing";

        if (!printersSelect.value)
            throw "Select printer";

        $.get("qr.base64", function(qr)
        {
            try
            {
                barcodeAsImageLabel.setObjectText('Image', qr);

                barcodeAsImageLabel.print(printersSelect.value);
            }
            catch(e)
            {
                alert(e.message || e);
            }
        }, "text");

    }
    catch(e)
    {
        alert(e.message || e);
    }
}

In the sample, we just request “qr.base64” resource that contains precalculated QR-code image for “http://developers.dymo.com”. In real application, you will probably pass the data to be encoded as a resource parameter.

Generate QR-code image on the server-side and base64-encode it on the client-side.

Base64-encoded strings are larger then binary png data. So, to reduce network traffic, we can return original png data from the server and base64-encode it on the client. To encode the data we will create , render our image on it, and then get encoded data using canvas.toDataURL() method.

printAsImageCanvasButton.onclick = function()
{
    try
    {
        if (!barcodeAsImageLabel)
            throw "Load label before printing";

        if (!printersSelect.value)
            throw "Select printer.";

        var img = new Image();
        img.onload = function()
        {
            try
            {
                var canvas = document.createElement('canvas');
                canvas.width = img.width;
                canvas.height = img.height;

                var context = canvas.getContext('2d');
                context.drawImage(img, 0, 0);

                var dataUrl = canvas.toDataURL('image/png');
                var pngBase64 = dataUrl.substr('data:image/png;base64,'.length);

                barcodeAsImageLabel.setObjectText('Image', pngBase64);
                barcodeAsImageLabel.print(printersSelect.value);
            }
            catch(e)
            {
                alert(e.message || e);
            }
        };
        img.onerror = function()
        {
            alert('Unable to load "qr.png"');
        };
        img.src = 'qr.png';
    }
    catch(e)
    {
        alert(e.message || e);
    }
}

Note: image loading is asynchronous process. So, we can’t just assign img.src property and immediately draw it on a canvas; we have to wait until the image is loaded completely from the server. To handle that, we do main work in onload handler. also, toDataURL returns data url, to get the data itself, we have to remove the url prefix.

Again, as in the previous case, qr.png resource contains recalculated QR-code image for “http://developers.dymo.com”. In real application, you will probably pass the data to be encoded as a resource parameter.

A drawback of this method is that it requires support in the browser. All major browsers already support it, but be aware that in Internet Explorer it is supported starting from version 9 only.

Use third-party service

Instead of generating QR-code image on your own server, is it possible to use one of the many free online QR-code generator/service? The answer is yes, but it is even more trickier than the previous way. The problem, as usual in web development, is the security. But default is it not possible to grab canvas pixels if an image from a different domain has been drawn on the canvas. It is possible to overcome it, but it requires three parties to participate properly. First, your JavaScript has to set img.crossOrigin property to ‘anonymous’. This will tell the browser that you are trying to access a cross-domain resource, so the browser can send appropriate request headers, e.g. the browser will not send cookies. Next, the server itself should allow its resources to be accessible from other domains. Only few of many QR-code online generators do allow it. And the last, the browser itself should support CORS for . It is very recent addition to the standards, so at the time of writing only Chrome does support it. In any other browsers you will still get “security exception” error. Here are some links regarding and cross-domain limitations:

http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#security-with-canvas-elements

http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html

http://code.google.com/p/chromium/issues/detail?id=82042

Update (2011-12-20): works in Firefox 9 as well.

printAsImageCanvas2Button.onclick = function()
{
    try
    {
        if (!barcodeAsImageLabel)
            throw "Load label before printing";

        if (!printersSelect.value)
            throw "Select printer.";

        var img = new Image();
        img.crossOrigin = 'anonymous';
        img.onload = function()
        {
            try
            {
                var canvas = document.createElement('canvas');
                canvas.width = img.width;
                canvas.height = img.height;

                var context = canvas.getContext('2d');
                context.drawImage(img, 0, 0);

                var dataUrl = canvas.toDataURL('image/png');
                var pngBase64 = dataUrl.substr('data:image/png;base64,'.length);

                barcodeAsImageLabel.setObjectText('Image', pngBase64);
                barcodeAsImageLabel.print(printersSelect.value);
            }
            catch(e)
            {
                alert(e.message || e);
            }
        };
        img.onerror = function()
        {
            alert('Unable to load qr-code image');
        };
        img.src = 'https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl=http%3A//developers.dymo.com&choe=UTF-8';
    }
    catch(e)
    {
        alert(e.message || e);
    }
}

The code is very similar to the previous example. The only difference is that we set img.crossOrigin property and we use Google’s Infographics API to generate the qr-code image. Notice that in this example the image is generated dynamically, and barcode data is passed as the part of the url.

Pure client-side JavaScript

At the time of writing, it seems there is no self-contained pure JavaScript solutions to create QR-code images using <canvas> completely on the client-side. In the future it might be one more way of doing QR-code printing.

Conclusion

It is quite simple to print QR-code barcode even if built-in support is somewhat limited.

Nov 292011
 

This blog post will demonstrate how it is easy to print a label with a QR-code barcode from any .NET application. Even more, it will show how to do that in two different ways. The sample VS 2008 project is available here.

Prerequisites

First, make sure the latest DYMO Label software is installed. It is always available on DYMO web-site, at the time of writing it is version 8.3.1. Next, in Visual Studio create a new .NET project and add a reference to DYMO.Label.Framework assembly. This will make possible to use DYMO Label Framework API in the project.

Use Barcode Object

The easiest way to print QR-code is to use built-in support for QR-code in DYMO Label Framework. First, design your label using DYMO Label software. Unfortunately, DYMO Label itself does not have ability to specify QR-code barcode type in the UI yet. So, add the Barcode object to the label and put it into desired position. Don’t specify the barcode symbology, use the default Code39. Save the label in to a file, open the file in any XML editor and change the <Type> tag to “QRCode”.

<BarcodeObject>
    <Name>Barcode</Name>
    <ForeColor Alpha="255" Red="0" Green="0" Blue="0" />
    <BackColor Alpha="0" Red="255" Green="255" Blue="255" />
    <LinkedObjectName></LinkedObjectName>
    <Rotation>Rotation0</Rotation>
    <IsMirrored>False</IsMirrored>
    <IsVariable>False</IsVariable>
    <Text></Text>
    <Type>QRCode</Type>
    <Size>Large</Size>
    <TextPosition>None</TextPosition>
    <TextFont Family="Arial" Size="8" Bold="False" Italic="False" Underline="False" Strikeout="False" />
    <CheckSumFont Family="Arial" Size="8" Bold="False" Italic="False" Underline="False" Strikeout="False" />
    <TextEmbedding>None</TextEmbedding>
    <ECLevel>0</ECLevel>
    <HorizontalAlignment>Left</HorizontalAlignment>
    <QuietZonesPadding Left="0" Top="0" Right="0" Bottom="0" />
</BarcodeObject>

See Barcode.label file in the sample project. After the label is ready, the actual steps to print it is quite easy: open the label, set desired data, print. Here is a snippet from the sample:

private void PrintBarcodeButton_Click(object sender, RoutedEventArgs e)
{
    // load label template
    var label = DYMO.Label.Framework.Label.Open(
        Application.GetResourceStream(
            new Uri("Barcode.label", UriKind.Relative)).Stream);

    // set barcode data
    label.SetObjectText("Barcode", "http://developers.dymo.com");

    // print
    label.Print(PrintersComboBox.Text);
}

First, label is loaded from a file, stored as a resource in the application assembly. Next, the barcode data is set to be the blog’s URL. And finally, the label is printed on the printer selected in the UI.

Use Image Object

Printing QR-code by using Barcode object is easy. The only drawback, it is hard to control the actual barcode size. <Size> tag can be used for that but it support only three predefined sizes Small/Medium/Large, but still the overall size will depend on the actual barcode data. The longer the data string, the larger is the barcode. So, the idea is to use some library to generate QR-code image of desired size, and then print it using the Image object. As before, design a label using DYMO Label software. Put an Image object on the label where the barcode should be printed. Set the Image’s Scale Mode to None to avoid image scaling and possible problems with the scanning/reading of the printed barcode. See BarcodeAsImage.label from the sample project. Then use selected library to generate the QR-code image. When specifying the barcode image size in pixels calculate it based on the printer resolution, that is 300 dpi for LabelWriter printers and 180 dpi for Tape printers. For example, if you want the barcode to be 1” in size, specify the barcode image size as 300×300 pixels. Actuals API calls are very similar to the first case.

private void PrintBarcodeAsImageButton_Click(object sender, RoutedEventArgs e)
{
    // load label template
    var label = DYMO.Label.Framework.Label.Open(
        Application.GetResourceStream(
            new Uri("BarcodeAsImage.label", UriKind.Relative)).Stream);

    // set data as a barcode image
    var imageStream = Application.GetResourceStream(
            new Uri("qr.png", UriKind.Relative)).Stream;

    label.SetImagePngData("Image", imageStream);

    // print
    label.Print(PrintersComboBox.Text);
}

First, label is loaded from a file, stored as a resource in the application assembly. Next, the barcode image is “generated”; for the simplicity, already created png file is used instead of library calls. Next, the image data is assigned to the Image object. And finally, the label is printed on the printer selected in the UI.

Conclusion

It is quite simple to print QR-code barcode even if built-in support is somewhat limited. The next post will show how to do the same thing by using DYMO Label JavaScript library.

Nov 172011
 

Here is one more sample demonstrates capabilities of DYMO Label JavaScript library. The correspondent JavaScript file is here.

Getting Printers

First, the sample shows how to retrieve a list of available DYMO printers. For each printer it shows all the available properties. To get the printer list use dymo.label.framework.getPrinters function. The function returns an array contains information regarding each printer. The sample calls getPrinters and then put all the information onto a table, see createPrintersTable() for details.

Note: There are helpful function to filter the result list to contain only LabelWriter or Tape printers; use dymo.label.framework.getLabelWriterPrinters or dymo.label.framework.getTapePrinters accordingly. This might be useful if your application is designed to print on die-cut labels or D1 tapes only.

Print Multiple Labels

Next, the sample shows how to print multiple labels at once, in one print job. The sample leverages the library’s LabelSet functionality do archive that. For each printer the sample creates one label set record represent data to be printed on one label. also the sample demonstrates how to apply different text styles to the print data. It uses a feature called text markup, the ability to apply formatting attributes/tags very similar to HTML ones. 

// create label set to print printers' data
var labelSetBuilder = new dymo.label.framework.LabelSetBuilder();
for (var i = 0; i < printers.length; i++)
{
    var printer = printers[i];

    // process each printer info as a separate label
    var record = labelSetBuilder.addRecord();

    // compose text data
    // use framework's text markup feature to set text formatting
    // because text markup is xml you can use any xml tools to compose it
    // here we will use simple text manipulations to avoid cross-browser compatibility.
    var info = "<font family='Courier New' size='14'>"; // default font
    info = info + "Printer: <b>" + printer.name + "n</b>"; 
    info = info + "PrinterType: " + printer.printerType;
    info = info + "n<font size='10'>is local: " + printer.isLocal;
    info = info + "nis online: " + printer.isConnected + "</font>";

    if (typeof printer.isTwinTurbo != "undefined")
    {
        if (printer.isTwinTurbo)
            info = info + "<i><u><br/>The printer is TwinTurbo!!!</u></i>";
        else
            info = info + "<font size='6'><br/>Oops, the printer is NOT TwinTurbo</font>";
    }

    if (typeof printer.isAutoCutSupported != "undefined")
    {
        if (printer.isAutoCutSupported)
            info = info + "<i><u><br/>The printer supports auto-cut!!!</u></i>";
        else
            info = info + "<font size='6'><br/>The printer does not supports auto-cut</font>";
    }

    info = info + "</font>";

    // when printing put info into object with name "Text"
    record.setTextMarkup("Text", info);
}

See print() function for a complete sample.

Note: Here is another blog post regarding using text markup. And one more regarding printing multiple labels.

Oct 042011
 

There are two ways of providing dynamic text data to be printed on your labels. In both cases the text can be “styled”, so different parts of the text will use different fonts, sizes and/or styles.

The first way covers most use cases for text formatting needs, it is simple, and, of cause, has some limitations. The limitation is that it supports line-by-line formatting only. So, each line can have its own formatting, but all characters in the same line will use the same formatting. If this is OK for your application, then here are the steps needed to utilize this method. first, you have to design you label layout/template. The easiest way to design a label is by using DYMO Label software. While designing, type a sample data for a label object, and apply some formatting, on line by line basis, e.g. make the first line bold, save the file, and put it on your server. 

image

Those are manual steps, now we will need some JavaScript. Load the label by using openLabelXml. Now you can set your real data by using setLabelText or, if you need to print multiple labels, by using a LabelSet. You pass a plain string without any formatting to the setLabelText method, and the library will apply line-by-line formatting for you based on the sample data in the label file. For example, if you call setLabelText(‘Will E. CoyotenACME Birdingn2200 Desert Meadows WaynLas Vegas, NV 89122’), the output will be like that:

image

The second way to format the text is by using so called “Text Markup” feature. It is some what more complex than the first formatting method, but in return you have the full control over the font attributes and can do character-by-character formatting. First, you design your label as described above, but you don’t have to specify any sample data. Next you have to construct a “text markup”.  A text markup is an xml string contains tags controlling font attributes, plus plain text data. The Supported tags are ones similar to HTML tags: <font>, <b>, <i>, <u>, <s>, <br>. Full xml-schema definition is available here. After you have the markup text, you can print it by using a LabelSet and setTextMarkup method.

var labelSet = new dymo.label.framework.LabelSetBuilder();
var record = labelSet.addRecord();

var textMarkup = '...';
record.setTextMarkup('Text', textMarkup);
label.print('DYMO LabelWriter 450', null, labelSet.toString());

Here is an example demonstrates different formatting capabilities: http://labelwriter.com/software/dls/sdk/samples/js/TextMarkup/TextMarkup.html, and the corresponded JavaScript http://labelwriter.com/software/dls/sdk/samples/js/TextMarkup/TextMarkup.js. Type anything into the “Text to Print” text box and click on any button below. The output should correspond to the button’s caption. The corresponded text markup will be copied to the “Text Markup” text box, so you can examine it without going into JavaScript debugger. Also, you can just type any text markup in the box and print it by clicking on “Print text markup” button. Just make sure it is a correct xml and correct markup. If it is not, a runtime error/exception is thrown.

Jul 192011
 

We are proud to announce a BETA release of the DYMO Label Mobile SDK for Android. The DYMO Label Mobile SDK for Android is a complete toolset containing libraries, documentation, and samples that make it easy to add label printing to any Android app. All DYMO LabelWriter and DYMO LabelManager printers are supported. Using the DYMO Label Mobile SDK in combination with DYMO Label Web SDK allows creating both native and web-based apps for Android.

Please Note

This release is a BETA and is not supported by DYMO. It has not been extensively tested outside DYMO and should be used for developer testing only, NOT for production software releases.

Architecture Overview

It is essentially the same as the architecture of DYMO Label Mobile SDK for iOS.

DYMOLabelMobileSDKforAndroid

The major piece here is a computer that has a DYMO printer plugged-in and DYMO Label software installed. DYMO Label software contains a service called DYMO Label Proxy that allows communication between an Android device and the printer.

Notes:

  • right now DYMO Label Proxy is available for Windows only. So, a printer must be connected to a Windows machine, or be available from Windows machine that has DYMO Label Proxy installed (see below).
  • the printer itself does not have to be connected directly to the computer running DYMO Label Proxy. The printer has to be ACCESSIBLE from that machine. This means that the printer might be really connected to a different machine and be a “shared” network printer. Or the printer might be connected to a DYMO Print Server and be “installed” on the computer using a RAW TCP/IP port. This setup might be used to simplify installation (see below).
  • the local network is used for communications between the proxy service and the mobile device. That means that on the mobile device the Wi-Fi should be turned on and the device should be connected to the network. Using just 3G is not enough.

Installation

SDK Installation

SDK is available here. It is a zip file, just extract it to any folder. Inside there are following folders:

  • docs – SDK documentation. Contains API reference documentation in JavaDoc format.
  • libs – jars to be included with an application.
  • Samples – sample apps.

Samples were tested with Eclipse Helios and Android SDK r11. The SDK supports Android API level 8 (2.2) and later.

DYMO Label Proxy Installation

The installation is fairly simple. Just install DYMO Label software, that’s it. DYMO Label Proxy service will be installed and run as a part of the installation. DYMO Label Proxy is a Windows service running on port 8631 by default. Because of that there are couple of considerations that must be taken into account:

  • DYMO Label Software will configure Windows Firewall to open the port 8631 for inbound requests. If a different firewall software is installed, you have to configure it manually.
  • The port number may be changed from the default one. Either use the configuration utility included or specify the port manually in the service’s application .config file. In any case don’t forget to update the firewall rules to open the port. Otherwise clients will not be able to connect to the service.
  • The final release to the public will add the ability to select the port number and autostart options for the service during installation.

Note: This version of DYMO Label Proxy contains enchantments and bug fixes over the version released for Web and iOS SDKs. To be able to use with Android SDK you must update it to the latest version.

DYMO Label Proxy Configuration

To configure the service use DYMOLabelProxyServiceConfiguration.exe utility. It lets you change the port number the service is listening to as well as stop/start/restart the service. In addition the utility displays a list of urls that might be used to connect to the service.

image_thumb

Changing Port Number

To change the port number enter a new value into “Port Number” field and click “Apply” button. Right now the service is not restarted automatically, so don’t forget to restart it.

Service Control

You can start/stop/restart the service from within the configuration utility. Alternatively the standard “Services” panel of the  “Computer Management” tool can be used.

Service ip-address

Usually the SDK is able to discover the service on the network automatically using Bonjour. But sometimes Bonjour does not work. One common case is when the service and the Android device are on different subnets, e.g. the mobile device is connected to a “wireless” subnet and the service to a “wired” subnet. This is not a problem with the DYMO service, it is how Bonjour works in its default configuration. There are solutions for this problem, but the detailed descriptions are beyond the scope of this post. Some ideas:

In this case it is necessary to know the service’s ip-address to be able to connect to it from the Android device (see below). The configuration utility can help here as well. Service’s ip-address(es) is displayed in Service URIs list.

API Overview

The SDK contains two complete samples those demonstrate most of the functionality the SDK provides. Here we will look at the API from the point of tasks that are necessary to perform to print a label. To print a label the following tasks usually have to be performed:

  1. framework initialization
  2. discover a printer to print the label on
  3. load label layout
  4. set label data
  5. perform actual printing
  6. Monitor printing progress

Note: these tasks might be performed in a different order, e.g. printer discovery might be performed after the label is prepared for the printing. Though usually printer discovery should be performed first, because it can take some time.

Framework Initialization

All SDK classes and interfaces are accessed from a top label Framework object. A constructor of Framework class accept Context as a parameter. The context might be either an activity/service or be the application context. The Framework instance can be created inside activity’s onCreate()  handler. Note, that Framework initialization might take some time; so if the activity ca be frequently recreated or if the Framework should be accessed from different activities, it make sense to use some sort of singleton to make sure only one instance of the Framework exists.

import android.content.Context;
import com.dymo.label.framework.Framework;

class PrintLabelManager
{
    static private PrintLabelManager instance_;

    static PrintLabelManager instance(Context context)
    {
        if (instance_ == null)
            instance_ = new PrintLabelManager(context);

        return instance_;
    }

    private Framework framework_;

    private PrintLabelManager(Context context)
    {
        framework_ = new Framework(context.getApplicationContext());
    }

    Framework getFramework()
    {
        return framework_;
    }
}
import com.dymo.label.framework.Framework;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends Activity
{
    private Framework framework_; 

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        setupFramework();
    }

    private void setupFramework()
    {
        framework_ = PrintLabelManager.instance(this).getFramework();
    }
}

 

Discover Printers

Before something can be printed it is necessary to know on which printer it will be printed. Printer discovery is an asynchronous operation. The reason is that it requires network communications and various delays and timeouts might happen during the process. To handle async notifications of the discovering progress a PrintersListener object should be assigned to the Framework object. PrintersListener defines two methods, one called when a new printer or printers are discovered, another when some sort of failure happened. To assign the listener use setPrintersListeners() method. To start discovering call startRefreshPrinters() method. This method is asynchronous and returns almost immediately. When a printer is found the listener’s method newPrintersFound() will be called. The list of available printers can be obtained by the Framework.getPrinters() or by  NewPrintersFoundEvent.getPrinters() methods. If the Proxy service could not be contacted during the discovering, e.g. it went offline, the printerLookupFailure() method will be called. Here is a code snippet to demonstrate that:

public class MainActivity extends Activity
{
    private void setupFramework()
    {
        framework_ = PrintLabelManager.instance(this).getFramework();
        framework_.setPrintersListener(new PrintersListener()
        {
            @Override
            public void printerLookupFailure(PrinterLookupFailureEvent event)
            {
                final String message = String.format("Unable to contact '%s' (%s)", event.getPrinterUri(),
                    event.getLocation());
                Log.e("Print Label", message);

                MainActivity.this.runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
                    }
                });
            }

            @Override
            public void newPrintersFound(final NewPrintersFoundEvent event)
            {
                runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        // output all discovered printers to the log
                        Iterable<Printer> printers = event.getPrinters();
                        for (Printer p : printers)
                            Log.i("Print Label", p.getName());
                    }
                });
            }
        });
    }
}

Please note, the listener’s methods are called from a non-UI thread. So, if you need to perform any UI related operations that must be called from the UI thread, don’t forget to use Activity.runOnUiThread() or View.postDelayed() methods.

Unlike iOS API there is no way to automatically determine when printer discovering should be stopped. It is important to stop it manually by calling stopRefreshPrinters()method. If stopRefreshPrinters() is not called this may lead to an extensive battery drain (underneath implementation uses Bonjour, that uses multicast network requests, and the requests use a lot of power). Call stopRefreshPrinters() after a timeout and when the activity is been stopped.

    // refreshes printers and update currently selected one
    private void refreshPrinters()
    {

        framework_.startRefreshPrinters();

        // / stop refreshing in 5 seconds
        labelContentEditText_.postDelayed(new CheckedRunnable()
        {
            @Override
            public void run2()
            {
                Log.i("PrintLabel", "----------- Stopping printers lookup after 5 seconds");
                framework_.stopRefreshPrinters();

                // usually this is called from newPrintersFound() handler
                // newPrintersFound will not be called if all printers are gone 
                updateCurrentPrinter(framework_.getPrinters());
            }
        }, 5000);
    }

 

Load Label Layout

A label layout specifies what will printed on a label. The layout contains ‘label objects’ – text, address, barcode, image, etc. Each object has a ‘reference name’, so the object can be referenced programmatically from the SDK. Usually DYMO Label software is used to create a layout and save it as xml file. Because the layout is serialized as a xml document, the layout can be created or modified using any xml editor or even programmatically. This and that blog posts describe label format in great details. To load label layout use one of Framework.openLabel() methods. Usually we will load the layout from an asset. Something like this:

    Label label = framework_.openLabel(this, "Address.label");

This assumes, that the Android project  has “Address.label” file in the assets folder.

image

Set Label Data

Label Layout can already contain data to be printed, e.g. an address. this might be a case when a label is generated dynamically on the server. But usually we will need to set data programmatically based on user’s input. This can be done using two different methods.

The first method allows printing of one label only. Use Label.setObjectText(String objectName, String objectText) method to set text data of Address, Text, Barcode, and CircularText objects. Use setObjectImage(String objectName, Bitmap image) to set image data for Image objects.

The second method is more universal, and it allows printing multiple labels at once. It is implemented using a “label set” concept. Label set is similar to a recordset, a database table. Label set consist of a set of “label records”. Each label record represents data to be printed on one label. Label record itself is conceptually is a dictionary (associative array), where dictionary keys are label object names, and dictionary values are label object data. To manipulate a label set use LabelSet interface. Use addRecord method to add a record into a label set. To set object data in the record, use LabelSetRecord methods. There are methods to add text and image data similar to ones above. Also, there is way to specify formatted/styled text data where each character or line can have different formatting (font size and style). To create a LabelSet use Framework.createLabelSet() method.

public class MainActivity extends Activity
{
    void printWithLabelSet(Printer printer)
    {
        // open a label
        Label label = framework_.openLabel(this, "Address.label");

        // create a label set
        LabelSet labelSet = framework_.createLabelSet();

        // label #1
        LabelSetRecord record = labelSet.addRecord();
        record.setText("TEXT", "6x7=42");

        //label #2
        record = labelSet.addRecord();
        record.setTextMarkup("TEXT", "font family='Arial' size='36'>6x7=<b>42</b></font>");

        // print label
        label.print(printer, labelSet);
    }
}

Actual Printing

To start printing call Label.print() methods. There are several  overrides, the most generic one is print(Printer printer, PrintParams printParams, LabelSet labelSet)

We have to provide three parameters:

  • printer – printer to print the label on. The printer instance can be obtained from a list of available printers populated during printer discovering process described above. This is the only required parameter, all other can be omitted.
  • printParams – printing parameters, like number of copies, print quality, etc. This parameter can be null, in witch case defaults will be used.
  • labelSet – a label set contains data to be printed. If omitted, the data contained by label instance will be printed.

This method call is asynchronous as well. Right after all necessary data are assembled the method returns. Printing progress monitoring can be done using PrintJob instance returned by the print() method (see below).

Print Progress Monitoring

PrintJob instance returned by the Label.print() call can be used to monitor print progress. Periodically call getStatus() method to retrieve current status information. Note: currently only this “polling” schema is supported; in the future we might add “pushing” data from the printer when it status has changed. getStatus() is an async call as well; when the status data has been retrieved from the printer, the PrintJobListener method statusReceived(PrintJobStatusReceivedEvent event) is called. Here is an example:

public class MainActivity extends Activity
{
    private void printButtonClick()
    {
        try
        {
            //... open label, assemble print data, etc 

            // print with default parameters
            final PrintJob job = label.print(currentPrinter);

            final Runnable getStatus = new CheckedRunnable()
            {
                @Override
                public void run2()
                {
                    job.getStatus();
                }
            };

            // an executor service to ask for the status in the background 
            final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

            // set the listener to be called when the status received
            job.setOnStatusListener(new PrintJobListener()
            {

                @Override
                public void statusReceived(PrintJobStatusReceivedEvent event)
                {
                    try
                    {
                        final PrintJobStatus jobStatus = event.getPrintJobStatus();
                        final JobStatusId statusId = jobStatus.getStatusId();
                        final String statusMessage = jobStatus.getStatusMessage();
                        Log.i("job status", statusMessage);

                        switch (statusId)
                        {
                        case ProcessingError:
                            // bad - unrecoverable printing error, do not ask status again
                            break;

                        case Finished:
                            // done - printing is done, do not ask status again
                            break;

                        default:
                            // OK - printing is in progress, ask the status after one second delay
                            scheduler.schedule(getStatus, 1, TimeUnit.SECONDS);
                            break;
                        }

                    }
                    catch (Exception e)
                    {
                        handleException(e);
                    }
                }
            });

            // schedule first status request in a second
            scheduler.schedule(getStatus, 1, TimeUnit.SECONDS);

        } catch (Exception e)
        {
            handleException(e);
        }
    }
}

Setup an Eclipse Project to Use SDK

Add Jars into a classpath

To use classes from the SDK two jars must be added to a class path (both can be found in the libs folder). The first one is DymoLabelFramework.jar – it contains the SDK classes. The second one is jmdns.jar. It contains Bonjour implementation used for printer discovering. JmDNS is an open source implementation of Bonjour/multicast-DNS for Java. The version bundled with the SDK is JmDNS 3.4.0 and can be downloaded from http://sourceforge.net/projects/jmdns/

Check Android SDK Target Version

The DymoLabelFramework internally uses some classes available only starting from Android SDK API level 8 (Android 2.2, Froyo). Make sure the project targets Android 2.2 or later.

Set Proper Permissions

The SDK requires two permissions to be set in AndroidManifest.xml. The first is android.permission.INTERNET, so the SDK be communicate with the Proxy service. The second is android.permission.CHANGE_WIFI_MULTICAST_STATE that is required to be able to use Bonjour for printer discovering.

Note: samples applications use another one, android.permission.ACCESS_NETWORK_STATE. It is uses to determine Wi-Fi status and ask a user to turn Wi-Fi on if necessary because otherwise no printers can be discovered. It is strictly to be a little bit more user-friendly, and is NOT required.

Setup an Ant Build Script to Use SDK

Use Android SDK tools to generate/update initial build.xml file.

Check Android SDK target version in default.properties file, so target=android-8 (or later).

Specify path where the jars are located in build.properties by using jar.libs.dir  property. E.g. for the sample projects jar.libs.dir=../../libs.

Note: to compile sample projects from the command line you have to specify path to the Android SDK in the local.properties file by using sdk.dir property.

Conclusion

DYMO Label Mobile SDK for Android provides a simple way to add label printing capabilities to any Android app. Along with DYMO Label Web SDK developers can use DYMO printers from their web-based applications or  from native apps.