September 25, 2012

Setting item selected state in Android GridView

When working with the GridView in an Android app recently, I ran into a very strange behavior around setting the selected state for a view created in my ArrayAdapter’s getView() method.  I’m using selectors to handle the drawable states and everything works properly when tapping a list item to select/tapping again to unselect.  When debugging the ArrayAdapter’s getView() method, I could see that the selected state was being set to the correct value when calling view.setSelected(), but the button background was not updated to the proper state.

After going on the obligatory StackOverflow & Google scavenger hunt, I eventually came across this post, which addresses how to call the setSelection() method in a single-select ListView.  It turns out that the same approach is needed when calling setSelected() on an individual view.

In short, you must do this:

private void setSelected(final View view, final boolean selected) {
    view.post(new Runnable() {
        @Override
        public void run() {
            view.setSelected(selected);
        }
    });
}

The key is posting a runnable on the UI thread to set the selected state. Otherwise, the view is marked as selected but its visual state is unchanged.

February 2, 2012

A Functional Queue in JavaScript

It’s been over a year since I’ve posted here, but I’ve been busy delving into Android and Ruby on Rails among other things. To get back into blogging (hopefully more regularly…we’ll see), I thought I’d share an interesting JavaScript exercise I was asked to complete as part of a job interview recently.

The task was to build a functional queue in JavaScript.  A functional queue is a queue (first in, first out) which is implemented with no side-effects.  For instance, a function to enqueue a value onto an existing queue will return a new object which represents the larger queue.  The original (smaller) queue is still available.

