Redth

code, ramblings, rants

iTunes Media HotKey Disabler

| Comments

This simple application will allow you to disable or enable iTunes from listening to when you press the media keys (Play / Pause) on your keyboard. This is great for applications such as gTunes which make use of the hot keys but cannot themselves prevent iTunes from also responding to those keyboard keys.

iOS7: Fun Times With the New Full Screen Layout!

| Comments

In a mad rush, I had to prepare an app for iOS7 after its release. Yes, I know, shame on me for not listening to everyone telling me to start getting my apps ready early. How bad could it be anyway?

For the most part, not too bad. The worst part for me came in the shape of dealing with this new idea that every UIViewController now expands the bounds of the entire screen, including where the status bar and navigation bars could be. In any case, I had to do a bit of learning really quickly. If you don’t already know what I’m talking about, here’s a picture of one unpleasant conversion experience:

iOS7 Recipe: Background Fetching

| Comments

This is my entry into the Xamarin Recipe Cook-Off. Recipes, in Xamarin terms, are very simple demonstrations of how a single feature or piece of functionality is implemented. I thought background fetching would be useful to many developers, and it’s pretty easy to implement, especially after reading this recipe.

I’ve also included the recipe in this blog post:

Background Fetching Data

This recipe shows how to register your application to perform background fetching on intervals.

1. Recipe

In your application’s Info.plist file, add the value fetch to the UIBackgroundModes (Required background modes) property.

Next, in your AppDelegate class, in the FinishedLaunching override method, add the following code to register your application for background fetching:

1
UIApplication.SharedApplication.SetMinimumBackgroundFetchInterval (UIApplication.BackgroundFetchIntervalMinimum);

Finally, in your AppDelegate class, override the PerformFetch method.

This method will be executed by the operating system when it sees best fit (eg: when the device is awake and connected already). You do not have complete control over how often or when fetching happens.

You should execute your own code to fetch new data in this method. It’s important to call the Action<UIBackgroundFetchResult> completionHandler parameter which is passed into this method with the appropriate result when you are done.

2. Sample PerformFetch

In this sample, a weather service is called by background fetching so that when the user opens the app, recent weather is available. The weather is cached locally after it’s fetched in the background, and the UI is also updated if there is new weather info.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public override async void PerformFetch (UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
{
  Console.WriteLine ("PerformFetch called...");

  //Return no new data by default
  var result = UIBackgroundFetchResult.NoData;

  try
  {
    //Get latest weather
    var w = await GetWeatherAsync("Windsor, Canada");

    if (w != null)
    {
      //Cache the weather locally
      CacheWeatherAsync(w);

      //Update the UI
      weatherViewController.UpdateWeather(w);

      //Indicate we have new data
      result = UIBackgroundFetchResult.NewData;
    }
  }
  catch
  {
    //Indicate a failed fetch if there was an exception
    result = UIBackgroundFetchResult.Failed;
  }
  finally
  {
    //We really should call the completion handler with our result
    completionHandler (result);
  }
}

3. Additional Information

  • Your PerformFetch has about 30 seconds to run before it’s killed
  • The operating system is more likely to grant more time (and more often) to your application for background fetching if you are efficient, which means executing quickly, and always calling completionHandler with an accurate result
  • You can tell the operating system the minimum time to sleep between waking up your application and calling its PerformFetch method if you know your app only updates at a certain interval, to avoid extra calls to PerformFetch and wasting battery life. You would specify the minimum time in seconds in the UIApplication.SharedApplication.SetMinimumBackgroundFetchInterval (double minimumBackgroundFetchInterval) method
  • You can actually make calls to update your UI from the PerformFetch method so that the next time the user launches the app, everything is up to date

How to Auto Wire Up Android Activity Views in Xamarin.Android

| Comments

One thing that’s occasionally bothered me was how verbose it is in Android to wire up views from a layout, in an activity. I finally was fed up enough to write a simple little helper that does this based on reflection. Consider the following verbosity monstrosity:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[Activity (Label = "RandomDataActivity")]            
public class RandomDataActivity : Activity
{
  Button button1; Button button2; Button button3; Button button4;

  TextView textView1; TextView textView2; TextView textView3;
  TextView textView4; TextView textView5; TextView textView6;
  TextView textView7; TextView textView8; TextView textView9;

  ImageView imageView1; ImageView imageView2; ImageView imageView3;
  ImageView imageView4; ImageView imageView5; ImageView imageView6;

  protected override void OnCreate (Bundle bundle)
  {
      base.OnCreate (bundle);

      SetContentView (Resource.Layout.RandomDataLayout);

      button1 = FindViewById<Button>(Resource.Id.button1);
      button2 = FindViewById<Button>(Resource.Id.button2);
      button3 = FindViewById<Button>(Resource.Id.button3);
      button4 = FindViewById<Button>(Resource.Id.button4);

      textView1 = FindViewById<TextView>(Resource.Id.textView1);
      textView2 = FindViewById<TextView>(Resource.Id.textView2);
      textView3 = FindViewById<TextView>(Resource.Id.textView3);
      textView4 = FindViewById<TextView>(Resource.Id.textView4);
      textView5 = FindViewById<TextView>(Resource.Id.textView5);
      textView6 = FindViewById<TextView>(Resource.Id.textView6);
      textView7 = FindViewById<TextView>(Resource.Id.textView7);
      textView8 = FindViewById<TextView>(Resource.Id.textView8);
      textView9 = FindViewById<TextView>(Resource.Id.textView9);

      imageView1 = FindViewById<ImageView>(Resource.Id.imageView1);
      imageView2 = FindViewById<ImageView>(Resource.Id.imageView2);
      imageView3 = FindViewById<ImageView>(Resource.Id.imageView3);
      imageView4 = FindViewById<ImageView>(Resource.Id.imageView4);
      imageView5 = FindViewById<ImageView>(Resource.Id.imageView5);
      imageView6 = FindViewById<ImageView>(Resource.Id.imageView6);
  }
}

Now that’s a lot of code to do something really simple. Plumbing code that’s so simple I’d rather not, and shouldn’t have to waste my time on it! How about this instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[Activity (Label = "RandomDataActivity")]            
public class RandomDataActivity : Activity
{
  Button button1; Button button2; Button button3; Button button4;

  TextView textView1; TextView textView2; TextView textView3;
  TextView textView4; TextView textView5; TextView textView6;
  TextView textView7; TextView textView8; TextView textView9;

  ImageView imageView1; ImageView imageView2; ImageView imageView3;
  ImageView imageView4; ImageView imageView5; ImageView imageView6;

  protected override void OnCreate (Bundle bundle)
  {
      base.OnCreate (bundle);

      SetContentView (Resource.Layout.RandomDataLayout);

      this.WireUpViews ();
  }
}

Here’s the extension method I created to do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public static class ActivityExtensions
{
  public static void WireUpViews(this Activity activity)
  {
      //Get all the View fields from the activity
      var members = from m in activity.GetType ().GetFields (BindingFlags.NonPublic | BindingFlags.Instance)
                    where m.FieldType.IsSubclassOf (typeof(View))
                    select m;

      if (!members.Any ())
          return;

      members.ToList ().ForEach (m => {
          try
          {
              //Find the android identifier with the same name
              var id = activity.Resources.GetIdentifier(m.Name, "id", activity.PackageName);
              //Set the activity field's value to the view with that identifier
              m.SetValue (activity, activity.FindViewById (id));
          }
          catch (Exception ex)
          {
              throw new MissingFieldException ("Failed to wire up the field "
                                               + m.Name + " to a View in your layout with a corresponding identifier", ex);
          }
      });
  }
}

Ok, ok, I know it’s not perfect, but it’s a bit of a time saver, and keeps my code looking a bit neater. In a perfect world I should just be able to use an android identifier as if it were already a declared as a code field. There’s also room for improvement in my extension method, for example, what if you declare a field that’s a View but not in the layout, but you did this intentionally? Well, I don’t want to do ALL your work for you ;)

