J2i.Net

Nothing at all and Everything in general.

Chevron Labs is Open for Unlocking Your Phone

If you want to do development on your phone and don't want to register for the Marketplace you have an alternative to paying the full 99 USD to be able to deploy to your phone. You can also register with Chevron Labs 10 USD to get deployment abilities. For the 10 USD fee your phone is unlocked and ready to run your own applications. When you are prepared to deploy to the Marketplace you will need to do the full 99 USD registration, but until then this is a nice start.

Find out more here

No Video Screenshots?

Presently if you need a screenshot of your application on Windows Phone 7 you will need to use the emulator. Recently I came across a developer that found this would not work for him. He needed a screenshot of his application playing video and the video looks lower quality in the emulator. For this scenario you'll need to simulate the screen playing video. It only took me a few minutes to figure out how to do this. I'll start off showing the finished product:

 

To make this I started off recording a video in the emulator. Since there is no real camera in the emulator you get a video of a black square going around the screen. That was fine for my purposes. 

 

Using the image editor of your choice (I used Paint.Net, which is free!) erase the white area in the top of the image. The rest of the image needs to be divided into three layers.

The top layer is going to be made of the transparent part of the image. Using the Magic Wand tool hold down the CONTROL button and click on the transparent overlay above and below the progress bar. Also select the parts of it that are in the play/rewind/forward buttons. Of the time indicator on your screenshot has any numbers with closed shapes (0,4,6,8, or 9) then you will also need to select the inside of the closed area. Once everything is selected go to the edit menu and select "cut." Create a new layer and paste the transparent part into it. You may need to move it around on the screen to get it back into it's original position. 

Right now the transparent isn't really transparent. If you edit the layer properties you can change the transparency. I set the transparency to 196/255. I also changed the color of the overlay to be slightly lighter. 

The opaque parts of the image will still be on the original layer. Create a third layer and in this layer place the image that you want to represent the video. You may need to reorder your layers but after that you are done, just save the image. 

When I did the above I saved my work. So you can download the Paint.Net file and just change the image. If Paint.Net isn't your image editor of choice I also exported the layers into PNG file. You can download them from Skydrive

 

Enable 32-bit Color if Your Application Supports It

The first generation Windows Phones had hardware that used both 16-bit and 32-bit color, but the operating system would force the display to use 16 color regardless. If you have graphics with smooth gradients then then you would end up seeing color bands on a 16-bit display. On Mango if a phone supports 32-bit color you can take advantage of it, but only if you ask! If you want to enable 32-bit color you will need to edit your WMAppManifest.xml. In the <App /> element add an attribute called BitsPerPixel setting its value to 32. That's all you need to do. After doing that when your application runs on a device with 32-bit graphics hardware it will display in 32-bit color mode. 

 

Modified Julian Date

Events related to the solar system and astronomy are often measured with modified Julian dates (MJD). Like regular Julian dates, MJDs are a count of the number of days since some specific date. But Julian dates start at noon whild MJDs start at midnight. The day from which they start counting is also different. 

I was looking for a conversion algorithm and didn't quite like the one's I came across. They were all written for C/C++ and the components of the date and time had to be passed as seperate parameters. There were also some features in .Net that allows one to make the code more readable that just were not available in C/C++. So based off of several other algorithms I encountered I came up with the following. 

 

double TimespanToDayPortion(TimeSpan source)
{
    return source.TotalHours / 24;
}
double TimeToModifiedJulianDate(DateTime sourceTime)
{
    int calcMonth, calcYear, calcDay;

    calcDay = sourceTime.Day;
    if (sourceTime.Month < 2)
    {
        calcMonth = sourceTime.Month + 12;
        calcYear = sourceTime.Year - 1;
    }
    else
    {
        calcMonth = sourceTime.Month;
        calcYear = sourceTime.Year;
    }
    var leapDays = (calcYear / 400) - (calcYear / 100) + (calcYear / 4);
    var mjd = 365L*calcYear - 679004L + leapDays + (int)(30.6001*(calcMonth+1)) + calcDay;
    return mjd + TimespanToDayPortion(sourceTime.TimeOfDay);
}

I've tested this against some other online calculators and they were getting consistent results

For the sake of simplicity I didn't account for the Gregorian calendar reform. As a part of the reform 4 October 1858 was followed by 15 October 1858. I only need this algorithm to do calculations for the current century, so not accounting for that has no impact on my needs.