In order to implement a functional queue, we need to be able to do a few things that are not immediately obvious in Javascript:

  1. Create a new instance of the array of queue items when an item is enqueued/dequeued
  2. Overload the class constructor so it can be created with an empty array (new queue) or an existing array (result of a enqueue/dequeue operation
  3. Return both the dequeued item and a new queue as a result of a dequeue operation

To return a new instance of the array of queue items, we can leverage the array.slice() method, which selects part of an array and returns a new array.  The trick here is to pass an index of zero to the slice method to get a new array instance and then use array.push() to enqueue or array.shift() to dequeue.

To overload the class constructor, we can use the arguments array to pass an existing array and create a new one if none is passed.

Finally, to return both the dequeued item and a new queue as a single result, we can use an object literal.

The finished product looks like this:

var Queue = function() {
	var items = arguments.length > 0 ? arguments[0] : new Array();

	return {
		length: function() {
			return items.length;
		},
		isEmpty: function() {
			return this.length() == 0;
		},
		enqueue: function(item) {
			var newItems = items.slice(0);
			newItems.push(item);
			return new Queue(newItems);
		},
		dequeue: function() {
			var newItems = items.slice(0);
			var item = newItems.shift();
			return {
				queue: new Queue(newItems),
				value: item
			};
		},
		head: function() {
			return items[0];
		}
	};
}
December 30, 2010

Adding Basic Authentication to a WCF OData service (and authenticating via an odata4j client if you’re into that sort of thing)

I’ve been slowly building my first Android application over the last several months.  Along the way, I’ve also jumped headfirst into Java development.  My C# background and excellent online documentation have made the transition quite simple, but consuming a WCF OData service from an Android application added a whole new set of challenges.

First, which format should I use to retrieve the data?  At first, I looked into getting JSON back and using one of the various JSON libraries to do the parsing.  This seemed messy and early experiments were not promising.  After going down a few more rabbit holes, I stumbled upon the fledgling yet excellent odata4j library.  odata4j did a great job of retrieving data from my WCF OData service and parsing it wasn’t too difficult.  There are several examples on the project home page to help you get started.  The Netflix OData Catalog was invaluable in getting the query syntax just right.

I won’t go into too much detail about the specifics of my Android application’s architecture (at least not in this post), but will mention that all of the data downloading and synching is done via a background account sync process.  This allows the application to access and edit the data without hanging during sync operations.

Now that the scene has been set, let’s talk WCF OData service authentication.  First, I’ll save us both some time and credit the code for securing the WCF service to this great MSDN blog post.  That post walks you through the creation of an HTTP module and a custom authentication provider.  The user name and password are Base64 encoded and passed to the service via the request header with each request.  The custom authentication provider handles verifying credentials against a database, etc.  If that’s all you were looking for, that blog has everything you need.  Case closed.  If you then need to authenticate against that WCF OData service using odata4j, read on playa.

I knew that to add the Base64 encoded credentials to the request header, I’d have to somehow hook into where the odata4j ODataConsumer is created.  After reading a bit about the OClientBehavior parameter in one of the overloads to ODataConsumer.create(), I looked for examples.  The only thing I could find was the AzureTableBehavior class.  I studied the class a bit and used it as a template for implementing the AuthenticatedTableBehavior class below.

public class AuthenticatedTableBehavior implements OClientBehavior {

    private final String userId;
    private final String password;

    public AuthenticatedTableBehavior(Context context, Account account) {
    	AccountManager am = AccountManager.get(context);
        this.userId = account.name;
        this.password = am.getPassword(account);
    }

    @Override
    public ODataClientRequest transform(ODataClientRequest request) {
        try {
        	String credentials = userId + ":" + password;
        	byte[] credentialBytes = credentials.getBytes("utf8");
        	String encodedCredentials = base64Encode(credentialBytes);
        	request.header("Authorization", "Basic " + encodedCredentials);
            return request;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static String base64Encode(byte[] value) {
        return Base64.encodeBase64String(value).trim();
    }

    private static byte[] base64Decode(String value) {
        return Base64.decodeBase64(value);
    }
}

Once you have added the above class to your project, simply pass an instance of the AuthenticatedTableBehavior class to the ODataConsumer.create() method similar to:

ODataConsumer consumer = ODataConsumer.create(ROOT_URL, new AuthenticatedTableBehavior(context, account));

Note that you'll have to pass an instance of android.content.Context and android.accounts.Account.  Both will be passed to your sync service if you're using account synchronization to retrieve your data.  You'll need to adjust the AuthenticatedTableBehavior class to fit your needs if you're doing something different.

Let me know if this is helpful to you and thanks in advance for any feedback.

Tags: , , , ,
May 10, 2010

Adventures in Windows XP to Windows 7 migration

Based on my experience using Windows Easy Transfer to migrate my home computer to Windows 7, I decided to use it to migrate my office computer from Windows XP to Windows 7…or so I thought. I ended up using Windows XP’s File and Settings Transfer Wizard instead, which is a much less reliable tool. I should have used the Windows Easy Transfer for Windows XP (http://bit.ly/1mmyKw) or just manually copied my files. Lesson learned.

Back to the problem… I had done a clean install of Windows 7, wiping out all of my data. I had a backup, right? After realizing that Windows Easy Transfer and the File and Settings Transfer Wizard ARE NOT the same program, I decided to set up a Windows XP virtual machine so I could restore my settings and then manually copy my data (like I should have in the first place). This was a chore because I had to install ALL the updates to bring the XP installation up to SP3 in order to do the restore. Only the restore didn’t work! I read somewhere that in order for it to succeed, the available hard disk must be at least three times the size of the data being restored. I had 6.5 GB of data, my VHD was only 20 GB. That may have had something to do with the failure, but my data was still inaccessible.

I experimented briefly with the FASTCONV utility (http://bit.ly/axWk3w), which is supposedly another way to extract data out of that magic USMT2.UNC folder that the File and Settings Transfer Wizard creates. I couldn’t get this to work, either.

Ultimately, I discovered the Windows User State Migration Tool (http://bit.ly/9q45hg), an enterprise level tool for migrating user settings. (I had to use version 2.6.2. For some reason, version 3.0 wouldn’t install on Windows 7.) This restored all of the my backed up files with the exception of my Outlook PST, which seems to have disappeared; possibly due to the difference in the location of those files under Windows 7? Luckily, I had all of my emails stored on the POP server, so I’m only missing my sent emails. At least I escaped the clutches of Windows XP with most of my data.

To recap what we have learned here:

  1. Windows XP’s File and Settings Transfer Wizard IS ABSOLUTELY NOT the same thing as Windows Vista’s and Windows 7’s Easy Transfer.
  2. It’s easier to just manually copy your files.
March 12, 2010

SharePoint Designer – Using the same custom form layout for both New and Edit pages

After building a custom Edit form for a custom list with a large number of fields with SharePoint Designer, I was not looking forward to repeating the process for the New form.  I was sure there had to be a way to reuse the form layout once I understood the differences in the HTML behind the New and Edit forms.  After trying a few things and doing some web searches, I figured out how to do this.

The steps are as follows:

  1. Save the default EditForm.aspx or NewForm.aspx page with a different name. 
  2. Add the appropriate type of SharePoint Custom List Form to the page (Edit or New). 
  3. From the HTML of the web part whose layout you want to reuse, copy everything between the <xsl:template name="dvt_1.rowedit"></xsl:template> tags into the new page, replacing those same tags in the form added in Step 2. 
  4. Do a “Replace” to replace all the ControlMode=”Edit” attributes with ControlMode=”New” or vice versa. 
  5. Do a “Replace” to replace all the DataBind(‘u’ (update on Edit pages) references with DataBind(‘i’ (insert on New pages) or vice versa. 
Props to Tim in the comments of this post for pointing me in the right direction.

This is my first post on this, my professional blog.  More to come!  Thanks for reading.
Follow

Get every new post delivered to your Inbox.