Welcome to Michael Lehman's Independent Innovation Sign in | Help

As I'm working on an Android project, I was trying to build a Google sample and got a weird error message that the IDE couldn't auto-fix:

The project is using an unsupported version of the Android Gradle plugin.

For anyone else searching for this, then answer turned out to be that this version (0.8.9) of Android Studio use a newer version than the one specified in the build.gradle file.  Updating from 0.9.+ to 0.12.+ fixed the issue for me.

Seems like this will be an on-going problem with using Android Studio unless Google continuously goes back and updates their sample code, which seems unlikely.

Hope this helps! 

Ok, time to start communicating in the textual way once again!

Hard to believe it's been nearly 10 years since I started podcasting and blogging.   (For a blast from the past check out: Adventures in Softwareland

These days I'm spending most of my time building and teaching about things that are a combination of software and hardware, the so-called Internet-of-Things.

It's fun to get back to my roots as a hardware hacker.  Hard to believe it's been 40 years since I built my own, custom-designed, implemented totally in TTL, 8-bit CPU.

This was in the days before the Altair, before the 6502, when a "personal computer" meant you had a 6-foot-tall, 19-inch-wide rack of electronics connected to a 10-characters-per-second (very loud) ASR-33 Teletype such as a PDP-8 or PDP-11.

Now you can buy a full Arduino or Linux (Raspberry Pi, etc.) box for under $50 that has digital and analog I/O built-in along with compilers, interpreters, and all the tools  you'd ever want, including 32GB memory cards!  (That first 8-bit CPU I built had a gigantic 256-BYTES of RAM and no ROM).

Anyway, time to share what I've been up to and point the way to solutions that I've found along the way so... here we go (again)! 

Well, after years of turning up my nose at the primordial soup that is Android (no offense meant, just so much apparent chaos) I'm now doing an Android project and finding that Eclipse and the latest tools have many redeeming qualities :)

Can't say what I'm working on but suffice it to say, it's fun and for that I am very grateful.

Hard to believe it's been nearly 20 years (1995) since I first learned Java. 

After many hours of programming saved based on downloading free source code from SourceForge and GitHub, we (DreamTimeStudioZ) have finally released our first open-source library: IORecipes for Windows 8 and Windows Phone 8.

Doing I/O using the Windows.Storage APIs on Windows 8 and Windows Phone 8 is relatively straightforward yet doing simple things like creating a file involves handling exceptions and potentially multiple API calls so we built a library that makes simple things simple.

Some of the APIs are listed below.

For full documentation and to download IORecipes go to: https://github.com/DreamTimerZ/IORecipes

Enjoy!

 

Create a file in the specified folder

    public static async Task<StorageFile> CreateFileInFolder(StorageFolder storageFolder, string fileName)

Create the specified subfolder in the app's root storage folder

    public static async Task<StorageFolder> CreateOrGetFolder(string folderName)

Delete the specified file from the specified folder

    public static async Task<bool> DeleteFileInFolder(StorageFolder storageFolder, string fileName)

Get the root folder for storing files created by your user

    public static StorageFolder GetAppStorageFolder()

Get the installation folder for the current app. This is used to retrieve data files you've bundled with your app as opposed to data files created by your user.

    public static StorageFolder GetAppInstallationFolder()

Get the names of all the files in the default folder for this app

    public static async Task<List<string>> GetDocumentFiles()

Get a list of names of files whose filename ends with the specified extension

     public static async Task<List<string>> GetDocumentFilesOfTypeFromFolder(StorageFolder storageFolder, string extension)

After having spent the better part of a day discovering how to build a simple C++ library for a Windows Phone 8 app, I thought I’d share.

The few couple steps are relatively easy:

  1. Create your Windows Phone 8 app in C# or VB
  2. Add an additional project using the Windows Runtime Component template.
  3. Add a reference to your second (WinRT) component to your managed project using the Add Reference dialog.

