jvance.com

.net, c#, asp.net, linq, htpc, woodworking

Jarrett's Tech Blog

  1. Getting Started with Android

    I've been following Android since it was released in late 2008.  I was excited because I knew the potential was limitless. One year later, both me and my wife got our first Android phones, the Verizon Motorola Droid.  It only took a year for Android to mature into greatness, but it still has a way to go.  I'll discuss some of the basics of using Android and share some of my favorite tips and applications.

    Why I Like Android

    Android is built on top of a solid foundation of openness and optimism.  Computer geeks like me love the piece of mind that comes with knowing you can change/fix anything you don't like about your phone.  Android allows you customize anything about the phone.  Also, Google is pushing for an ecosystem where all devices are treated equal.  The future of the cell phone is not 2 year contracts or nickle and dime calling plans.  We will no longer need voice plans, just a monthly data plan.  Android will enable this.  If not 2010, 2011.

    contacts

    Before You Start

    With Android, your data lives in the cloud.  For the best experience, before you get your new Android phone, you should update your contacts on your Gmail account.  Still using Hotmail? Now is a good time to switch.

    The contacts manager in Gmail works really well.  It isn't pretty and there does seem to be some missing features, but it gets the job done.

    • Organize your contacts into Groups
    • Clean up your contacts, put the proper first and last name in for everyone
    • Add phone numbers, addresses to your contacts so you can easily call or navigate to the contact
    • You can batch import from a CSV file
    • Add pictures to your contacts so they show on the phone (Note: your phone will pull a picture from Facebook but the picture is usually too small to see clearly)
    • Crop pictures of contacts to just their face so it is easier to recognize when they are small

    Things to Know About your Droid

    verizon-droid-phone-76ca6b81ec4c0d36_large[1] The Droid is a great phone, but there are few things you should know about it.

    • There is a button on the top to turn the screen on and off (I didn't know at first because my wife turned it on for the first time).
    • The screen and OS support multi-touch but it is not enabled.  When I first held the phone, my finger would inadvertently touch the side of the screen and my other finger would not register swipes and taps.  So make sure when you hold the phone, your fingers aren't touching the side of the screen.
    • The gold button on the side is the camera button.  Just hold it down to start the camera.  Hold it down again to focus and take a picture.
    • Before taking pictures, wipe the lens with a clean cloth as my lens is usually smudged from handling it.
    • There is protective plastic behind the sliding screen.  It will come off eventually.  No big deal.

    Things to Know About the Android OS

    • The notifications take place at the top the screen.  You can drag this down to see more info about the notification or clear the notifications.
    • Hold down the home button to switch between recent applications.
    • Hold down the search button to do voice searches.
    • Touch and hold down anywhere there is a blank spot on the desktop to add shortcuts and widgets to the desktop.  You can swipe between three desktops.  Take advantage of all three.
    • Make sure you use the toggle widget to manage your battery usage.
      • The icons from left to right are: Wifi, Bluetooth, GPS, Sync, Brightness
      • Airplane mode will use the least amount of battery.

    My Desktops

     androiddesktops

    • The middle screen is where I keep the main apps that I use on a daily basis.  This is also where I have the Power Control widget that is very important for controlling battery usage.
    • The right screen is where I keep shortcuts for directly calling people, mostly my family.
    • The left screen is where I access my music and news and check my calendar.

    droid_dock[1] Accessories

    I received a multi-media dock as a present and I keep it at my desk at work.  I love it.  The phone easily slides in and out and it keeps my phone charged.  My wife has the car dock and she loves it as well.

    If you have the docks then you can't really use protective cases.  All the protective cases for the the Droid seem crappy anyway probably because it is physically difficult to make a decent case for a slider phone.  Anyway, the screen is Gorilla glass which makes it very difficult to scratch.

     

    Applications

    • Bump - this application is great for exchanging photos and contact information.  You can even bump iPhones.
      bump
    • Barcode scanner, Google Goggles - take pictures of barcode and QR codes or with goggles you can take pictures of  stuff and it will figure out what it is.  You can even download new applications to your phone by taking a picture of the 2D barcode.
    • Google Voice - replaces my old cell-phone number and gives me Gmail like functionality for my voice mail.  When anybody calls my Google Voice number, it rings my cell, both my work numbers, and it rings on my computer at home. 
    • Corporate Email - Android has decent support for corporate email with exchange access.  It isn't the complete exchange experience, but it works.
    • FlingTap Done - A nice TODO list app that has some neat features.
    • Google Maps w/ Google Latitude - the maps application is great.  It supports street view, and with latitude, you can see where your friends are at.  Now, when my wife meets me at the restaurant, I know when she'll arrive.
    • Tracks - record the GPS locations of your jogs, walks, car rides, etc.
    • Music - with all the internet based music apps, you don't really need to put music on your phone.  I like Last.fm and Slacker radio.  Pandora is starting to have too many comercials.  Also, you can easily buy songs from Amazon MP3 or just listen to 30 seconds of all the "Hot" songs.
      slacker
    • Podcasts - I use Google Listen for my podcast needs.  Ironically, the search function isn't that great.
    • Newsrob - Although I prefer to use Google Reader on my laptop to keep up with my favorite blogs, this app does the job when I'm on the go and it stays in sync with Google Reader.
    • USA Today and NPR News - good news apps.
    • Google Talk, Facebook, Swift - these apps let me IM, keep in touch with friends and tweet.
    • OpenSudoku, Shortyz (cross word), Robot Defense (tower defense), Devilry Huntress (bejeweled), Labyrinth Lite, Totemo are all fun puzzle/strategy games.
      opensudoku
    • Nesoid and SNesoid are great emulators for some retro Nintendo and Super Nintendo gaming.
    • SchottGunn and The Schwartz Unleashed turn your phone into a light saber and a shotgun.
    • Flixster Movies - goto app for when we feel like going to the movies.
    Posted by JarrettV on January 22 at 12:12 AM

  2. Comparison of YUI Compressor for .Net to Microsoft Ajax Minifier

    Minify

    Microsoft just released the Microsoft Ajax Minifier for minifying javascript files.  Since I've been using the Yahoo! UI Library: YUI Compressor for .Net to do this in AtomSite, I thought it would be great to compare the two to see which is best.  I'm mainly interested in the file size reduction but it would be nice to know any speed differences as well.

    The Test

    image

    This method allows me to test compress some javascript using any method I pass into the Func delegate and capture the results.

    To get a reasonable sample of the performance I minified 3 different files with each method 1000 times.  I attempted to configure both algorithms to produce the smallest output possible.

     image

    The Results

    image

    From these results you can see that Microsoft AJAX Minifier creates smaller files in about the same amount of time.  Note, both algorithms have been set in aggressive, or hypercrush, mode to rename variables and perform other tweaks for reducing file size. The Microsoft AJAX Minifier seemed to have more granular options for tweaking output. However, the YUI Compressor is open source so you could add additional options if you need them.

    The Comparison

    Scorecard Speed Size Reduction Options CSS & JS Support Build Task Open Source
    YUI Compressor lose lose lose win win win
    Microsoft AJAX Minifier win win win lose win lose

    And the Winner is..

    It depends.  I suggest using the Microsoft AJAX Minifier as it produces smaller files.  However, the YUI Compressor.Net better satisfies my needs as it can minify both JS and CSS files.  So, when I need to minify dynamic combinations of both types of files, I'll use Yahoo! UI Library: Compressor for .Net.  When I need to do one-time minification during a build or prior to deployment, I'll use the Microsoft AJAX Minifier.

    Download

    I've uploaded the test solution and console app so you can run the tests yourself.

    JsMinTest.zip (291KB) fixed

    More Reads

    Check out how I am using minification and combination in AtomSite to speed up page load time.

    Posted by JarrettV on October 19 at 11:57 PM

  3. Publish Photos with Live Photo Gallery to Picasa Online

    The following guide will assist you in posting your favorite photos online for you friends and family to enjoy.  It will also show you how to geotag those photos as to see where the photo was taken on the map.

    Step 1: Import Photos from Camera

    You should already have Windows Live Photo Gallery installed on your machine.  If not, you can download it from Microsoft.

    Tip: when downloading, uncheck the MSN Toolbar and anything else you don't need from the install.

    Once the photo gallery application is installed, plug your camera into your computer to transfer your photos.  You should see the following window pop up.

    CameraAutoplay

    Select Import Pictures and Videos using Windows Live Photo Gallery.

    The next screen will allows you to name and tag the photos you are importing.  It is important to add this information to your photos so you organize and find them later.  If you've taken photos over series of days on different subjects, you'll want to choose the first option.  Otherwise, the second option is best when all the photos on your camera are similar.

     ImportPhotos

    Since my subjects are different, choose the first option.

    For each group of photos, type a name and some tags.  The name is similar to an album name and this is where all the photos will be stored on your computer.  The tags help describe what is in the photo.  Example tags: Dog; Cat; Pet; Nature; Landscape; Vacation; Flower; Food

    ImportPhotoGroups

    Click import to load the photos onto your computer.

    Step 2: Fix and Rate Photos

    Now you should see photos inside Windows Live Photo Gallery.  Go through your photos and Fix them by cropping or adjusting the exposure and colors.  Each time you look at a photo, you should add any additional tags or even a caption to the photo.  Now you can rate your photos.  Here is how I rate my photos.

    Rating Description
    No Stars Don't even rate photos that are below average
    * Stars This is an ok photo, but not good enough to show off
    ** Stars This is a good photo with substantial meaning, personal album
    *** Stars This is a great photo people should see, share online album
    **** Stars This is a best in class photo, wall hanger
    ***** Stars This is an extremely rare excellent photo, magazine cover

    Step 3: Publish Photos Online

    Now that your photos are well tagged, you can publish them online to share with everyone.  I use Picasa, but you can also use Flickr, Facebook, Smugmug, and others.  You'll likely need a plugin to publish to these online services.  See Listing of Publish Plugins for Windows Live Photo Gallery.

    Since I am using Picasa, I'm going to download the Picasa plugin. Once it is installed, you are now ready to upload your photos.

    Next, select all the photos you want to upload to a single album.  You can choose your best photos by filtering them with the stars.

    WindowsLivePhotoGallery

    Once you've selected the photos you want to upload, click Publish and choose Publish on Picasa Web Albums.

    Login with your Google account.

    PicasaPublisherLogin

    Now you can choose an existing album or create a new album. Type in a name and optional description. Also, I recommend that you limit the max photo size to 1600 or lower to speed up the uploads (and keep people from stealing full resolution copies of your photos).

    PicasaPublisher

    Click OK to start uploading.

    Once your photos are uploaded, you can view them online.

    Step 4: Set Location of Photos

    Choose a photo from your new album. Click the Add Location link on the right side of the photo.

    AddLocation

    Type in the location of where you took the photo.  Zoom in on the map and click the exact location to mark where you took the photo.  It is very helpful to switch to satellite mode.  Usually, in satellite mode, you can zoom in for an extremely accurate geotag.

    MapYourPhotos

    Now you can add the location to the rest of your photos in the album. 

    Tip: It is best to do this photo-by-photo in succession since the locations are usually near each other on the map.

    Once you've marked all the locations of your photos, you can see where they were taken on the album map.

    PhotoLocations

    Congratulations, now you can email the link to your new online photo album and wow your family and friends.

    Posted by JarrettV on August 19 at 11:35 AM

  4. Get Value of Checkbox using jQuery to Enable Button

    Reading the value of a checkbox in jQuery is not obvious.  You must use a special selector :checked and then check if the value is undefined.

    //checked
    var checked = $('input[type=checkbox]:checked').val() != undefined;
    
    //unchecked
    var unchecked = $('input[type=checkbox]:checked').val() == undefined;
    

    The typical use case for this code is when you want the user to check the "I agree to the terms and conditions" before they can continue. For example:

    $(function() {
      $('#agree').click(function() {
        var satisfied = $('#agree:checked').val();
        if (satisfied != undefined) $('#continue').removeAttr('disabled');
        else $('#continue').attr('disabled', 'disabled');
      });
    });
    

    The above code finds the checkbox and binds to the click event.  When the user checks or un-checks the checkbox, it finds the continue button and enables or disables it based on the value of the checkbox.

    Update - A more elegant way

    //checked
    var checked = $('input[type=checkbox]').is(':checked');
    

    Change Textbox Readonly Value via Checkbox using jQuery

    Another case you may want to enable or disable a textbox based on the value of the checkbox.

    $(function() {
      $('#isOther').click(function() {
        var other = $('#isOther:checked').val();
        if (other != undefined) $('#other').removeAttr('readonly');
        else $('#other').attr('readonly', 'readonly');
      });
    });
    

    The above code changes the readonly property on the textbox when the checkbox is changed by the user.

    Posted by JarrettV on July 14 at 3:58 PM

  5. Tiny HTPC Movie and Hulu Box Part 5 Conclusion

    The two 50mm fans arrived and I put them into their new home.  To line them up in the back, I raised them up on a small piece of wood and tie-wrapped them into place. They are the perfect height for the case.  I used some aluminum to fill in the blank spaces.  I got lazy at the end and used a wood block to plug the last space.

    Hulu Box 006 Hulu Box 013

    The HTPC made too much noise with these new fans so I made a couple modifications:

    • Change fans to run from 5 volt instead of 12 volt (from 5000rpm down to 2100rpm) see here
    • Remove some of the metal blocking the PSU fan

    The noise is now on par with the original Xbox.  I plan to replace the PSU fan with a silent 40mm fan from FrozenCPU to further reduce the noise.

    Hulu Box 035

    I also removed the casing over the PSU and organized the wires for better air flow. I taped over some of the rear holes so the air would enter from the front and travel across the motherboard.

    Hulu Box 009  Hulu Box 010

    Temps CPU 1 CPU 2 Northbridge
    Idle 32 C 33 C 48 C
    Load 58 C 60 C 55 C

    The Rear

    The motherboard IO panel fit perfectly between the top and bottom of the case.

    Hulu Box 038

    The Front

    I lightly sanded the sharp edges of the black plexi-glass.  I did not have any extra fine sandpaper so I used a buffing pad to get a smooth matte match with the case.

    Hulu Box 024

    The keyboard is a Logitech diNovo Mini and compliments the case really well.  The Zotac ITX motherboard allows you to enter the BIOS using the Delete key.  So even though the keyboard doesn't have function keys, it will still work in the BIOS.

    Hulu Box 041

    Here it is in it's final resting place on the fireplace mantel.  You can see the Wii on the right for comparison.

     Hulu Box 046

    I'm very happy with how the custom modded case turned out. The motherboard, PSU, fans, buttons, and black plexiglass all came together much better than I expected.  It is a cool, quiet, and beautiful computer.  Most of all, it plays every file format and can run video from any website perfectly.

    I recently installed Boxee and I've been watching some 1080p files and listening to Pandora all within the same interface.  Boxee is definitely the future of the HTPC.

    Posted by JarrettV on June 27 at 10:03 PM

  6. Tiny HTPC Movie and Hulu Box Part 4 Assembly

    I created the front from a scrap piece of black plexi-glass found at a local glass supplier: Eastern Shore Glass.  They cut it for me by scoring and snapping it. They were extremely nice and helpful. I got two pre-cut pieces and some scrap all for $8.

    Hulu Box 008

    I drilled holes in the plexiglass for the buttons and LEDs.

     Hulu Box 007

    Drilling a hole in plexiglass greater than 1/4" is tricky.  I needed to start with a smaller bit and keep increasing the size to keep shards from breaking off.

    On the back side of the black plexiglass I created a frame from aluminum that I could use to mount it to the case. I used brass screws to match the case feet.

    Working with aluminum is fun as it is a fairly soft metal that is easy to drill and cut.

    Hulu Box 021

    The buttons are held in place with wood and hot glue. The LEDs are simply hot glued in place.

    Hulu Box 027 Hulu Box 032

    I bolted the plexiglass aluminum frame to the case.  On the bottom of the case, I drilled and cut holes for air intake.  The cool air enters from below and travels across the motherboard to exit out the rear via fans.  There are no vents on the top or sides.

    Hulu Box 012

    I mounted the power supply in the case using a single bolt which keeps it from sliding backward when plugging in.  I used wood spacers covered with a thin layer of foam to allow the PSU to be sandwiched between the top and bottom of the case.  A small bracket made from aluminum provides enough friction to keep the PSU firmly in place.

    Update: I've since removed the power supply circuit board from the casing and created a new solid backplate so I could reduce the number of fans needed in the case.  I also added additional holes below the PSU circuit board to bring in cool air.

    Hulu Box 028

    I mounted the motherboard by drilling four holes and using small bolts.  The rubber feet act as standoffs to raise the motherboard up to the desired height.  It also allows air to easily travel below and around the board.

    Hulu Box 034

    In the next part, I'll mount the fans, round the edges of the plexiglass and show the final photos of it in action.

    Posted by JarrettV on June 23 at 12:13 AM

  7. Jackson

     

    Jackson 016

    Jackson

    Posted by JarrettV on June 22 at 11:21 PM

  8. Tiny HTPC Movie and Hulu Box Part 3 Hardware Test

    The parts arrived from Newegg and I put it together.  The Intel fan that came with the CPU was not very tall. The fan may have fit the short height of the case, but it would have been tight.  I'm glad I ordered the other fan.

    Here is a picture of it after I turned it on.

    Mini ITX Build

    I rescued some buttons, LEDs, and speaker off of an old case.

    Buttons and LEDs

    I fired it up, loaded Windows 7 RC1 and the new Hulu Desktop app.

    Hulu Desktop App on HDTV

    Unfortunately, watching fullscreen Hulu is choppy.  I've played many different video formats (MKV, Bluray, DivX) and they all play smooth regardless of resolution (720p, 1080p, etc). This is definitely a bug in the Hulu desktop app as even CBS, Youtube, and Vimeo HD videos playback fine.  I plan to try some various changes to resolve the Hulu video stuttering.

    Update: Hulu is only choppy within the desktop application.  It is smooth when played through the browser.

    Update2: Found a thread in their forum: Lag in fullscreen mode

    It is also mentioned in many other threads so this seems to be a common problem.  Let's hope they fix it soon.

    In the next part, I'll mount the parts into their tiny new home (see part 1) and fabricate a front-panel.

    Posted by JarrettV on June 14 at 1:02 AM

  9. Unzip Nested Zip Files While Streaming

    I recently encountered a scenario where I needed to unzip all the files in a zip file and also any files from internal zip files.  The source data is streaming in through an HTTP POST via IIS into BizTalk. The zip files can be large (up to 200 MB) and there can be multiple posts happening at the same time.  This is too much data to fit in memory.  Also, I needed to avoid unnecessary network traffic so using temporary files is not an optimal solution.  Therefore, I needed a forward-only streaming solution.

    To accomplish this, I turned to #ziplib. The ZipInputStream object looked like the perfect solution to this situation. Here is an example of how to use this class:

    using ( ZipInputStream s = new ZipInputStream(stream)) {
      ZipEntry theEntry;
      while ((theEntry = s.GetNextEntry()) != null) {
        int size = 2048;
        byte[] data = new byte[2048];
        size = s.Read(data, 0, data.Length);
        if (size > 0) {
          Console.Write(new ASCIIEncoding().GetString(data, 0, size));
        } else {
          break;
        }
      }
    }
    

    As the raw data is streamed through the ZipInputStream, it gets unzipped.  The GetNextEntry() method sets the position to the beginning of the next file.  Then we just read from the ZipInputStream to get the unzipped file data.  So to unzip nested zip files, I came up with a function I could call recursively:

    public static void NestedUnzip(Stream stream, string targetPath)
    {
      ZipInputStream s = new ZipInputStream(stream);
      ZipEntry entry;
      while ((entry = s.GetNextEntry()) != null) {
        //when internal zip file, unzip it
        if (Path.GetExtension(entry.Name).ToLower() == ".zip") {
          NestedUnzip(s,
            Path.Combine(targetPath, Path.GetFileNameWithoutExtension(entry.Name)));
        } else {
          //make sure target path exists
          string path = Path.Combine(targetPath, entry.Name);
          Directory.CreateDirectory(Path.GetDirectoryName(path));
    
          //write the data to disk
          using (FileStream fs = File.Create(path)) {
            byte[] buffer = new byte[1024];
            int read = buffer.Length;
            while (true) {
              read = s.Read(buffer, 0, buffer.Length);
              if (read > 0) fs.Write(buffer, 0, read);
              else break;
            }
          }
        }
      }
    }
    

    Now this would work great for my needs as it process the data as a forward-only read-only stream.  However, whenever a nested zip runs out of entries (i.e. GetNextEntry() == null) the ZipInputStream calls close on the underlying stream.  This results in the unzip process ending prematurely.

    To fix this, I commented out the Close() call within the GetNextEntry() method of the ZipInputStream class:

    if (header == ZipConstants.CentralHeaderSignature ||
      header == ZipConstants.EndOfCentralDirectorySignature ||
      header == ZipConstants.CentralHeaderDigitalSignature ||
      header == ZipConstants.ArchiveExtraDataSignature ||
      header == ZipConstants.Zip64CentralFileHeaderSignature) {
      // No more individual entries exist
      // -jv- 11-Jun-2009 Removed close so it can support nested zips
      //Close();
      return null;
    }
    

    Of course, the calling method should properly close the source stream so this is a safe change to make. For example:

    using (Stream s = inmsg.BodyPart.GetOriginalDataStream()) {
      NestedUnzip(s, unzipLocation)
    }
    

    The result is a perfect streaming solution with low memory usage and no need for temporary files.

    Posted by JarrettV on June 13 at 11:33 AM

  10. Tiny HTPC Movie and Hulu Box Part 2 The Parts

    HtpcParts2

    I ordered the parts today from Newegg.

    The video is built into the motherboard and I plan to reuse a hard drive I already have.  I'm hoping to get away with just using a Media Center remote control or a smaller bluetooth keyboard once things are setup.  Also, I will leave open the option of adding a full-size DVD/Bluray drive in the future.

    These parts are powerful enough to do everything I need.

    In the next part, I'll assemble the parts and load the OS to test out the components.

    Posted by JarrettV on June 09 at 9:00 PM

© Copyright 2024