Categories
News

Cool App Contender: HOP (Hunger Obesity Prevention) App

Embarcadero Cool App ContestThere were a lot of amazing apps submitted for the Embarcadero Cool App Contest. Last month’s winner was 1Password for Windows. Any entries that don’t win one month, are automatically eligible for the next month. We will have our next winner shortly.

In the meantime I thought I would highlight a few of the entries that caught my attention. They are all very cool apps.

Sherwood Middle SchoolThe first one I want to highlight is by two sixth grade girls, Suresh and Safalta, from Sherwood Middle School in Shrewsbury, Massachusetts. They created an app to help tackle two big problems at the same time: Hunger and Obesity.

The idea is brilliant: Educate users on lowering their caloric intake to reduce obesity, and then provide a way for them to donate the money they would have spent on junk food to those who are hungry.

One thing I really liked about this entry is they didn’t start with Delphi. Their school taught them to use Java and Python, and they tried a few different tools. They found they were difficult to use, hard to understand and took a lot more code than they wanted. Then they tried Embarcadero Delphi and found it really easy. As they put it, “Embarcadero provided [an] easy button tool for compiling codes for multiple devices including android, iOS etc. which helped us to develop app quite faster. We are planning to recommend the use of Embarcadero [Delphi] to other kids interested in developing apps.”

They used Delphi with FireMonkey, LiveBindings, FireDAC and SQLite to build their app for iOS and Android. Watch their video as they explain obesity and how their app works.

I’ll share some of what they wrote in their entry too.

Obesity in children and young adults is a global health problem among developed countries. United States ranks first in the world with 35% of male, 39.5% female children, and young adults suffering with obesity. Obesity in children affect an estimated 41 million children worldwide, as per World Health Organization (WHO) and United Nations Children’s Emergency Fund (UNICEF). Obesity leads to major health problems including, type 2 diabetes, high blood pressure, high cholesterol levels, fatty liver disease, gallstones and heart diseases.

Similarly, malnourishment and hunger in poor countries affect 159 million children causing nearly 3.1 million children to die each year in the entire world, as per WHO and UNICEF.

Our goal is to help and motivate kids from developed nations by encouraging them to lose weight by eating less, and use the money saved, to help feed hungry and malnourished children living in poor countries. To achieve this goal, our objective is

  1. To provide a free to all Hunger and Obesity Prevention (HOP) App to help children with obesity, encourage them to lose weight through making conscious efforts to engage in physical activity, avoid junk food and promote eating healthy foods.
  2. Then provide an opportunity for HOP participants to celebrate their achievement, by pledging to donate 25 cents/pound lost to UNICEF for feeding hungry children, as a motivation to lose weight for greater cause.

Purpose: Overeating and genetic reasons are important factors in causing obesity. Eating more food, particularly junk food and lack of physical activity leads to accumulation of excess calories to store as body fat, which then results in weight gain and obesity. Obesity is preventable or reversed by consciously taking control of what you eat, and burning excess calories from the body by exercising regularly.

Our long-term goal is to make an advanced version of HOP with ability to take pictures of food/snacks/drinks and estimate calorie contents, select meals and retrieve calorie information from restaurant menus to keep track of calories consumed each day. In addition, we plan to integrate activity-monitoring apps like “Fitbit” or “Pacer” and precisely monitor the progress with physical activity in fighting obesity.

This basic version of HOP is intended to determine if the user is obese, then set goals to lose weight, track physical activity, dieting plans (such as healthy eating, avoiding junk food and salty snacks), record weight over a period of time. When the participant succeeds in losing 1 pound of their body weight, it means they have cut or burned 3500 calories.

Now we ask the participants to make a pledge to donate the unused calories for saving the lives of starving children. By pledging to do so, it gives a cause for participants with obesity to lose weight and hope for hungry children fighting to survive.

UNICEFOur HOP App designed to pledge 25 cents to UNICEF on their behalf as a way to celebrate their achievement. However, in future users will have options to donate to any charitable organizations that are associated with feeding hungry children. Our mission is to help ending obesity and hunger in children and give them the gift of life, through motivating obese children to SHARE CALORIES with hungry children.

I’m really excited to see their app develop, and it is great that they chose RAD Studio and Object Pascal / Delphi to build this. Especially with 10.1 Berlin it includes easy components to connect with health devices like scales, heart rate monitors and cadence sensors.