The tricky part comes when you want to start passing strings around.  All the Microsoft documentation tells you all about how to pass numbers, Enums, etc. but nothing, not even on StackOverflow about passing strings.

The key is using the Platform namespace in your unmanaged code.  In my case I wanted to pass in a string and return a number.  The key is to discover there’s support for managed strings but you have to know where to look.

First, declare your method in the .h file of your C++ class like this:

int GetNumberFromString(Platform::String^ ValueData);

and then define the method in the .cpp file of your C++ class like this:

int WindowsPhoneRuntimeComponent::GetNumberFromString(Platform::String^ ValueData)
{
    int i;
    i = ValueData -> Length();

    return i;
}

 

Note two key things:

  1. The parameter is defined of type Platform::String^
  2. The parameter is a pointer to a string object, thus you must use the –> operator to reference it’s methods, such as Length() in the example above.

One final thing, to access the string contents, call the Data method which returns a pointer to type const wchar_t.

Hopefully this saves somebody a few hours someday!

After much searching and reading of the circular-referencing Live SDK documentation, I *finally* found a library on GitHub that does exactly what we needed:  Simple, API-based SkyDrive manipulation with working examples!

Three cheers for the Live SDK for Windows: https://github.com/liveservices/LiveSDK-for-Windows

If you’re doing development on Windows Phone you will really want to get these two tools:

 

First, Windows Phone Tools (standalone app) from Codeplex: http://wptools.codeplex.com/

Second, Isolated Storage Explorer extension for Visual Studio 2012 (requires Pro or above) http://visualstudiogallery.msdn.microsoft.com/c4cdb312-2017-4370-a572-8c38526f4b4a  integrates basic Isolated Storage access directly inside VS.

Both highly recommended!

Well, 2012 was an interesting year, technology-wise for me.  I used new tools, revisited old dusty corners of my techno-memory and learned a bit about teaching technology.

Q1 – 2012

=======

In the early part of the year I completed my first from-scratch Mac OS app since the advent of Objective-C… a far cry from the days of the Tardis Software FastFinder (my command-line replacement for the MacOS 1.0 Finder – check out this letters-to-editor page from April 1985) and Consulair C (Bill Duvall’s original C compiler for Mac).

Q2 – 2012

=======

That adventure was followed by my first foray into the sound booth at Lynda.com where I recorded our first online course, Windows Phone SDK Essential Training.  I had reached out to the great folks at Lynda.com in late 2011 and, serendipitously had the opportunity to follow in Joe Marini’s footsteps when he moved from Microsoft to Google.

I then started on my journey of retro-tech.  In May, I had the opportunity to revisit the world of DirectX and video capture.  It’s amazing how this world has not made much forward progress since the 1990’s.  In order to capture video + audio you still need to create filter graphs (a non-trivial process!) and then load them (an even more non-trivial process) and make sure they don’t leak memory.  I’m happy to say that the result went into production and is happily being enjoyed by visitors to the “museum” as you read this.

Q3 – 2012

=======

Having moved once again through the land of ancient technology, I worked hard to find a new gig with a more modern flavor.  It turned out to be much more difficult that I’d imagined, given the actual dearth of real developers doing mobile apps, and yet I finally landed what I thought was the gig of the year – 7 months doing iOS apps. 

Starting in late July, I had the opportunity to work with a great agency here in Seattle as part of a team building a cutting-edge iOS/Android hybrid app – I got to build the iOS platform on which an HTML5 ‘responsive’ app would live.  The team was great, the environment was urban and energized, what’s not to like?  Well, once the app was built in 3 weeks or so, I went to the VP and said, OK, this is a 7 month gig, what’s next?  Well, it seems there was a SNAFU between engineering and their HR folks and it was intended to be a 5-7 WEEK gig, not a 7 MONTH gig. 

So back to looking for the next good thing I went…  and found it a few weeks later back in retro-tech land.

Q4 – 2012

=======