Just wanted to share this little bit with you. Hopefully it sparks some ideas for something greater in your day! Happy Coding!

Xamarin Studio Launcher

| Comments

Xamarin Studio Launcher

I’ve recently converted to a Mac. As a long time Windows user, one thing I was very accustomed to was keeping multiple visual studio, or more recently, Xamarin Studio instances open at any given time. Switching to a Mac I found this isn’t so easy, so I decided to make a nice little Launcher application to open new Xamarin Studio instances at will!

So, without further ado, please download the Xamarin Studio Launcher!

Download Xamarin Studio Launcher

Xamarin Evolve 2013

| Comments

Xamarin Evolve 2013 was an Awesome conference! I got to see a lot of familiar faces, and meet plenty of new ones! It’s such a great experience to see and talk with such great people who I’d only otherwise know online!

I also had the great privilege to do some speaking at Evolve! I’ve posted my slides below and will update the post with links to the videos when they are available!

Thanks to Xamarin and everyone who made this such a great event!

A Month With Android

| Comments

Just before the new year, I wrote a post about switching back to Android (to a Nexus 4), and I was excited at the prospect. I explained that I’d been a long time iOS user (quite happily so), except for a brief stint on Android 2.3 (Gingerbread) which ended not so well.

Well, it’s been about a month now since I’ve switched back to Android, and I’m not looking back anytime soon! I’m going to do a quick recap about the things I love, and the things I miss:

Why I’m Looking Forward to Android

| Comments

Mou icon

The Back Story

Way back in Froyo days, I took the leap from my iPhone 3G to Android as my daily device with a Samsung Galaxy S. I was co-authoring a book Professional Android Development with Mono and C#/.NET

Android was new, it was exciting, it was different. It was also slower, higher maintenance, and had me flashing roms weekly. Not necessarily a problem for a supergeek like me, but still tiresome and prone to moments of Oh sorry, that’s a bug in my phone’s rom or my battery’s dead because of all the services i have running.

Needless to say, it wasn’t very long before I was back on the iPhone train. I was content with the iPhone 4, and then the iPhone 4S, and now the iPhone 5. They’re all great devices, they just work… as long as you want to use them how Apple intends.

The primary reasn I’m switching back to Android, is my Galaxy S just doesn’t cut it for development anymore. My wonderful wife will inherit my iPhone 5 (like she does all my devices), and I’ll have a Nexus 4 to test on soon.