What I Learned At TechDays 2009 Toronto! Part 1 Windows Mobile 6.5

TechDays Toronto 2009 wrapped up nicely on Wednesday, and I’ve finally had a chance to go through and review my pages and pages of notes (writing, diagrams, and chicken scratch).  I learned a lot at this event, and I’m planning on blogging a few posts over the next few days about it.  I find that just by blogging and thinking about the things I wrote down at the event helps me to retain a lot more than I would have otherwise, and it gives me another opportunity to think about these topics more deeply.

Ok – before I get to the sessions, let me start with lunch –> Lunch the 1st day was satisfactory at best, but lunch redeemed itself on the second day with the Chicken Salad Sandwich.  There were some booths and tables set up outside the lunch area demoing products and other things, but I didn’t see much there for developers – albeit I gave it a quick “twice-over” and didn’t look too deeply at any of the tables.

The power of Twitter!  I’ve been able to get involved with the TechDays twitter conversation with the tag #TechDays_ca – this was a powerful way to connect with many people attending the event and also many of the speakers and organizers.  I’d recommend to anybody to hit up the Twitter bandwagon.  I use TweetDeck to manage my tweets and twitter conversations.

So, in no particular order, I want to talk about some of the top things I learned and that interested me the most….. Let me start with the Windows Mobile Session…..

1.Windows Mobile 6.5

 In the “Taking Your Application on the Road with Windows Mobile Software” session, Mark Arteaga and Anthony Bartolo did a presentation on Windows Mobile 6.5 development and the Windows Mobile Marketplace.  This was a session I was really looking forward to, and it didn’t disappoint.  I have done some mobile development as it relates to the manufacturing environment that’s mostly related to data collecting, bar code scanning, etc.  I’ve done some interesting things around queuing to local SQL databases when the server is unavailable and things like that.  However, in this session Marc explained things in Windows mobile 6.5 that were just completely cool, but not only cool – practical demos and applications were also discussed.  The potential with Windows Mobile 6.5 is really exciting.

Let me summarize the key points, from my notes, that were most interesting to me:

Fake GPS

  • Used for development of GPS enabled applications
  • Emulates a physical GPS
  • Uses a text file for reading raw GPS data

Cellular Emulator

  • Integrate with Pocket Outlook (contacts, email, SMS, appointments, tasks)
  • In the development environment (Visual Studio .NET)
  • Send phone calls to the emulated phone
  • Send SMS messages

Windows Mobile Marketplace

  • Launch to coincide with the release of Windows Mobile 6.5
  • A market place for developers to sell their applications to Windows mobile users (my impression is that it will be similar to the app store on the iPod)
  • Developers get 70% of money for the purchase of the software by consumers.  Microsoft gets 30% which goes directly into the infrastructure of the Marketplace

WM 6.5 & Misc

  • Full IE browser with the same capabilities as the desktop browser (Note: This is a huge feature in my opinion.  I’m a Windows Mobile user and the browser is very limited.  Although I hear positive things about Opera, my experience with is has left me wanting to go back to Pocket IE)
  • Gestures (I can see these touch gestures being useful and allowing the developer to create better mobile apps with native gestures built in for flipping, panning, etc)
  • Widgets – similar to gadgets available in Windows XP
  • System state – trapping phone calls, SMS, media player song information, etc
  • Accelerometer available on certain devices – Unified Sensor API is available on codeplex
  • GSensor – Shake and Drop detection

Although I don’t see the new features having a big impact right now on the type of mobile application development that I’m currently involved with on the shop floor, there is definitely potential in the future as more device manufacturers provide hardware that is compatible with the latest Windows Mobile OS.  The move to include a full IE browser, as I understand it, will give the mobile device the same IE functionality as with a desktop PC, but I don’t believe that this functionality will take away from the types of applications that are currently developed natively for Windows Mobile (versus running in a browser) using .NET, C++, etc…. but in the realm of mobile browser based applications this is a huge step forward.  It also guarantees that any existing website should work on the mobile browser – however, if it is not customized for the mobile screen display resolution it may not look correctly or will require you to pan and scan the page.

I do see a huge impact for mobile development in the areas outside the shop floor environment with Windows Mobile 6.5.  For anybody interested in (or currently) developing mobile applications on the .NET framework, WM 6.5 is very promising.  Based on what I’ve seen, the quality of available applications should be increased with WM 6.5, and time to market from development to production will likely be able to decrease due to the addition of new native functionality.

At the end of the session they gave away Rock Band Beatles Edition to the winner of an audience competition where audience members got up in front of everyone to describe the mobile application they’ve been working on.  Cool!

To be continued – I will post again shortly about some more things I learned at TechDays Toronto 2009.

Dan

Advertisements

Mobile Scanner Application Framework: An Application Architecture for Mobile Scanner Applications:

This blog post will go over the application architecture used to create mobile bar code scanning applications that take advantage of a reusable framework, design patterns, and a layered approach.  We have several applications that run on mobile scanner devices running Windows Mobile OS (Example: Intermec CK31 device).  This layered approach works for applications developed natively using the .NET Compact Framework as well as applications developed using the full framework running over a terminal server.  I got involved in developing a new mobile scanning application recently, so I went over the source code of our previous scanning applications and found a big problem:   Old mobile scanner applications were not layered or structured in a way that made architectural sense, were not easily understandable, and the code was tedious to look at yet alone update. I also looked for ways I could refactor the code to make it generic and reusable. Previously, all of our scanning applications had code to handle basic tasks like accepting input into a text box, validating the contents, moving to the next field to scan, checking for the proper qualifier (the beginning character of the scan), etc, but in addition to the items listed above, the code was not re-usable and looked like a garbled mess.

I created a project titled ScannerInput to encapsulate the functionality and validation that was typical in our bar code scanning applications.   The project encapsulates all of the logic required for scanning functionality for our mobile scanning applications and its object model supports extensibility in functionality so that features such as custom validation can be implemented in a structured and clean way.  In addition, the application framework internally references the user interface components to provide tighter control and logic flow within the UI elements.

What is does:

  • Validates qualifier used for the scanned input (multiple qualifiers can be specified)
  • Validates contents of scanned inputs (validation routine is contained within a strategy (strategy design pattern))
  • Moves to next field if scanned data is valid (yes, the framework references the UI element and takes care of this for the client application developer)
  • Prevents the user from changing fields if the current field does not pass validation
  • Clears field and raises validation event on client if scanned data is invalid
  • Raises event back to client when last field has been successfully scanned (the client decides if it should restart the process, or do whatever else the client wants to do)
  • Raises an event to the client if the user cancels the scanning process (the client decides what it wants to do in this event)
  • Client has control of the functionality of the ScannerInput objects by setting properties and handling events

Here is a class diagram representing the two main classes in the ScannerInput project:

image

ScannerInput Class

This class represents a textbox control on the form, but also the qualifier or qualifiers required for the input and how the textbox value should be validated. This is done using the strategy pattern (see below). Here is an example of client code that would instantiate a ScannerInput class and specifies the validator strategy to use in the New constructor:

  si = New ScannerInput(New ScannerInputFieldLengthValidator(4, 7))
  si.TextBoxControl = txtMachineCode
  si.Qualifiers.Add("D")
  si.FieldName = "Machine Code"
  

Internally, when the TextBoxControl property is assigned, the ScannerInput class adds its own event handlers to the control. For example, it handles the KeyPress event to know when to validate the contents of the field. The ScannerInput code handles all of the logic and user interface control flow such as navigation between text boxes as input is scanned, preventing changing focus of text boxes if validation hasn’t passed, validating qualifier, and validating scanned data.

In four lines of code we now have a text box that is jacked into the scanning routine of the framework.  Now, it will easily accept and validate scanned input.  If scanned data is valid it will move on to the next text box for more input or can be directed to open another form or do any other programming task as events are raised back to the client that the client can handle and do what it likes if it chooses to.

ScannerInputControls Class

This class inherits a generic List (Of ScannerInput) class. It allows the client to add ScannerInput objects to the list (see below). It exposes a set of events that are raised back to the client. To add a ScannerInput control to the list you would simple use code as follows:

m_ScannerInputControls.Add(si)

Strategy Pattern Used For Validation Extensibility and Code Separation of Validation Logic

The strategy pattern is used for the validation piece of the architecture. As data is scanned into a field, the contents need to be validated. Here is the Interface used for the strategy and a couple of examples of the strategy implementation.

The interface:

Public Interface IScannerInputValidater
    ''' <summary>
    ''' Validates the content of the ScannerInput control textbox
    ''' Part of Strategy design pattern
    ''' </summary>
    Function Validate(ByVal ScannerInputObject As ScannerInput, ByVal Value As String) As Boolean
End Interface

Validator Classes implementing the interface:

Public Class ScannerInputShiftValidator
    Implements IScannerInputValidater

    Dim _ErrorMessage As String

    Public Function Validate(ByVal ScannerInputObject As ScannerInput, ByVal Value As String) As Boolean _
    Implements IScannerInputValidater.Validate
        Select Case Value.ToUpper
            Case "A", "B", "C"
                Return True
            Case Else
                _ErrorMessage = "Invalid Shift Entered"
                Return False
        End Select
    End Function
End Class

Public Class ScannerInputFieldLengthValidator
    Implements IScannerInputValidater

    Dim _MinLength As Integer
    Dim _MaxLength As Integer
    Dim _ErrorMessage As String

    Public Sub New(ByVal MinLength As Integer, ByVal MaxLength As Integer)
        _MinLength = MinLength
        _MaxLength = MaxLength
    End Sub

    Public Function Validate(ByVal ScannerInputObject As ScannerInput, ByVal Value As String) As Boolean _
    Implements IScannerInputValidater.Validate
        If Value.Length >= _MinLength And Value.Length <= _MaxLength Then
            Return True
        Else
            Return False
        End If
    End Function