Good luck to Suresh and Safalta!

Categories
News

FireMonkey and the Android Misconception

FireMonkey(300px)When it comes to Delphi, C++Builder and FireMonkey’s support for Android, there are 5 caveats.:

  1. ARM Cortex-A series CPU (not Intel Atom)
  2. ARMv7 Instructions
  3. NEON Technology
  4. GPU
  5. Specific versions of Android

At one point there was some attempts made to make a list of devices that were supported either completely or partially, but new devices were coming to quick to track. This lead to the misconception that FireMonkey apps only run on a very small subset of Android devices.

Since that time there have been a number of improvements to the compiler and the FireMonkey framework. Also the landscape of Android devices continues to evolve and change. Yet I still run into people who believe that FireMonkey still only runs on a small subset of devices. I thought I would provide an update and set the record straight.

Tegra 2 and NEON

Shortly before Android support was added, the Tegra 2 processor was in use. It was ARMv7 and Cortex-A, but lacked the NEON SIMD extension. So what is NEON? NEON is a SIMD (Single Instruction Multiple Data) instruction set. When it was introduced it was an option that some ARMv7 processors included to improve performance. Since it was optional, the Tegra 2 excluded it.

Intel i487 SXIt seems kind of uncertain to have some processors with some features, and others missing them, especially if you require them for your application to run. This isn’t some crazy thing that only happened with Android and ARM. Back in the time of the Intel 486 CPU (right before things went Pentium) some systems had an optional 487 math co-processor. This co-processor introduced some additional x87 instructions that accelerated some floating point operations. Some programs would be faster on a machine with x87 support, and others required it. When the Pentium came out, it incorporated the x87 instructions into most of the CPUs (there are always exceptions).

Pentium MMXThe Pentium didn’t end up being the “One CPU to rule them all” though. Along came MMX Instructions. MMX is a is a single instruction, multiple data (SIMD) instruction set that was optional for some CPUs (where have I heard that before?) Some programs were faster on an MMX enabled CPU, and others required it to run at all. After a few years, most all CPUs, even those made by AMD included MMX instructions. It didn’t end there. New CPU instruction sets are introduced all the time, but it is rare that they get the same publicity that MMX or the x87 set did.

What does all of this have to do with NEON, besides perspective? Well, Neon is now part of the ARM standard. The new ARM chips in modern Android devices include Neon. They don’t even both listing it as a feature because it is assumed. The R&D team bet on NEON and they won. Since the compiler takes advantage of Neon instructions it is faster than it would be if they hedged their bets and ignored Neon.

Enter the GPU

NVidia 6600GT GPUMuch like the x87 was a separate processor that augmented the system performance, there are many other processors in your computer, specifically around audio and graphics. The big thing about the GPU is that it not only beefed up the existing graphics co-processors, but it took on the 3D and texture operations and ran them through a massively parallel architecture. The original GPU that I had was actually a separate board in addition to my graphics card. Today they are mostly integrated.

On Android they typically go with a System on a Chip (SOC) that includes the CPU, GPU and a number of the other electronics.

The Rise and Fall of Intel Atom

ARM logoARM is an open standard CPU manufactured by many different chip makers, often times under their own brand. A few manufactures include Qualcomm, Texas Instruments, Samsung and even Apple (for their mobile devices). ARM logoIntel wanted a piece of the mobile processor action, but instead of just implementing ARM they introduced the Atom processor. It still used the x86 instruction set of the desktop CPUs, but was designed to be more energy efficient. They put them in Windows tablets and Android devices.

This introduced another division in the Android landscape. There were two different processor architectures. Since most Android apps were written with Java and ran in a virtual machine, it wasn’t a huge deal. Except for games. Most games use native code for performance reasons, so that required either the game to include both ARM and Atom code and libraries, or the game just wouldn’t work on Atom.

Harry Houdini 1899Enter libHoudini. Intel realized that mobile gaming was a big part of Android, and the fact that you couldn’t play a lot of popular games on Atom devices wasn’t good. So they created libHoudini, a proprietary ARM translation layer that translates ARM instructions into x86 instructions for the Atom processor.

libHoudini was around for a while, but around Jelly Bean or KitKat it became standard on Atom based Android devices. This resulted in ARM native apps just working on Atom devices.

