Android

Dynamically Preventing Rotation on an Android Fragment

Recently at work, I’ve been working on making an Android version of the company’s iOS application. The application itself runs entirely in portrait mode, except for the image of the benefits card that is included in the application. In iOS, that was easy enough to accomplish. In Android, the most common way to limit orientation changes is on a per-activity basis in the manifest, like this:

<activity
   android:screenOrientation="portrait"
   android:configChanges="orientation|keyboardHidden">
</activity>

Unfortunately, we can’t do that. Our application makes use of the “slide out” menu that was made popular in the Facebook application, but that you can now find as a very common pattern in many applications. The way that you accomplish this pattern in Android is by using the DrawerLayout and by using Fragments. Fragments are much like User Controls in Asp.Net WebForms or Partial Views in Asp.Net MVC or Rails. You have a container and you can load different layouts into that container, while maintaining the rest of the page’s layout as-is. The code that drives the fragment layouts has its own lifecycle (making it much more like WebForms User Controls than a Partial View).

The problem that this causes us is that we have one activity that sometimes we want to be able to rotate and other times, we want to keep it locked into place depending on which fragment is loaded at any given time. I searched and searched and could not find a solution that worked for us 100% of the time and was simple enough to implement. Eventually, I came up with my own solution to this problem.

The code for this entire project can be found on GitHub. For demonstration purposes, the project is based on a Sliding Menu project created by Ravi Tamada. Most of the code is his, with just the modifications I’m going to discuss here.

The menu looks like this:
The Slide Out Menu

When you click an item, it loads a fragment into the main window section. Here are the landscape modes of the Home Screen, followed by the Communities Screen:
The Home Screen in Landscape

The Communities Screen in Landscape

What we want, however, is for the Communities screen to remain in portrait mode no matter how we turn the phone, but the other pages can rotate. To accomplish this, I modified the method that is called whenever someone selects one of the menu items out of the menu.

/**
	 * Diplaying fragment view for selected nav drawer list item
	 * */
	private void displayView(int position) {
		// update the main content by replacing fragments
		Fragment fragment = null;
		
		// We allow the Sensor to be used in all instances by default
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
		switch (position) {
		case 0:
			fragment = new HomeFragment();
			break;
		case 1:
			fragment = new FindPeopleFragment();
			break;
		case 2:
			fragment = new PhotosFragment();
			break;
		case 3:
			// In just this one instance, we turn the sensor off
			// Until a different menu item is selected, which re-enables it
			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
			fragment = new CommunityFragment();
			break;
		case 4:
			fragment = new PagesFragment();
			break;
		case 5:
			fragment = new WhatsHotFragment();
			break;

		default:
			break;
		}

		if (fragment != null) {
			FragmentManager fragmentManager = getFragmentManager();
			fragmentManager.beginTransaction()
					.replace(R.id.frame_container, fragment).commit();

			// update selected item and title, then close the drawer
			mDrawerList.setItemChecked(position, true);
			mDrawerList.setSelection(position);
			setTitle(navMenuTitles[position]);
			mDrawerLayout.closeDrawer(mDrawerList);
		} else {
			// error in creating fragment
			Log.e("MainActivity", "Error in creating fragment");
		}
	}

Notice that the first thing we do is allow the orientation sensor to work.

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

However, as we are setting to load the fragment for communities (if that is selected), we turn the orientation sensor off.

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);

That causes the device to not rotate and to return to the original orientation, no matter how you are holding the phone when it loads.

After this change, we see the following. The home screen looks right in portrait mode:
After - The Home Screen in Portrait

Rotating it, does make it move to landscape:
After - The Home Screen in Landscape

But, when I choose Communities and we are in landscape, the app will only display portrait mode:
After - The Communities Screen in Landscape

That’s all there is to it. If you have a better solution, please feel free to leave it in the comments. If you want to check out the code and play around with it, here is the link to the repo again.

Podcasts

New Podcast – Preparing to Give a Presentation

Lavalier MicrophoneI just published my most recent podcast yesterday and it is my most favorite solo (non-interview) podcast yet.

In this podcast, I talk about the best ways to prepare to give a talk. In my case, my example was for my upcoming Stir Trek talk, but I also make sure to talk about ways that you can apply this preparation to business presentations, best man toasts, or oral book reports. I made sure to include a lot of practical resources and steps you can take to ensure that you can give a great presentation.

Preparation truly is key and I’ve seen some smart people give terrible presentations because they didn’t prepare properly, so I’m very paranoid about the subject. However, one of my old bosses really drilled the importance of preparation into me, so I take it very seriously and I’m pretty passionate about it. It doesn’t matter if you are leading a meeting, giving a keynote, or writing a blog. People can tell if you’ve put the background time in or not.

I’d definitely appreciate a listen.

You can also subscribe to the podcast at any of these places:
iTunes Link RSS Feed

Thanks to all the people who listen, and a special thanks to those who have rated me. I really appreciate it.

The episodes have been archived. Click Here to see the archive page.

Podcasts

My Interview with Paul Bergeron

Paul BergeronI recently came across a great tool called TextQL. I thought it was so useful that I reached out to its creator, Paul Bergeron, that day. He was gracious enough to come onto the podcast and we had a great conversation. You can hear that conversation here.

