AdMob integration into Windows Phone 7


One awesome detail that iPhone and Android developers have always enjoyed was the ability to make some extra money by including ads in their free applications. In fact, I took advantage of it several times, most notably in That’s Not Funny for the Android and it’s port to the iPhone.  In the scheme of things, it’s not a lot of money, but it pays for my daughter’s crippling Hello Kitty addiction.

So recently, I thought it would be cool to port this app to the newly minted Windows Phone 7.  The coding was straight forward enough.  But the ability to monetize is simply not there on the WP7 – there are noises that eventually Bing Ads toolkit will come to the phone, but nothing has materialized yet.  At the same time, none of the big mobile players, such as AdMob (now Google) or Quattro Wireless (now Apple) have released anything for the platform. 

Seeing how I used AdMob on both Android and the iPhone platforms, I set out to build a custom control that the WP7 developers can simply drop into their forms and it would just magically make them money.

The bottom line is this: I posted the results of this initial effort on CodePlex.  Plus, I created a video that walks you through the process of embedding ads.

The development revealed a couple of things about the Windows Phone 7 SDK: it’s a typical 1.0 release – the APIs are somewhat incomplete.  For instance:

  • Browser User Agent.  AdMob requires this information, but WP7 provides no way to get it.  I had to implement a nasty hack, where I would spin up a WebBrowser control, load a bit of JavaScript into the web page and have it spit out the User Agent back to me via Browser to OS interop. 
  • IP Address.  AdMob requires an external IP Address.  WP7 has no way of finding it.  In this case, I actually had to create a web page,  that detects the IP address server side and responds with it via JSON.

But all in all, a very pleasant development experience.  My familiarity with Silverlight definitely helped.  I would even say that a passing knowledge of this technology is absolutely required.  If you do not have Visual Studio 2010 installed on your box, the setup will provide you with a WinPhone7 only version of VS2010.  And if you do have it, then it’ll integrate the tools into your existing install.  I wish this was an option, as the WinPhone7 only version of  VS2010 is markedly snappier. 

I feel like version 2 of Windows Phone 7 SDK is going to patch all the holes left by v1 and will turn out to be be fantastic.

For reference: That’s Not Funny.

Android

Windows Phone 7

 
NotFunnyAndroid AdMobOnWinPhone7  

author: Angry Hacker | posted @ Sunday, August 01, 2010 10:48 PM | Feedback (2)

How to get rid of flicker on Windows Forms applications


Windows Forms apps have a well known issue that when you have a bunch of controls on your form (not to mention any 3rd party controls), the app flickers, there is UI tearing – it's just not pretty.  The problem most seems to impact the startup of the app when everything is being loaded.

Simply setting the form and any controls to be Double Buffered doesn’t do the trick because the .DoubleBuffered property works at a control level, not the form level. 

There is a fix for this that automatically enables double-buffering at the form level and on down.  This works by setting the WS_EX_COMPOSITED flag in the Form.CreateParams.ExStyle property.  Just drop the following code into form:

protected override CreateParams CreateParams
{
    get
    {
        // Activate double buffering at the form level.  All child controls will be double buffered as well.
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;   // WS_EX_COMPOSITED
        return cp;
    }
} 


This fix works relatively well, but WS_EX_COMPOSITED flag causes a couple of side effects:

  • The Maximize, Minimize and Close buttons don’t animate on Windows XP.
  • Resizing a control-heavy form feels very laggy because everything is being double-buffered.

The trick to fix both issues, it turns out, is the same, though very hacky.  The idea is to turn off the WS_EX_COMPOSITED flag right after the form is loaded and thus turning the form-level double-buffering off. So replace the above code with the following:

int originalExStyle = -1;
bool enableFormLevelDoubleBuffering = true;
 
protected override CreateParams CreateParams
{
    get
    {
        if (originalExStyle == -1)
            originalExStyle = base.CreateParams.ExStyle;
 
        CreateParams cp = base.CreateParams;
        if (enableFormLevelDoubleBuffering)
            cp.ExStyle |= 0x02000000;   // WS_EX_COMPOSITED
        else
            cp.ExStyle = originalExStyle;
 
        return cp;
    }
} 

 

So the pieces are in place: when enableFormLevelDoubleBuffering is set to false, we’ll have to get the System.Windows.Forms.Form object to call the CreateParams method and, in doing so, reset the ExStyle flag.  But how can we get the app to call CreateParams

For reasons I don’t know, simply calling the following does the trick:

this.MaximizeBox = true;


Yes, did I mention, it was hacky?  So let’s create a method that does all the work:

private void TurnOffFormLevelDoubleBuffering()
{
    enableFormLevelDoubleBuffering = false;
    this.MaximizeBox = true;
}


And we should call this method after the form has loaded in the Shown event:

private void frmMain_Shown(object sender, EventArgs e)
{
    TurnOffFormLevelDoubleBuffering();
}

And that’s how we roll.

author: Angry Hacker | posted @ Wednesday, July 21, 2010 4:37 PM | Feedback (0)

Today I learned…


…that in Legoland, it’s probably a good idea to go on the water rides first, then go and do the face painting thing.

author: Angry Hacker | posted @ Tuesday, July 13, 2010 11:14 PM | Feedback (0)

How to find Overlap or Intersection


I forget this every time. 

C#

 public bool NumbersOverlap(int Set1Min, int Set1Max, 
                           int Set2Min, int Set2Max)
{
    return (Set2Min >= Set1Min && Set2Min <= Set1Max) || 
           (Set2Max <= Set1Max && Set2Max >= Set1Min) || 
           (Set2Min <= Set1Min && Set2Max >= Set1Max);
}

 

VB 6

Private Function NumbersOverlap(Set1Min As Integer, Set1Max As Integer, _ 
                                Set2Min As Integer, Set2Max As Integer) As Boolean
 
    NumbersOverlap = (Set2Min >= Set1Min And Set2Min <= Set1Max) _ 
                  Or (Set2Max <= Set1Max And Set2Max >= Set1Min) _ 
                  Or (Set2Min <= Set1Min And Set2Max >= Set1Max)
 
End Function

 

Unit Tests

Console.WriteLine(NumbersOverlap(1, 10, 11, 15));  // false
Console.WriteLine(NumbersOverlap(8, 19, 19, 25));  // true
Console.WriteLine(NumbersOverlap(8, 19, 19, 25));  // true
Console.WriteLine(NumbersOverlap(8, 20, 19, 25));  // true
Console.WriteLine(NumbersOverlap(8, 20, 1, 25));   // true
Console.WriteLine(NumbersOverlap(8, 30, 1, 25));   // true
Console.WriteLine(NumbersOverlap(8, 25, 1, 25));   // true
Console.WriteLine(NumbersOverlap(25, 50, 1, 25));  // true 
 

 

author: Angry Hacker | posted @ Wednesday, May 26, 2010 7:50 PM | Feedback (2)

The Downfall of Peer Guardian for the Mac.


Peer Guardian for the Mac has got to be the most opaque app ever.  At least two apps would not work:

  • Steam
  • Penguin Club

It just silently block them.  No preferences, no UI to selectively pick apps or ports.  It seems to block all non-HTTP socket traffic.

So I set out to uninstall.  Dragging the app into the Trash Can didn’t fix the situation.  Finally I had to uninstall it with the help of AppDelete.  Then, magically, Steam and Penguin Club just worked.

author: Angry Hacker | posted @ Thursday, May 13, 2010 5:08 PM | Feedback (2)

How to find all printers in your Active Directory


If you ever want to do a prank on a massive scale, you need to find all the printers in your Active Directory, not only ones that are connected to your computer.  Oddly enough, the method to find them is not trivial.  The code is in c# and it works in Visual Studio 2008.

   1:          private void FindAllPrinters()
   2:          {
   3:              string[] wantedProps = { "name", "servername", "printername", 
   4:                                         "drivername", "shortservername", "location" };
   5:   
   6:              var ds = new DirectorySearcher { Filter = "(objectClass=printqueue)" };
   7:              foreach (SearchResult sr in ds.FindAll())
   8:              {
   9:                  Debug.WriteLine(sr.Path);
  10:                  ResultPropertyCollection rpc = sr.Properties;
  11:   
  12:                  // use rpc.PropertyNames instead of wantedProps if you want to
  13:                  // know more about the printers than is provided below
  14:                  foreach (string property in wantedProps)
  15:                  {
  16:                      foreach (object value in rpc[property])
  17:                          Debug.WriteLine(string.Format("\t{0}: {1}", property, value));
  18:                  }
  19:              }
  20:          }


Note that you need to add a reference to System.DirectoryServices.  Also keep in mind that this code fetches all the printers in your domain.  If you have many domains in your organization, you’ll have to get the list and instantiate DirectorySearcher class separately for each one.

Bookmark and Share kick it on DotNetKicks.com

author: Angry Hacker | posted @ Tuesday, April 06, 2010 8:20 PM | Feedback (0)

14 Predictions for 2020