Embarcadero was actually in discussions with Intel. There was talk of making an Atom targeted compiler for Android, but work was also done to improve compatibility with libHoudini. Atom was never officially supported (mostly because the market share was too small) so the Android app packager includes a check to say it didn’t work with Atom processors. But you can remove that checker and your app will probably run great on most Atom devices.

While Atom never had a huge share of the market, it looks like it is going to have even less as Intel has cancelled their next Atom processor line.

Android Versions

Unlike Apple, new version updates don’t tend to roll out as fast on Android devices. This means you typically encounter a few different versions of Android running in the wild. It isn’t all that bad though. In my opinion, Ice Cream Sandwich (API 15) was really when Android came into its own. It was Honeycomb (API 14) that finally gave tablets some serious love, and ICS merged those new features back to phones. Anything before ICS is really legacy at this point (at least in my opinion). Android tracks the popularity of Android versions on their Developer Dashboard.

Android Platform Versions Chart
As of May 2, 2016

Ice Cream Sandwich and older only account for a total of 4.3% of Android devices. While there are feature differences between the top 3, nothing is too revolutionary as to make the others obsolete yet.

A Thousand Flowers

Unlike iOS, where Apple is the only company to make devices that run it, Android is EVERYWHERE! I guess I’m kind of a collector of Android devices. I owned the first Android powered watch by WIMM and even created a 6 sided dice app for it. Now that Delphi supports Android I love testing it on different Android devices. Here is a list of my findings

  1. Android Wear – I’ve tested 4 or 5 different Android wear devices, including the Moto 360, and they all worked flawlessly with FireMonkey.
  2. Google Glass – Again, worked out of the box with FireMonkey. We even later added official support. Unfortunately Google is reimagining Glass right now, but I suspect when then new version comes out it will work great.
  3. Epson Moverio BT-200  – Similar to Google Glass, but has two independent translucent lenses so it can do 3D. Runs Android Jelly Bean and works with FireMonkey right out of the box. There is a BT-300 coming soon.
  4. Ouya – This was the Android gaming console that was going to change the world. It ended up under delivering, and then not evolving fast enough. It does however run FireMonkey just fine, and I know a few developers who used it for creative projects.
  5. Amazon FireTV and Fire TV Stick –  Designed to work with your TV and running Amazon’s own version of Android. Again worked like a charm with FireMonkey.
  6. Amazon Fire Phone – I think this is a pretty cool device, a shame it didn’t catch on. Also runs FireMonkey apps fine.
  7. Amazon Kindle Tablets – I’ve not tested these, but I know people who have. Again it runs a different flavor of Android. From what I hear some people had to update their OS to get it to work with FireMonkey, but it did work.
  8. BlackBerry Phone – Yeah, I went there, and so did FireMonkey. It worked too, although there are some idiosyncrasies about the OS that show up when you invoke the share sheet. I originally tested it on the BlackBerry OS, which supports Android apps, but now they’ve gone full Android.
  9. Windows Phone 10 – My Windows Phone wouldn’t install the right preview of Windows 10, but Marco had better luck than I and got FireMonkey apps running on Windows 10 Phone under the Astoria bridge. Then Microsoft discontinued it. Windows Phone never had much market share, and continues to dwindle.
  10. Huge collection of tablets and phones, including one with an Atom processor – they all worked (except that one old Tegra 2 tablet that ran Gingerbread).

Since Android is everywhere I’d wager that there is no Android app that actually runs on every single Android device out there, I don’t care what you wrote it with. Now if someone wants to prove me wrong, that is fine, I suspect different Android devices will be released faster than we can test them.

Conclusion

Let’s run through those requirements again and see how big of an impact they really represent.

  1. ARM Cortex-A series CPU – Atom was never big, and is on its way out. Most everything else is ARM Cortex-A (or newer / compatible).
  2. ARMv7 Instructions – ARMv6 is either really old, or used in a micro device like a beacon or some other IoT device. Not in any Android devices. Oh, and ARMv8 is the big thing now. It is 64-bit and runs FireMonkey apps fine.
  3. NEON Technology – Like I said, it is part of the standard now, so unless you have an old Tegra 2 tablet (I still have one) then nothing to worry about.
  4. GPU – All of the GPU compatibility and performance issues I know of have been fixed, and GPUs are standard on Android devices (at least ones with a screen).
  5. Specific versions of Android – Only 2.3% of devices have an unsupported version of Android.