I'll have to use this algorithm later for one of the augmented reality example programs and will be referring back to it later.

Augmented Reality Part 1: Getting Orientation Data

Download Code (382 Kb)

A few days ago I started developing a program for controlling my computerized telescope with my phone. Before I knew it I found myself in topics that are all a part of augmented reality. I thought it may be helpful to others if I collected my notes together to share. I'm trying something new with this post also. In addition to the blog post and the code I've also made this information available in video form at the links above. The video and this post cover the same information.

Before getting started with Augmented Reality you will want to make sure that you have a device that has the supported features. A lot of the concepts that I share in this series could be applied to other phones, but I will be concentrating on Windows Phone and taking advantage of the features and functionality that it has to provide. If you want to make use the information these posts on other devices you may have to find or make implementations for some high level functionality if your device and development environment does not already provide it.

To get started you will need a computer with the Windows Phone Developer Tools installed and a Windows Phone. Not all Windows Phones will work though. The phone will need to have GPS hardware and a compass/magnometer. All windows phones GPS hardware but not all phones have the magnometer. There are some devices that have a magnometer but don't have the driver needed to make it available to third party developers. At the time I am writing this I have two phones that have Mango installed. My HD7 has a compass but it does not have the necessary driver. My Samsung Focus does have the necessary driver. Before we go any further let's ensure that your device supports the magnometer. If it doesn't you'll need to find a device that does before you can proceed any further with development.

Does My Phone Support the Needed APIs

To test your device create a new Windows Phone project and add a reference to Microsoft.Devices.Sensors. You only need one line of code to check whether or not your device has a mangometer.

bool compassFound = Motion.IsMotionAvailable;

Set a break point after that line and run the program on your phone (at present it will always return "false" on the emulator). Hopefully it will return "true" for you.

Getting the Device's Orientation

Once you have a device that supports the compass let's get the device's orientation. At the very least your device has a magnometer and an accelerometer in it. It may also have a gyrometer in it too if it is a more recent device. You could get the readings from all of these sensor's individually but we'll rely on the Motion API to get the information from the sensors that it finds present and let it perform the math needed to get the data in an easy-to-consume form. The general pattern that you will use when interacting with the sensor APIs is that you'll create an object to represent a sensor, subscribe to an event to get notifications about the reading changing, and then call a Start() method to turn on the sensor and to start receiving data from it.

The compass (And thus the Motion API) requires calibration from time to time. In addition to an event that is called when there is sensor data there is also an event for notification that the device requires calibration. If this event is fired you'll need to tell the user to move his or her phone in a figure 8. Once the phone is calibrated your application will start to receive readings and you can remove the notification.

bool IsMotionAvailable {get; set; }
private Motion _motion;

IsMotionAvailable = Motion.IsSupported; 
if (IsMotionAvailable)
{
    _motion = new Motion();
    _motion.Calibrate += new EventHandler(motion_Calibrate);
    _motion.CurrentValueChanged += new EventHandler>(motion_CurrentValueChanged);
    _motion.Start();
}

The information that comes back from the Motion API tells us both the device's current orientation and movement/acceleration. For now we are only concerned with the device's orientation and will ignore the other data that is available. For now the fields of interest are the Pitch, Yaw, Roll, and Quanternion. The fist three figures are also used when describing the motion of an aircraft. If an aircraft is changing it's pitch that means that the front of the plan is being tilted up or down. If the airplanes wings remained level but it started moving to the left or right then its yaw is changing. And finally if the plane starts to tilt to the left or right then we would say the plane is rolling. These terms are applied to the phone in a similar way. If you have the device laying face up on a level table with the top of the device facing north than it's pitch, yaw, and roll are all set to zero. (I will call this the "zero position"). As you change the device's orientation these fields will change accordingly. The Motion API returns rotational measurements in radians. This makes sense given that the math functions available from the .Net framework also work with radians. But when displaying them on the screen it is easier to work with degrees. So for display only I have radian to degree converter.

public class RadToDegreeConverter : IValueConverter
{

    public object Convert(object value, Type targetType, 
                                      object parameter, 
                                      System.Globalization.CultureInfo culture)
    {
        double v;
        if (value is float)
            v = (float)value;
        else if (value is double)
            v = (double)value;
        else if (value is decimal)
            v = (double)(decimal)value;
        else
            return String.Empty;
        v = v * 180d / Math.PI;
        return v.ToString("000.0");

    }

