Tuesday, December 21, 2010

Detecting is home(launcher) screen showing

While developing widgets for android, especially the clock widget which should updates each second, determining whether the home screen is on top is important to save for batteries and CPU power. After quite some time of research, following is the method I could find to do this:

 public boolean HomeIsShowing(){
  Intent intent = new Intent(Intent.ACTION_MAIN);
  intent.addCategory(Intent.CATEGORY_HOME);
  ArrayList homeList = new ArrayList();
  for(ResolveInfo info : this.getPackageManager().queryIntentActivities(intent, 0)){
   homeList.add(info.activityInfo.packageName);
  }
  
  ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
        for (RunningTaskInfo t : am.getRunningTasks(1)) {
            if (t != null && t.numRunning > 0) {
                ComponentName cn = t.baseActivity;
                if (cn == null)
                 continue;
                else
                 if (homeList.contains(cn.getPackageName())) return true;
            }
        }
        return false;
 }

Tested on my HTC Desire, it tooks about 5000ms to run 1000 iteration of the above query: that's about 5ms each time, it's quite heavy since it is querying all the applications installed (maybe?) so you probably won't use this too often.

Sunday, December 12, 2010

Creating custom Client validation for ASP.net MVC3 Unobtrusive Validation [1]

There are quite some tutorials on the Internet about creating custom validation attributes for ASP.net MVC. One of the greatest one is this:

http://bradwilson.typepad.com/blog/2010/01/remote-validation-with-aspnet-mvc-2.html

BTW, the remote validation is already included in MVC3 so that this is not needed to create!
MVC3 RC is out, and it is including a nice library called jquery.validate.unobtrusive which allows NO ugly javascript code attached to the form element, and it is working along with jquery validation plugin.

What it would do is adding additional HTML5 data- tags to form and input elements, like this:

        <fieldset>
<p>
<label for="CreateNewAlbum">CreateNewAlbum</label>
<input type="checkbox" value="true" name="CreateNewAlbum"
id="CreateNewAlbum" data-val-required="The CreateNewAlbum field is required." data-val="true" checked="checked">
<input type="hidden" value="false" name="CreateNewAlbum">
</p>
<p>
<label for="NewAlbumName">NewAlbumName</label> <input type="text" value="" name="NewAlbumName" id="NewAlbumName" data-val-requiredif-operator="EqualTo" data-val-requiredif-dependentvalue="True" data-val-requiredif-dependentproperty="CreateNewAlbum" data-val-requiredif="New Album Name is required." data-val="true" class="input-validation-error"> <span data-valmsg-replace="true" data-valmsg-for="NewAlbumName" class="field-validation-error"><span htmlfor="NewAlbumName" generated="true" class="">New Album Name is required.</span></span>
</p>
</fieldset>

In the following posts, I am going to write about how to add custom client validation for unobtrusive scripts.

First, I would start on talking about the jquery.validate.unobtrusive.js plugin-library.

For unobtrusive script to work, following few things must be enabled:
  1. In the View file, make sure ViewContext.UnobtrusiveJavaScriptEnabled = true
  2. In the rendered Html, you need following script file loaded, in following order:
    1. jquery
    2. jquery.validate
    3. jquery.validate.unobtrusive
  3. The model is proper decorated with necessary attributes.
So everything should looks fine and client validation should kicked in. So, what's under the hood of unobtrusive library?

It actually defines an object called adapter, which maps the client data-validator attributes to jquery.validate rules. For example, it maps the required rule of jquery.validate using following snippet:


function setValidationValues(options, ruleName, value) {
options.rules[ruleName] = value;
if (options.message) {
options.messages[ruleName] = options.message;
}
}

adapters.add("required", function (options) {
// jQuery Validate equates "required" with "mandatory" for checkbox elements
if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
setValidationValues(options, "required", true);
}
});

As it is not too hard to guess, the options is actually the object passing to jquery.validate.

Tuesday, November 30, 2010