So while FireMonkey apps may not run on every single Android device in existence, most apps don’t and no app needs to. FireMonkey apps to run on the vast majority of them, and that is what matters.

Categories
News

REST Client Video Challenge

Yesterday, I mentioned I built a REST client and deployed it to iOS and Android inside 5 minutes. Someone asked me to make a video actually showing how it was done. So here it is showing a simple REST client built and deployed to iOS 9.1 and Android 6.0 Marshmallow.

Since I am using SpitCast, and it doesn’t offer an encrypted endpoint for its REST service, I had to modify the Info.plist to allow that on iOS 9.

Could I do it faster without the video recording and explanation? Yes, but I think you get the idea. Delphi makes building multiplatform REST clients really, really easy.

I’m curious to see someone create a client app using other general purpose development tools to connect to a REST service and too see how long that takes.

If I wanted to connect to a different end point to pull down more information on an individual surf spot I could that by handling the OnItemClick event for the List View.

If there is interest I’m happy to share my Sync-Timer source code.

More on Android Services with Delphi 10 Seattle

New Android Service WizardToday we had our RAD Studio 10 Seattle Deep Dive and I expanded on my Minimalistic Android Studio video with some more details. If you didn’t get registered to join us live, be sure and register now to get access to the replay. In the meantime, here are some more details and a new sample for you.

These slides cover both Android Services and iOS Background Execution Mode. You can read about the different iOS Background Modes in Apple’s documentation.

Luis Navaro published a new sample that shows how to download a image in the background with an Android service. It uses a local service, and launches it with an Android Intent.

Here is another sample that shows how to use the bind mechanism to launch an remote Android service and communicates to it via the Java Message (JMessage) object. There are a couple manual steps that you need to consult the included readme about. Otherwise it won’t work as expected. There are three projects in the project group. One is the actual Android Service, then the other two are apps that connect to the project. One of them is the host app that will contain the service within its APK.

Remember, you need to add the service to the host application after building the service. Then you can deploy it within the host app APK.

The DocWiki has an Overview of Android Services and a Guide to Creating Android Services.

Stay tuned for more details about Android Services with Delphi 10 Seattle.

Parallel For Loops

Parallel For Loops are a hassle-free way to supercharge your program with the Parallel Programming Library. The syntax is similar to the standard For loop, with the advantage of each iteration running on in a different task on the thread pool. This allows multiple iterations to run at the same time, taking advantage of the multi-core and hyper-threaded architecture common on laptops, desktops and mobile devices today.

Here is the replay of the Skill Sprint:

Here are the slides:

http://www.slideshare.net/slideshow/embed_code/44464343

Update: I was chatting with Allen Bauer today and he mentioned that while you technically can use Queue and Synchronize from within a Parallel For loop, he wouldn’t recommend it because it will dramatically reduce the speed of the loop. It is still faster than a linear loop, but not as fast as it could be. I’ll leave these examples here, but keep that in mind when optimizing your parallel code.

Here is the syntax in Object Pascal. The stride is the first parameter is it is optional. It controls how the iterations are grouped when being sent to the CPUs. Min and Max are your usual start and stop range for the loop. The last parameter is an anonymous method that represents the code to be executed on each iterations. It takes an Index parameter that is either an Integer or Int64 that provides the value of the current iteration.

TParallel.For(Stride, Min, Max, procedure (Idx: Integer)
begin
  if IsPrime(Idx) then
  begin
    TInterlocked.Increment (Tot);
    TThread.Queue(TThread.CurrentThread, procedure
    begin
      Memo1.Lines.Add(Idx.ToString);
    end);
  end;
end);

Here is the C++ code syntax. It takes a event instead of an anonymous method.

// . . .
TParallel::For(NULL, Min, Max, MyIteratorEvent);
// . . . 

void __fastcall TFormThreading::MyIteratorEvent(TObject *Sender, int AIndex)
{
	if(IsPrime(AIndex)){
		TInterlocked::Increment(Tot);
	};
}

There are some great blog posts and videos on the Parallel Programming Library

Stephen Ball has a series of blog posts on the Parallel Programming Library, including a Quick Introduction and one on managing the thread pool. As Stephen points out, while you can customize the thread pool, that doesn’t alway mean you should. Malcolm Groves also has some great blog posts on PPL.

Danny Wind has a great Code Rage 9 session on the Parallel Programming Library (be sure to download his samples). David I. did the C++ version.