Continuing in the clear theme for 2012, the year ended even more retro, and simultaneously modern, than I could have imagined.

I’m both in the final stages of authoring a beginner’s course on iOS development and, because it involves multiple interlocking NDA’s I can only say that these days my toolset includes WinDBG (the Windows Kernel debugger) and multiple Linux VMs based on Ubuntu and Debian.

It’s amazing how one’s fingers remember the old commands (page down in ‘vi’ is still ctrl+f, insert is still just the single keystroke ‘I’, etc. etc.) once the cobwebs are dusted off.

And on to 2013…

In the coming year my plan is to create more than consume, get outside everyday and enjoy yet another fascinating circumsolar journey!

Happy New Year everybawdy (as we used to say in the early days of podcasting ;)

 

Well…, I finally figured out how to use the new Windows.Phone.Media.Capture API to record audio on my Nokia 920 Windows Phone 8 device!

Unlike the XNA-based recording feature which works on Windows Phone 7.x that only retrieves raw data, this new (to WP8) API allows the capture of audio in one of 3 formats:

  • AAC – Advanced Audio Coding
  • AMR – Adaptive Multi-Rate Encoding
  • PCM – Good ‘ol WAV file format

After days of searching and finding no sample code I decided to just try to “think like the developer” and try to make anything work.

The biggest issue, once I figured out that there was no callback features which I could use to create a ‘VU’ meter-like effect (to show the amplitude of the incoming single), was to hunt for how to create an IRandomAccessStream from a MemoryStream object.   The answer is… you don’t! 

The two tricks to making it work were (a) understanding that it ONLY records to files not to memory and (b) you MUST use the new WinRT Windows.Storage APIs to create the file.

Here’s the guts of a simple app that has a “Record” button and a “Stop” button.  I started with the Windows Phone App template (not the databound one) and added two buttons then added the code.

Here’s the XAML:

<!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel"
              Grid.Row="1"
              Margin="12,0,12,0">
            <StackPanel Orientation="Vertical">
                <Button x:Name="Button1"
                        Content="Record to file as AAC"
                        HorizontalAlignment="Center"
                        Margin="0,50,0,0"
                        Click="Button_Click_1" />
                <Button x:Name="Button2"
                        Content="Stop Recording"
                        HorizontalAlignment="Center"
                        Margin="0,50,0,0"
                        Click="Button2_Click"
                        Visibility="Collapsed"/>
            </StackPanel>
        </Grid>

 

And here’s the code-behind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using PhoneApp1.Resources;
using Windows.Phone.Media.Capture;
using Windows.Storage.Streams;
using Windows.Storage;
 
namespace PhoneApp1
{
    public partial class MainPage : PhoneApplicationPage
    {
        //
        // file for the recorded audio
        //
        StorageFile outputFile;
 
        //
        // Audio capture device instance
        //
        AudioVideoCaptureDevice dev;
 
        /// <summary>
        /// Handle tap on the "Record" button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void Button_Click_1(object sender, RoutedEventArgs e)
        {
            //

// First, we have to get a reference to

// our applications "local" folder

            //
            StorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
            
            //
            // Then we have to see if we can create a folder 
            // named 'data' underneath that
            //
            StorageFolder dataFolder = null;
 
            //
            // Note:  The way to determine if a Folder exists is to 'get' it
            // and catch the FileNotFound exception
            //
            try
            {
                dataFolder = await applicationFolder.GetFolderAsync("data");
            }
            catch
            {
                dataFolder = null;
            }
 
            //
            // If we didn't get it, let's create it
            //
            if (dataFolder == null)
            {
                dataFolder = await applicationFolder.CreateFolderAsync("data");
            }
 
            //
            // Now we create the file
            //
            outputFile = await dataFolder.CreateFileAsync("test.aac", 
                               CreationCollisionOption.ReplaceExisting);
 
            //
            // and then open it as a stream so we can write to it
            //
            var stream = await outputFile.OpenAsync(FileAccessMode.ReadWrite);
            
            //
            // Next, open the capture device for audio only and set the recording format
            //
            dev = await AudioVideoCaptureDevice.OpenForAudioOnlyAsync();
            dev.AudioEncodingFormat = CameraCaptureAudioFormat.Amr;
 
            //
            // Finally, let's start recording and disable our button so the
            // user can't try to start recording before stopping
            //
            dev.StartRecordingToStreamAsync(stream);
            
            Button2.Visibility = System.Windows.Visibility.Visible;
            Button1.IsEnabled = false;
        }
 