2010 is here.  It seems like only yesterday that we partied like it was 1999.  Here are my predictions for what the world will look like in ten years.

  1. There will be a massively noticeable jump in the battery technology.  If today, we are struggling to get the hybrid plug-ins on the road, in 10 years, electric vehicles will rule.  Why?  Because right now there are way too many people are working on improving the batteries – someone is bound to make a breakthrough.  Most new vehicles sold will be electric.
  2. The vehicles themselves will be similar to what we have today.  With one significant difference – they will have internet connectivity, which changes everything.  All of a sudden the entertainment options quadruple.  The kids in the back can watch whatever.  The vehicle will do a lot of self-diagnostics and possible let you know ahead of time about needed maintenance, etc…
  3. Solar for residential home will be a no brainer.  The improvement in the efficiency of solar panel will go through the roof and the price will drastically come down. Thus it will make no sense to keep on paying the electric company when you can produce it yourself and potentially sell it back to the utilities (although the last part will most likely not last).  The reason for Solar’s success lies in the basic research that has been going on for a decade now.  There will most likely be laws mandating solar roofs for new buildings (commercial at first, then residential).
  4. Facebook will be history.  People will simply get bored with it. It will be replaced by another fad. 
  5. The number of significant mobile phone operating systems will shrink significantly.  Nokia’s Symbian and Maemo will be gone.  Same fate awaits Palm’s WebOS.  The battle will be fought between the Apple’s iPhone, Google’s Android, Rim’s BlackBerry and Microsoft’s next mobile OS.  I don’t foresee any new entrants, as all the major players now have an OS, which is really difficult to build without a ton of people.
  6. We will still have general purpose computers, even though by 2020 the mobile devices will be able to do pretty much anything the desktop counterparts can.  But they’ll be smaller and more stylish.  Windows will still be dominant.  Google’s Chrome OS will be nowhere to be seen.
  7. We will not have landed a human on Mars because it is devilishly difficult to bring that person back to earth.  But the Red planet will become increasingly polluted with all kind of hardware from Earth (e.g. rovers, etc…).
  8. One of the Voyager spacecraft encounters a signal or an anomaly that could possibly be construed as alien in nature.
  9. Here is an easy one – most of our data is in the cloud.  Even desktop applications, such as Microsoft Office, operate on data residing in the cloud.  In other words, when you go File/New – a file gets created in the cloud.
  10. The TV will be different.  First of all, the coolest toy that everyone will want in 2020 is a foldable TV.  Other TVs will simply look like glass when turned off.  But beyond that the TV will be connected, there will be an App Store for the TV that does all kinds of things.
  11. Geek stats:  Typical  bandwidth will be about 500 megabits per second. Hard drives will mostly be solid state, typical drive – 1 petabyte.   The CPUs for mobile devices will come with multiple cores.  Typical servers will easily contain 64 cores. 
  12. Combine predictions about solar and batteries.  For commercial deliveries it’s absolutely huge.  All of a sudden your largest expense (gasoline) is history because your vehicles run on batteries using electricity produced by the solar panels installed on the roof of the warehouse.  This enables cheaper deliveries on a large scale.  Thus the refrigerator will do the shopping for us.  It will quickly scan the contents and communicate to your grocery store what you are running out of.  Items you are short on will be brought to you as a part of your weekly deliveries.
  13. We’ve all seen how citizen journalism changed things in the Iran protests.  All of a sudden 100 people with cheap camcorders were telling the world what was really happening in the streets of Tehran.  Fast forward 10 years and now you got thousands of people live video-blogging from their iPhone 8G to services such as Ustream.  This makes it very difficult of oppressive regimes to go on, though they surely will.
  14. North Korea no longer exists – it will have merged with the South – it will happen very quickly and unexpectedly.  Cuba’s 50 year experiment with communism is over after the death of Fidel and his brother.   Arabs and Jews are still at it (albeit after at least one major war).  USA continues to have all kinds of problems stemming from living beyond means, unworkable and corruptible legislature, exploding medical costs for the baby boomers, etc…  China experiences another Tiananmen square like event, although the results are far more explosive.  

author: Angry Hacker | posted @ Sunday, January 03, 2010 12:06 AM | Feedback (0)

Google Voice for BlackBerry. Why do you suck so?


I ended up installing Google Voice on my BlackBerry.  Why?  Cause my employer took away SMS/MMS messaging from the calling plan.  There goes my social life.  Anyway, I was expecting the standard Google fare: highly refined user experience, the necessary minimum of features to get going, combined with the fast access time.  Well…one of out three ain’t bad.  It’s speedy.  Oh, hold on, one out of three actually sucks.  At least it’s fast.