    public object ConvertBack(object value, 
                                             Type targetType, 
                                             object parameter, 
                                             System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

The Quanternion figure that comes back also contains rotational information and is consumable by the XNA vector classes. I use the Yaw, Pitch, and Roll for display purposes only but use the Quanternion field in actual algorithms. Your augmented reality application will want to know the direction hat the camera on the phone is facing. Assuming that you are using the rear facing camera that means you will want to know the direction that the rear of the device is facing. To get this information start with creating a Vector3 that represents the direction that the rear of the device is facing when it is at the zero position. This vector will get rotated with the data that comes back from the Motion API and the resulting vector tells us which way that the device is facing.

Vector3 DeviceFaceVector = new Vector3(0,0,-10); 
Vector CurrentDirectionVector { get; set; } 

void motion_CurrentValueChanged(object sender, SensorReadingEventArgs e) 
{
 var attitude = e.SensorReading.Attitude;
 this.Dispatcher.BeginInvoke(() => 
  { 
     IsCalibrated = true; 
     Pitch = attitude.Pitch; 
     Yaw = attitude.Yaw; 
     Roll = attitude.Roll; 
     CurrentDirectionVector = Vector3.Transform(DeviceFaceVector, attitude.Quaternion); 
   }); 
} 

The CurrentDirectionVector will tell us what direction that the back of the device is facing. Let's convert it from a Cartesian (x,y,z) coordinate to a polar coordinate so that we can display the direction the phone is facing (measured as degrees from north) and the angle towards the sky or ground that the phone is tilted. Only a few function calls are needed to do this conversion

void CalculateAltaAzimuth()
{
    double x = CurrentDirectionVector.X;
    double y = CurrentDirectionVector.Y;
    double z = CurrentDirectionVector.Z;

    ViewingAzimuth = Math.Atan2(x, y);
    ViewingAltitude = Math.Atan2(z, Math.Sqrt(x*x + y*y));
}

Displaying the Values on the Screen

To display these values on the screen I will make use of data binding. But I also want to have the camera's point of view used as the program background. Eventually we will be overlaying images on this background. To have the image as a background create a framework element (grid, rectangle, canvas, or some other element) that is stretched over the portion of the screen in which you want the background to display. I'll have it stretched over the entire screen.

<Canvas Width="800" Height="480" x:Name="RealityOverlay">

In the code-behind I need to make a video brush that will be used to paint this surface. The video-brush will have the camera set as it's source.

_photoCamera = new PhotoCamera(CameraType.Primary);
VideoBrush vb = new VideoBrush();
vb.SetSource(_photoCamera);
PhotoBackground.Fill = vb;

This get's us as far as knowing how to tell the device's position. In the next post I'll show how to get the distance and direction to points of interest. Then I'll show how to project those points of interest onto the screen so that they appear to be part of the environment.

Video Explaining the Above

3 minute Code Walkthrough

I seem to have Stumbled Into Augmented Reality...

At this time of the year the best time to get a picture of the planet Jupiter from where I live is around 3:00am. I've got my telescope by the door so that at first opportunity I can quickly take it outside to perform setup and start taking pictures. But I didn't get a chance to do this Saturday on account of weather. It was cloudy outside and rain was in the forecast, so I knew I wouldn't have an opportunity. So I instead decided to turn my efforts towards something that would be of assistance to my telescope usage in the future. The telescope has a hand control device but in an age with so many smart phones I thought I could do better. So I decided to start on implementing my own hand control with my Windows Phone. 

My first goal was to simply make something that I could use to control the telescope within 24 hours. For the initial run there is a laptop connected to the RS232 port on my telescope. It will eventually be replaced with a .Net Micro Framework device, but for a prototype with 24-hour turn around trying to get custom hardware up and running was not possible. I made a client for my phone that would be my primary point of control for the telescope. I was successful at getting my goal achieved but at the end of it I came to realize that I had started to get into some augmented reality concepts without trying.

I had been taking notes and video logs of my progress (one video log entry is below) and I'll be breaking them down into a form that is more applicable to general applications. Some of the math involved can be scary, so to keep it understandable by more people I will by be making use of the math routines available in XNA and allow the reader to look further into XNA if he or she wants to know what it is doing behind the scenes. For example, you will see how to use an XNA matrix to do rotation calculations, but I won't be explaining what XNA is doing behind the scenes to perform such operation.

The first of several post that comes from my weekend efforts will come tomorrow evening after I proof a few things.

Video

What Does Windows 8 Mean for Windows Phone Developers?

It was only a few weeks ago that Windows 8 was unveiled at the Build conference. At first glance it looks a lot like Windows Phone with heavy use of the Metro visual language. The only part of the system that hasn't had the Metro touch is the desktop (unlike previous versions of Windows the Desktop is not something that is always running). The Start menu looks like the Windows Phone start screen only it scrolls horizontally instead of vertically. The only mention of Silverlight is that you could still use it in Desktop mode for backwards compatibility, but the Metro [default] instance of IE would run no plug-ins, including Silverlight. The programming model also is not based off of Silverlight or the Desktop .Net runtime. Its based on something new called WinRT (Windows Runtime). 

At first glance this is something that has concerned Silverlight and Windows Phone developers. At first glance some one might come to the conclusion that the skill in which he or she has invested has become second class in Windows 8. Is Silverlight really getting killed off? What's going to happen for the Silverlight based Windows Phone?

I don't know the future any more than the next person, but what I saw at Build isn't something that raised concern. I found it to be rather reassuring. Before I explain why let me grant the elephant in the room, the rumor that Silverlight is going to be dead. I don't believe this rumour. For years people have predicted that certain Microsoft Technologies were dead (DirectX, .Net, and many other technologies that we still use today). But I'll grant it anyway so that we can explore what seems to be a popular concern. 

Let's assume that next year Microsoft announces that it is going to sunset Silverlight and toss out the Windows Phone programming model in favour of the Windows 8 programming model. What does this mean for the skills that you have developed? Are they now useless? You've been developing skills in C#/VB, XAML, asynchronous programming, and some APIs that were specific to Silverlight and Windows Phone. Let's look at how each one of these will contribute to your Windows 8 development. 

Languages: C# and VB

C# and VB are still being used on Windows 8. If you've been using these languages you can continue to use them. Additionally if you know C++ or have algorithms that had been written in C++ you'll be able to port them over to Windows 8. Windows 8 also supports JavaScript as a programming language too. 

XAML

XAML is still used on Windows 8 for building your UI. Many of the elements you've become familiar with are present in addition to some new ones. No huge changes there. 

Asynchronous Programming

One of the challenges for developers that were new to Silverlight was that task that one may have been used to doing synchronously are only available as asynchronous calls. On Windows 8 you'll find that many of the tasks that were asynchronous in Silverlight and Windows Phone are still asynchronous. Additionally other APIs have been made asynchronous, including File IO. 

The Familiar and What This All Means

You'll come across APIs that look similar of not identical to what you've seen in Windows Phone and Silverlight. Windows 8 has the concept of an application getting tombstoned, specifying the permissions it needs, and so on. Windows 8 Metro applications will only be distributed through the Marketplace. Doesn't all of this sound familiar. If you are a Windows Phone developer it should. You've already got a head start on Windows 8 development. This is far from the doom and gloom picture that some stories would have some one believe. 

If you want to dive into Windows 8 programming the 64-bit development images are available for download. I suggest running them on real hardware. I tried them in the emulator VirtualBox and it's just not the same experience there. 

Windows Phone 7.5 (Mango) Availability

Mango is starting to roll out! It was several months ago that Microsoft made known that Mango would be available this fall, though when this fall had never been specified. The first day of fall was a few days ago and Microsoft is making good on their promise with Mango rolling out to some devices as early as today. While the Mango BETA had been out for some time there are some questions that are now answered with the final release.

Microsoft is going to start pushing the update to a small number of customers and gradually ramp up the availability. Most customers will have access to Mango by the end of October. Be sure to check the Where's My Update page to know when the Mango deployment begins for your network.

The availability and cost of Internet Connection Sharing will depend on your carrier. It will only be available on new Mango devices. The previously existing devices won't be getting the feature. Keyboards for additional languages may be available on some devices, but the underlying language for a device will still be the same as it was when it was purchased.

Information from the new OS release is still being made known, so I'll be making updates to this page as I encounter them.

Remember the Permission

I had a bit of a late night last night. I had just downloaded the Windows Live SDK and wanted to try it out. I took the Voice Memo application tha tI put on CodeProject.com and tried to add a feature to upload recordings to Skydrive. In the SDK there is a SignInButton controll and setting some parameters on this control along with responding to an event the control has is all that is needed to to make use of it. When I ran my program it failed with an error about the WebBrowserControl neededing to be on the visual tree before it is used. 

You cannot call WebBrowser methods until it is in the visual tree."

This was a little confusing to me at first. I am not using a web browser control anywhere in my program. So I played with the parameters on the control trying to see if I could change the response I was getting. After continual failure I posted a question on the Windows Live Connect support forums.  One of the Microsoft employees asked me if I could make a simple project demonstrating the problem. When I made my simple project the error would not occur. I then realized what was causing the problem. The Voice Memo application has had its permissions appropriately reduced. But those reduced permissions did not include what was needed by the login control. I ran the Windows Phone Marketplace Test kit and it told me the other permissions that I needed; ID_CAP_WEBBROWSERCOMPONENT  and ID_CAP_NETWORKING. After adding those permissions it worked like a charm!

Rather than sweep my mistake under a rug I thought I would share it in the hopes that posting this will save some one from having made the simple yet time consuming oversight that I had

 

Windows Phone Camp is Coming!

What's a Windows Phone Camp? 
A free, full day event chock-full of everything you need to know to develop a Windows Phone application. Whether you're a seasoned veteran or just getting started with .NET development this full-day event is for you. Interested in profit? We'll also lead discussions on how to monetize your applications and generate profits with your apps.

Don't miss the new Windows Phone 7.5 (codename "Mango") features as well - with detailed sessions in the afternoon around Fast Application Switching, Multitasking, Live Tiles, Push Notifications, and more. 

The day will be capped with an 
open lab hands-on session and prizes for apps completed. This is the perfect opportunity to begin work on your dream application, or finish that app you've already started, with Windows Phone experts there to guide you every step of the way. Bring your own laptop to join in the fun and show off your killer app! 

Agenda

9:00 AM

 

Description: Description: Description: C:\Users\Public\Documents\Webcamps Email - All\PHONE CAMPS\phonecamps_metro_er_allup_OFT_EVANG\spacer.gif

 

Welcome Campers

9:15 AM

 

Description: Description: Description: C:\Users\Public\Documents\Webcamps Email - All\PHONE CAMPS\phonecamps_metro_er_allup_OFT_EVANG\spacer.gif

 

How to make money with your Windows Phone app

10:00 AM

 

Description: Description: Description: C:\Users\Public\Documents\Webcamps Email - All\PHONE CAMPS\phonecamps_metro_er_allup_OFT_EVANG\spacer.gif

 

Frameworks for fun and profit > Silverlight and XNA

 

 

Description: Description: Description: C:\Users\Public\Documents\Webcamps Email - All\PHONE CAMPS\phonecamps_metro_er_allup_OFT_EVANG\spacer.gif

 

Canteen

1:00 PM

 

Description: Description: Description: C:\Users\Public\Documents\Webcamps Email - All\PHONE CAMPS\phonecamps_metro_er_allup_OFT_EVANG\spacer.gif

 

Hands-on lab

3:00 PM

 

Description: Description: Description: C:\Users\Public\Documents\Webcamps Email - All\PHONE CAMPS\phonecamps_metro_er_allup_OFT_EVANG\spacer.gif

 

Cool stuff your app can do

4:00 PM

 

Description: Description: Description: C:\Users\Public\Documents\Webcamps Email - All\PHONE CAMPS\phonecamps_metro_er_allup_OFT_EVANG\spacer.gif

 

To the Cloud

4:45 PM

 

Description: Description: Description: C:\Users\Public\Documents\Webcamps Email - All\PHONE CAMPS\phonecamps_metro_er_allup_OFT_EVANG\spacer.gif

 

Be What's Next > People's Choice Awards


Prerequisites 

Bring a notebook computer and identification. Also check out the APP HUB where you can get developer toolslearn about application featuresunderstand common task for Apps and register and load your APP.


Notes:
 
This event is brought to you by Microsoft and is free of charge. However, you are responsible for booking and paying for your own travel and accommodations.

Event Locations
9/20 - Charlotte, NC
9/22 - Alpharetta, GA
9/27 - Malvern, PA
9/29 - Reston, VA
10/18 - Chevy Chase, MD
10/19 - New York, NY
10/25 - Tampa, FL
10/27 - Burlington, VT
11/2 - Raleigh, NC
11/4 - Ft. Lauderdale, FL
11/8 - Orlando, FL
11/10 - New Paltz, NY
11/10 - Miami, FL
11/15 - Blacksburg, VA
11/17 - Washington, DC
11/29 - Pittsburgh, PA
11/29 - Atlanta, GA
12/1 - Long Island, NY