Inspired by Paul’s own demo of TextQL that you can see at its Github repo, I decided to install it and try it out myself. I created my own simple CSV of dumbed down blog data and showed it off a little bit here:

TextQL Demo

(I do realize that join was pointless, I just wanted to show that it could do joins).

Another interesting (for varying definitions of interesting) note about this podcast is that I’ve made a change to the quality. I had been encoding the MP3s at 128kbps (because that’s what Audacity/LAME just did) and I was unhappy with how the vocals were turning out. They were a little “fuzzy”. I upped that to 160kbps and I think that the episode sounds a lot better.

If you have any comments about the episode or if you notice a quality difference, let me know.

You can also subscribe to the podcast at any of these places:
iTunes Link RSS Feed

Thanks to all the people who listen, and a special thanks to those who have rated me. I really appreciate it.

The episodes have been archived. Click Here to see the archive page.

AOP

Executing on the Background Thread with PostSharp

Background ThreadIn my last two PostSharp blog posts, I looked at creating some custom attributes that you could use to get custom behavior out of PostSharp. Of course, I was implementing simple functionality and in fact, PostSharp had most of if not all of those features already built in.

Today, I want to dig in a little more to some of the built in power of PostSharp. To do this, I had to sign up for the 45 day evaluation license for PostSharp Ultimate. I had been putting that off to do as much “free stuff” as I could, but I really wanted to see what PostSharp could do, so I fired up the evaluation.

I created a very simple UI that looks like this:
Simple "Long Running Process" UI

When you click the buttons, I call a class that just sleeps for three seconds and returns to simulate some slow process.

public void LongRunningOperationBlocking()
{
    Thread.Sleep(3000);
    return;
}

I created code that will run this blocking process and then when the UI thread is free again, it displays a message box with whatever was in the textbox. Here is the UI in action. Note that I cannot select the text after clicking the button because the UI is locked up for 3 seconds.
Blocking Fail

However, with PostSharp, we can easily execute these long running methods on a background thread. As long as the method returns void, the context menu will reveal the “Execute method in the background” option like this:
The PostSharp Context Menu Showing Background Thread Option

After selecting that option, you get this wizard:
The PostSharp Add a Feature Wizard

The sum total of the “visible” changes is that our other method got a new attribute, “[Background]”

[Background]
public void LongRunningOperationBackground()
{
    Thread.Sleep(3000);
    return;
}

But, the win is that now when I click the button, the UI returns immediately and we see the message box right away, even while the long running process is going.
Blocking Fail

That is a gigantic amount of threading code that we don’t have to write. It is only probably 4-6 lines per method, but you have to write the same thing over and over again for every method you want to have do work on a background thread. Of course, any time you can just cut out “boilerplate code”, you make your code not only easier to write, but easier to read and discern intent. And that is “A Good Thing™”!

As always, you can download the code for this series from my Github repository for it. The path to this post’s code is here.

AOP

Parameter Checking with PostSharp

Guard TowerLast time, I started off my PostSharp series by adding some logging coming in and out of a method. It was very easy to do and it was nice to have a single point of code that wasn’t copy-paste repeated all over the codebase. This time, I want to look at what it might take to check the parameters that come into the method.

As Matt Groves pointed out in the comments of my last post, Phil Haack created something called NullGuard to do the kind of thing that I’m endeavoring to do here. In addition, PostSharp themselves created the ability to do just this very thing with the release of PostSharp 3, but it is only available in the paid editions. You can see an explanation in detail here.

Smart people don’t roll their own code for things that are already “solved problems” (I ranted about this in a recent podcast). However, I’m going to tackle this simple problem a few different ways in order to demonstrate how you can create your own more complex rules with PostSharp.

I created a class called NoNullParamsAttribute.cs and its code is as follows

using PostSharp.Aspects;
using System;
using System.Text;

namespace IntroToAop2
{
    [Serializable] 
    public class NoNullParamsAttribute : OnMethodBoundaryAspect 
    {
        public override void OnEntry(MethodExecutionArgs args)
        {
            var messages = new StringBuilder();

            for (int i = 0; i < args.Arguments.Count; i++)
            {
                if (args.Arguments.GetArgument(i) == null)
                {
                    messages.AppendFormat("Parameter \"{0}\" cannot be null. ", args.Method.GetParameters()[i].Name);
                }
            }

            if (messages.Length > 0)
            {
                throw new ArgumentException(messages.ToString());
            }
        }
    }
}

Now, we can call that above one of our methods from last week like this

[NoNullParams]
public string ReverseString(string input)
{
    var inputArray = input.ToCharArray();
    Array.Reverse(inputArray);
    return new string(inputArray);
}

Now when I call it passing in null, I get an argument exception with the message ‘Parameter “input” cannot be null.’. I could obviously do the same check to make sure that it was not empty, or that all integers were greater than zero, and so on. Of course, the examples I mentioned earlier are much more sophisticated, however today we’ve seen how to iterate over method parameters, get their name, and examine them. Not too bad for a day’s work!

All of the code can be found on my GitHub repo for this series under IntroToAop2.