Here are the sins of the application – hope they fix them soon:

  • There is no light indicator to see that an SMS arrived
  • There is no sound or vibrate to indicate a new text message and no way to configure it
  • Auto text does not work when composing SMS.  In other words, the first letter of the sentence will not automatically go upper case, even though every other Google app on the BlackBerry happily does it.
  • There is no push capability – the application must poll Google servers to check for new activity
  • MMS is non-existent
  • When the SMS message does arrive, the Google Voice icon changes very imperceptibly.  It needs much better contrast, similar to the Gmail app.
  • When you are looking at your SMS conversations – Google Voice displays just the phone number, not the name.  This is massively odd, considering that I started the conversation from the Address Book.

author: Angry Hacker | posted @ Thursday, November 19, 2009 6:26 PM | Feedback (0)

Expert .NET Micro Framework


I haven’t had this much fun programming in a long, long time – since the exhilaration of  the first project after college.

The further in time we go, the more removed the programmers are from the hardware. Consider the number of abstractions, that a typical C# corporate developer works through.

  1. CPU/Registers
  2. Windows Kernel
  3. Windows Drivers
  4. Windows API
  5. .NET Wrapper for Windows API
  6. Probably some other home grown or 3rd party framework
  7. Finally code.

That’s a lot of layers. If you think of a guy who writes firmware in assembly as a heart surgeon, then the C# coders are psychologists, trying to cajole and persuade Windows into doing what we need it to do.

That’s why, after perusing chapter 5 of Jens’ book and writing the following:

   1:  OutputPort op = new OutputPort(Cpu.Pin.GPIO_Pin0, true);
 

and an LED light connected to the first pin of the CPU board lit up…well, I felt like a heart surgeon again.

The thing about this book…it’s so massively timely. .NET Micro Framework is not widely used, certainly not on the scale of the full blown .NET framework. There isn’t a whole lot of resources you can tap. Aside from a NNTP newsgroup and a forum or two, that’s it. There isn’t an army of programmers writing blog entries about it daily.

On top of all that, the book is actually pretty great and reads very easily. It goes from getting started to basic to advanced, giving you runnable code all along the way. It covers pretty everything that is possible today with the .NET Micro Framework.

It has an awesome mega chapter on networking, where he goes into having the device be a client or a web server, device discovery, SSL and all other kinds of goodies. In fact, I am trying to implement most of it and the book came in just in time.

Totally recommend it.  Link.

author: Angry Hacker | posted @ Saturday, October 03, 2009 3:43 PM | Feedback (0)

Bulk Scanning Photos. Take 2.


Recently I’ve been on a tear to scan my old paper photos before they turn into dust.  My first attempt has been reasonably successful.  I hired a lady to scan photos for me and at the end of the day, it came out to about $0.36 per photo.  I paid the lady $10 per hour. 

The process was as follows:

  1. She would scan the 3 photos at a time into Photoshop in the configuration below.  The important piece here is to leave space both between the photos and the edges of the scanner and between the photos themselves.  Why?  Because the next step would not work without it.

  2. Then she would apply Photoshop’s Crop and Straighten Photos feature, which would split the photos into 3 separate images. 
  3. The lady would rotate each individual photo properly.
  4. She would then save these 3 images separately.

After she left, I was left thinking that several things could be improved upon:

  1. For instance, maybe Photoshop could somehow be automated to automatically apply the Crop and Straighten Photos feature and perhaps save the file. 
  2. A better scanner would mean faster processing and cheaper rate per photo. 
  3. At the end she processed a total of 110 photos.  This is not bad, but I have 1500 photos at least. 

To automate Photoshop I headed to the Adobe forums.  I posted my problem there and 15 minutes later or so I had my answer.  It turns out Photoshop CS4 not only supports scripting, it has a full blown Integrated Development Environment with an editor, debugger, etc… that ships with it.   Some chap wrote me a script that would take a file, apply to it the Crop and Straighten Photos feature and would save the 3 resulting photos as separate files.  This worked like a charm.

Once the photos were separated, I needed to find a way to bulk rotate them into the right position.  I set the view in the folder to Thumbnail, selected all the photos that needed to rotated clockwise, right-clicked and selected ‘Rotate Clockwise’.  Ditto for counter clockwise. 

Armed with the new process, I had a friend loan me a faster scanner (just your average HP all-in-one device).  I called the lady back, and this time, all she had to do was just scan 3 photos at a time and save the resulting file.

After she left, I ran the script on the folder where she saved all the images, then rotated them properly – this took a total of about 3 minutes.

I calculated the monetary damage and it was really really good - $0.19 per photo - cheaper than any commercial service out there. 

author: Angry Hacker | posted @ Saturday, October 03, 2009 1:38 AM | Feedback (4)