Allen Bauer, our Chief Scientist, also has a CodeRage 9 session on the PPL Architecture.

If you want to take advantage of the new C++11 Lambda syntax on Win64 and mobile, then check out this community article or watch this CodeRage 9 video snippet. Get Bruneau and David’s code for C++ and Parallel libraries.

Update: Keep in mind that a Parallel For loop isn’t always the best performance option, but it is really easy to use. Check out Stefan Glienke’s Stack Overflow answer for an alternative using the PPL TTask for even better performance.

Mobile Push Notifications without a BaaS

Delphi, C++Builder and RAD Studio XE7 include support for mobile push (remote) notifications via a Parse and Kinvey BaaS providers. This makes it really easy to send push notifications to your users on mobile devices. Both Parse and Kinvey offer free service levels (as well as paid), and you can also download App42 SDK for Appmethod and use the App42 BaaS instead.

BaaS or Backend As A Service Providers are companies that maintain the backend servers necessary for many application development tasks. They handle things like user authentication, data storage, push notifications, etc. Sometimes they are referred to as mBaaS or Mobile-BaaS because if the heavy focus on mobile application development these days, but they typically are not tied to mobile.

This doesn’t mean you have to use a BaaS provider to send mobile push notifications. This is just the easy way. During CodeRage we’ve had sessions on how to do push notifications without a BaaS provider. It is different for both iOS and Android, so you are looking at a lot more code and effort, but it is possible.

CodeRage 9 had a session by Jeff LeFebvre had a session on Android Push notifications via Google Cloud Messaging (GCM):

Here is a transcript of the Q&A as well as download links.

For iOS & iPhone use of Apple Push Notifications (APN) Luis Felipe and Anders Ohlsson have some blog posts and videos on the subject. Luis did the original post and video in Spanish, and then Anders translated and expanded on it.

Luis’ post on iOS notifications with XE4 (Spanish but you can use Google Translate). It includes some source code downloads too. The video is also in Spanish but it shows a lot of source code, so it is easy enough to follow along.

Ander’s blog post expanding on it (English), and his CodeRage video on the subject (English)

Keep in mind that this is about the same level of complexity to use most other tools for sending and receiving push notifications.

Categories
News

Voice Enable Your Android Apps

During CodeRage 9 I revisited adding voice support to Android apps. There are some updates from my previous skill sprint coverage on the topic and my original post on launching Google Glass apps via Voice.

You can download the Samples and Components on GitHub. It covers voice recognition, text to speech and launching apps on Google glass with your voice. The examples also cover Android Wear.

Voice Launching Google Glass Apps

  • Add a Voice Trigger XML file:
  • Modify the Android Manifest Template:
    • Add an Intent Filter
      • <action android:name=”com.google.android.glass.action.VOICE_TRIGGER”/>
  • Add Meta Data for Filter
    • <meta-data android:name=”com.google.android.glass.VoiceTrigger”
             android:resource=”@xml/my_voice_trigger” />

Custom Glass Voice Trigger

  • Change XML to from Command to Keyword.
  • Use arbitrary text for voice trigger.
  • Use the Development permission:
    • <uses-permission
      android:name=”com.google.android.glass.permission.DEVELOPMENT”/>
    • Added to android manifest template
  • Not allowed for app store distribution
    • Usable for in-house or ad-hoc use

Additional Prompts on Google Glass

  • Collect additional Voice recognition input when app is launched.
    • Add an Input Prompt to the Voice Trigger XML
      • <?xml version=”1.0″ encoding=”UTF-8″?>
      • <trigger command=”TAKE_A_NOTE”>
      •     <input prompt=”What shall I say?” />
      • </trigger>
  • In FormCreate get speech guesses from Intent Extras
    • SharedActivity.getIntent.getExtras. getStringArrayList(TJRecognizerIntent.JavaClass.EXTRA_RESULTS);

Voice Recognition on AndroidAndroid/Google - Speak Now

  • Prompts user for voice input
  • Returns up to 5 “guesses”
  • Works offline too
    • (only returns 1 guess)
  • Reusable component for download.
  • Requires RECORD_AUDIO & INTERNET permissions.
  • Sends audio to Google’s servers.
  • Uses context to select words.
  • Pronounce punctuation (period, comma, etc.)
  • Works on Android phones & tablets
  • Works on Google Glass
  • Works on Android Wear
  • Doesn’t work on iOS (no exposed API)