End Class

Public Class ScannerInputNumericValidator
    Implements IScannerInputValidater
    Dim _ErrorMessage As String

    Public Function Validate(ByVal ScannerInputObject As ScannerInput, ByVal Value As String) As Boolean Implements IScannerInputValidater.Validate
        If IsNumeric(Value) Then
            Return True
        Else
            Return False
        End If
    End Function
End Class

Public Class ScannerInputNumericGreaterThanZeroValidator
    Implements IScannerInputValidater
    Dim _ErrorMessage As String

    Public Function Validate(ByVal ScannerInputObject As ScannerInput, ByVal Value As String) As Boolean Implements IScannerInputValidater.Validate
        If IsNumeric(Value) Then
            If Val(Value) > 0 Then
                Return True
            Else
                Return False
            End If
            Return True
        Else
            Return False
        End If
    End Function
End Class

The nice thing here is that there are generic validators to validate simple things like numeric values, or field length ranges. A validator could easily be written and re-used to check a database table to see if an item scanned, for example, is an actual item that exists in a backend database. This could be done without modifying any of the ScannerInput project files, but simply by passing in the instance of the validator to the New constructor of the ScannerInput instance.  Looking back at our old way of doing things, we had scanner input control logic intertwined with validation code along with constants used to specify the qualifiers used for each field- etc… and all of this was in a single code file – it was unsightly.

Now, if you are wondering.. What if you want to have multiple validators validate a ScannerInput object?

The New constructor of the ScannerInput object has only one validator parameter option, but you can easily bundle calls to multiple validators by creating a new class object of type IScannerInputValidater that internally uses multiple validators or has the capability to add validators to a collection at runtime and use them by sequentially calling the validate method of each one.  An instance of the object would just need to be passed into the New constructor if the ScannerInput object.

Client Application

I just want to briefly describe the application used to develop and test the Mobile Scanner Application Framework.  The client application was designed using an n-Layer approach (UI, Data, Business, and Facade layers), ORM mapping, and the Microsoft Enterprise Library Logging and Instrumentation Block.  Future mobile scanning applications can use the Mobile Scanner Application Framework by referencing the ScannerInput project from the user interface layer and simply create ScannerInput objects and assign them a few properties (as we saw in the code samples above). The ScannerInput project takes care of the sequential program flow and validation of data scanned into the text boxes. There is very little code in the UI client project in comparison to our previous scanning applications. Most of the code in this new approach is creating a couple instances of ScannerInput objects and assigning their properties and then handling the events raised back to the client by the ScannerInputControls list object.

Here’s a screen shot of a client using the Mobile Scanner Application Framework:

image
  • In this case the letter in brackets indicates the qualifier (first character(s) in the scanned input required to be there to be considered valid (handled entirely by the framework).
  • Each text box is tied to a ScannerInput object (see code example above) which handles validation and sending error notification back to the client to handle – in this case the client handles it by displaying a validation error message on the client form.
  • As scanned input is completed the framework takes care of moving between fields.
  • As per the object model listed at the top of this post, events are raised at certain points within the framework (Validation, CycleCompleted, CycleCanceled)

Conclusion

  • The situation just required a little thought (On deciding to develop the framework I asked myself:  How could I make this easier, more structured, and more maintainable?)
  • Client mobile scanner applications are easier to maintain than our non-structured mobile applications without sacrificing anything in the User Interface
  • The strategy pattern is used for validation and new validators can be added by creating a class to hold your custom validation logic that implements IScannerInputValidator and then simply passing it to the New constructor of the ScannerInput object. This seperates validation logic from the rest of the application logic making initial development, maintenance, updates easier, more effective, and cleaner
  • Bugs are easier to track down and fix – you can see this as it is very easy to identify where validation takes place, user interface code, and mobile scanning code takes place.  Couple this with a well designed user interface (layers, best practices, etc) and you have an easy to maintain application.
  • It took less time to create the ScannerInput project and write the client code from scratch than it would have taken if I used an archaic approach of copying the code from an old scanning application and pasting the code into the new project where the program flow relied on writing almost the same code for the KeyPress, Focus, LostFocus events for every single input text box on the form
  • New Mobile Scanning applications can be created with ease
  • Writing new mobile scanner client applications is much quicker and much less frustrating
  • Orchestrating and modifying the program flow of code written all over the place (from validation, to program flow logic) would not have been fun if I had used an unstructured approach
  • Adding a new text box for scanner input to the form requires 3 or 4 lines of code to hook it up into a ScannerInput object. The old way would have required copying and pasting event handlers and creating a new method in the code file for its own validation routine, etc.
  • Client applications can benefit by enhancements to the program flow and logic contained within the framework immediately as they are developed.

Note: I don’t have the ScannerInput project source code posted to this blog right now.  I am hoping to find some more time very soon to revisit this and post the rest of the code including the internals of the ScannerInput object.  If you are looking for more information in the meantime please contact me or leave me a comment.

Dan