        /// <summary>
        /// Handle a tap on the "Stop" button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void Button2_Click(object sender, RoutedEventArgs e)
        {
            //
            // Stop recording and re-enable our record button
            //
            await dev.StopRecordingAsync();
            Button2.Visibility = System.Windows.Visibility.Collapsed;
            Button1.IsEnabled = true;
        }
 
 
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }
 
    }
}

 

And that’s it! 

As I’m plotting updates to my Windows Phone course for Windows Phone 8, I ran across a number of interesting libraries that Windows Phone devs might find useful.

All are open-source and available via NuGet:

As I said earlier, I’m working on an online video course for iOS developers.  After covering the basics of the 30,000 ft. view, a quick Hello World app, an XCode tour and a short “Objective-C for C# and Java developers”, I’m on to exploring all the built-in controls.

When you’re writing apps, at least for me, I’ve found that I learn exactly what I need to know to do the job which means “not everything.”   For example, as I was exploring UIButton, I found out that you can either have a background image (which stretches) and/or an image next to the caption (which doesn’t).

I also discovered you can have a background image AND the text caption together.

The longer I work at being a teacher of technology, the more I appreciate all the hard work the teachers I’ve been blessed with over the years put in to make it look so easy!  Thank you all.

With the release of Windows Phone 8, I’m starting to look at all the new and updated features to figure out how my Windows Phone SDK Essential Training course might be updated.

I’m surprised that Microsoft’s developer site seems to be a little short on code examples specifically for the updated SDK.

Well… Nokia to the rescue!  If you want Windows Phone 8 sample code, look no further!  Check out this awesome list of the new SDK features WITH CODE on the Nokia Developer Wiki.

I’m working on a new video-based course for beginning iOS developers.  Finally got all the kinks worked out of the recording systems and dove into actually recording the content today!

If you have any questions about developing for iOS please let me know in the comments and I’ll do my best to address them in the course content.

Today’s ex-bug is a doozy.  I have code which has been running on iOS since iOS3 and it just stopped working recently in iOS6.

UIAlertView is an API call which presents a popup ‘dialog’ at the bottom of the screen with one or more buttons used in situations like confirmation of a delete from a UITableView.

One of our apps was built on the ‘utility’ model in which there’s a main view and one or more modal views which appear like turning a card over (i.e. a flip along the vertical axis from right-to-left as you go deeper and left-to-right as you unwind).

In the main view, there was a delegate method named ‘canBecomeFirstResponder’ which is used to provide start/pause/resume control of the audio recording via the headphone play/pause.

However, when showing an UIAlertView in one of the ‘modal’ views, the canBecomeFirstResponder of the main view was being called and returned YES even when the main view wasn’t visible.

The fix, for us, was to keep track of when the ‘modal’ views were on-screen and return NO to the call to canBecomeFirstResponder and it works like a champ!

Chalk up one for the good guys and we’re off to the App Store to put the update in the queue for review!

Today’s Win8 developer head scratcher:

Run Visual Studio 2012 on another computer using Remote Desktop (RDC) and when you press F5 to debug, if you minimize the RDC window while it’s launching, the “store” app never appears.  Visual Studio thinks it’s running but you can’t get to the app’s full-screen window to interact with it.

Never happens when you’re running on the actual machine nor does it ever fail as long as the RDC window is not minimized.

I suspect that it’s the virtual video driver somehow.

More Posts Next page »