Using TSpeechRecognition Component

  • Properties
    • Language: en-US
    • Prompt: Speak now
    • AlwaysGuesses: True
  • Methods
    • Listen
    • ListenFor
  • Events
    • OnRecognition
    • OnRecognitionEx
    • OnCommand

Text-To-Speech on Android

  • Converts Text to spoken word.
  • Reusable component based on Jeff Overcash’s translation.
  • Code shows example of handling Java Listener events.
  • Works on Android phones & tablets
  • Works on Google Glass
  • Doesn’t work on Android Wear (no speaker)
  • iOS Support is possible . . . . (needs implementation)

Using TAndroidTTS Component (component name may change)

  • Just one procedure: Speak

A Note About iOS

  • iOS does not expose voice recognition API
    • (Need to use 3rd party)
  • iOS 7 supports Text to Speech API
    • AVSpeechSynthesizer
    • Just haven’t implemented in component yet

Google Glass Voice Trigger Sample

The replay video will be available here later.

Download the XE7 Trial today and check out the special offers.

Fire UI and the Multi-Device Designer

During CodeRage 9 I had a session on Fire UI and the Multi-Device Designer. You can also check out my previous post on creating a custom FireUI view for the Moto 360.

Fire UI is made up of three parts:

  1. Behavior Services – Runtime & design time platform design information
  2. Multi-Device Designer – Unified project – Tweak UI for platforms
  3. TMultiView Component – Adaptive layout

Behavior Services at Design Time

  • Examples:
    • TTabControl.TabPosition
      • Bottom on iOS, top otherwise
    • Font.Size & Font.Family
    • Many controls have Size.PlatformDefault = True
    • TMultiView mode

Behavior Services at Runtime

  • TBehaviorServices class in FMX.BehaviorManager.pas
  • IDeviceBehavior defines
    • GetDeviceClass: TDeviceInfo.TDeviceClass;
    • GetOSPlatform: TOSPlatform; // Windows, OSX, iOS, Android
    • GetDisplayMetrics: TDeviceDisplayMetrics;
  • IFontBehavior defines
    • GetDefaultFontFamily & GetDefaultFontSize

OS Specific example

 var
  DeviceBehavior: IDeviceBehavior;
begin
  if TBehaviorServices.Current.SupportsBehaviorService(?
    IDeviceBehavior, DeviceBehavior, Self) and
    (DeviceBehavior.GetOSPlatform = TOSPlatform.iOS) then
    // behavior specific to iOS
end;

Display metrics example

var
  DisplayMetrics: TDeviceDisplayMetrics;
begin                        // self is a form in this case
  DisplayMetrics := DeviceBehavior.GetDisplayMetrics(Self);
  if DisplayMetrics.AspectRatio > x then
    // AspectRatio specific behavior
end;
type
TDeviceDisplayMetrics = record
    PhysicalScreenSize: TSize;
    LogicalScreenSize: TSize;
    AspectRatio: Single;
    PixelsPerInch: Integer;
    ScreenScale: Single;
    FontScale: Single;
end;

More Information

Check back later and I’ll have the video replay available too.

Download the XE7 Trial today and check out the special offers.

Categories
News

New XE7 Android Features Skill Sprint

XE7 is full of new features everywhere, but there are some really nice ones specific to Android. Here is a replay of my Skill Sprint session on New Android Features.

The new Android specific features in XE7 include:

There are lots of other new features that are not specific to Android, but that will still help make your apps amazing for Android, iOS, Windows and OS X.

The FireUI: Multi-Device Designer in RAD Studio XE7

Here is the video replay, slides and resources from my Developer Skill Sprint on the new Multi-Device Designer in RAD Studio XE7. This is one part of the new FireUI, the evolution of FireMonkey.

The Multi-Device Designer is a new feature in Appmethod, RAD Studio, Delphi and C++Builder XE7 that makes it easy to maximize the reuse of your visually designed forms across devices, while also getting the most flexibility and customization as possible.

Design your UI once for Windows, OS X, iOS and Android, then customize it for different screen sizes: iPad, iPhone, Tablet, Google Glass, Surface Pro, etc.

You can view the slides on Google Docs.

Check out the Guided Tour on the Welcome Page and the following DocWiki pages:

Check out the other skill sprints too. . .