Discussing the nuts and bolts of software development

Friday, February 25, 2011

 

Windows Phone 7 Isolated Storage Explorer & Open Source Project

Simplifying WP7 local data storage development and testing

Written by: Anthony Hooper and Romeo Dumitrescu

One of the biggest challenges for developing any advanced Windows Phone 7 applications is not using or manipulating the isolated storage, but rather having to continuously set up test and development data over and over again as new features are added or bugs are found and fixed.  Although the WP7 development tools Microsoft has provided are arguably the best of class, there currently is no easy way to explore, load, or export local data in a WP7 device or emulator that is developer friendly.  Until now.


Enter the WP7 Isolated Storage Explorer.  Both a stand alone tool (that connects either to an emulator or a tethered device) or a Visual Studio 2010 plug-in that enables developers and QA specialist or testers to explore, save, and even upload data to the isolated storage.

Lets first explore why the isolated storage is important for WP7 applications.  Relying heavily on loading and storing data from the cloud (web services) results in slow loading and sluggish response time of the application.   It’s a best practice to cache some data locally and in many situations much of the data in a mobile application can be stored locally, something many application do not do.

So how does the WP7 isolated storage explorer enter into the development cycle?  Simply put, it facilitates iterative development and testability of your WP7 applications by facilitating saving, loading and exploring any isolated storage files associated with your WP7 applications.  It will speed up debugging edge cases by enabling developers to load isolated storage cache files to the emulator or device, it will empower QA/Test specialists by enabling them the power to explore local data files to help identify critical bugs.  Furthermore, it will speed up testing and feature development by enabling testers and developers the ability to preload their devices/emulators with dev and test data to short cut recreating use cases.


How do you get started?

            // Code to execute when the application is launching (eg, from Start)
       // This code will not execute when the application is reactivated
       private void Application_Launching(object sender, LaunchingEventArgs e)
       {
            IsolatedStorageExplorer.Explorer.Start("localhost");
       }

       // Code to execute when the application is activated (brought to foreground)
       // This code will not execute when the application is first launched
       private void Application_Activated(object sender, ActivatedEventArgs e)
       {
            // This will restore the state of the explorer and the hostname after
            //  reactivating the application
            Explorer.RestoreFromTombstone();
       }

The connected application will show up in the application drop down list in the WP7 Isolated Storage Explorer desktop client. To see the Visual Studio integrated client: In Visual Studio 2010, click on the View > Other Windows, select WP7 Isolated Storage Explorer.

Finally, why did we start this project? It started as one of our developer's aggravations with the MS provided SDKs. Not that they weren't fantastic (they were very complete) but local storage was difficult to work with. Furthermore, Macadamian believes in efficient, predicable testability of all applications we build. We felt that this was missing from the SDKs provided by Microsoft and hope that this project/tool can help the WP7 developer community. There is nothing like a little healthy competition on the mobile marketplace!

Wednesday, February 09, 2011

 

Nokia and Microsoft to Join Forces? by Martin Larochelle

Last week I attended a presentation by Nokia about how to do business with them. I was planning to write a blog about how to develop for their phones and how to publish applications to the Ovi Store.


I concluded that if one has many C++ developers, the Nokia phone is quite accessible. Most of their presentation was focused around how Qt can now be used to develop for all of their platforms (Symbian, Maemo, MeeGo). This is great for us, because we did a couple of projects with Qt in the past six months. They followed with a walk-through of publishing apps to the Ovi Store. Bottom line, the review process takes 7 to 9 business days and it is rejecting slightly over 30% of the submissions on the fist pass.


Today, a Nokia internal memo was leaked,the contents of which indicated that things could all change on Friday. The memo revealed that the N9 should be the first Nokia device to ship with MeeGo. "at this rate, by the end of 2011, we might have only one MeeGo product in the market". In their presentation, Nokia had hinted that their CEO would make an announcement at MWC, which most of us assumed to be their anticipated MeeGo Tablet. But given the contents of the memo and the fact that the CEO only expects one MeeGo device to ship this year, it now seems unlikely.


The memo will fuel the rumour that Nokia would move to WP7 for its phone platform. In insight, we learned how the Nokia Ovi Store could be a great asset to get WP7 off the ground.


Possibly the biggest asset that Nokia has is the global reach of its platform. Nokia covers 170+ counties with credit card payment and 99 countries with carrier billing. Their store is translated into 30 languages and their application approval process includes a moderation process that takes into account the regional and culture differences of each country published to.


The most surprising statistic which they've released is that carrier billing has increased app sales by up to 13x in some markets. In comparison, Android has carrier billing in two countries and the other competitors have none. These agreements take time to negotiate, and most carriers want to take 50% of the app price. If Nokia brings that to another ecosystem, it would increase the app sales drastically.


Instead of WP7 it would be easier for Nokia to go with Android and have their own application market for their phones. But will developers really want to submit their apps on all these application market clones? WP7 seems like the most accessible choice.


On the other hand, WP7 is struggling. It did not even surpass Windows Mobile in Q4. Although Microsoft shipped 2 million phones, it took almost two months for our biggest WP7 fan to find the one he wanted. What if Nokia moved to WP7 and started distributing massive amounts of WP7 world-wide? It would be a huge gain for Microsoft, having the potential to give them 30% of the World’s smartphone market shares. These potential gains could justify an exclusive deal with Nokia.


According to their memo, Nokia is "standing on a burning platform", which they plan to evacuate on Friday. Will they save the value they have, partner up with Microsoft, and create an ecosystem that can compete with iPhone and Android?


Tuesday, February 01, 2011

 

Pass Me the Data, by Rob Woods

You've written the Hello Android app, then created your own simple app. Now you've created a much more complicated app with several activities. You may need to be able to pass data between your activities. In this post, I will take you from the basics of passing simple data types between activities, right up to making your own custom objects parcelable so they can also be passed along with the same ease as a simple data type.
If you feel that you need a bit more background on this subject matter before reading further, here is a helpful article on Android application development.

Before we start passing data around, first you will need to understand how an activity is launched. To launch a new activity, you would create an Intent and pass it to the Activity method startActivity().

Illustration:
"Intent newIntent = new Intent(Context, Class);
startActivity(newIntent);"

Now lets say you have a listactivity, and whenever a user taps on an entry in the list, you want to launch a new activity that does something with the data from that list entry. The most basic scenario for passing data is to attach an extra to the intent in the form of

"newIntent.putExtra(name,value);"

Where name is a String that is used to "tag" your data and value is the actual data object you are passing to the intended activity. Value can be many different types, including String, int, Boolean, etc. You can see the complete list of putextra methods here.

Here's an example from the callingaActivity.
"Intent newIntent = new Intent(this, SomeActivity.class);
newIntent.putExtra("MAGIC_NUMBER", 42);
startActivity(newIntent);"

Now on the called activity side (receiving the Intent), in your activities onCreate() method, you will need to retrieve the extra data from the intent. You can do this by calling getIntent() to get the intent that started the activity, then getIntExtra(name, default). This is if you passed an int value, if you passed a different type, you would use the corresponding method for that type.

For example:
"int magic_number = getIntent().getIntExtra("MAGIC_NUMBER", 420);"

Note that the default value is used if the tag "MAGIC_NUMBER" had no value assigned to it. This is great if you are just passing one piece of data using a basic data type, but if you are passing more data than just a single type, you might want to consider using Bundle.

Basically, a Bundle is just a mapping of tag-data pairs grouped together into one passable object. Let's say that you had a contact list and when the user taps a contact, you want to pass the name, id and phone number to the called Activity. You could do so like this:

"Intent newIntent = Intent(this, ContactDetails.class);
Bundle extras = new Bundle();
extras.putString("CONTACT_NAME", name);
extras.putInt("CONTACT_ID", id);
extras.putString("CONTACT_NUMBER", number);
newIntent.putExtras(extras);
startActivity(newIntent);:

And on the receiving Activity:

"Bundle extras = getIntent().getExtras();
String name = extras.getString("CONTACT_NAME");
int id = extras.getInt("CONTACT_ID");
String number = extras.getString("CONTACT_NUMBER");"

Now lets say you've created your own data class with several different types of data representing the class:

"public class Dog extends Object {
private String mType;
private String mName;
private int mId;

public Dog(String type, String name, int id) {
mType = type;
mName = name;
mId = id;
} "

You could pass each piece of data separately by adding 4 tag-data pairs to a Bundle and passing the Bundle. However, a smarter way of doing this is to implement the parcelable interface in your Dog class. The parcelable interface has 2 methods which are needed to implement, describeContents() and writeToParcel(Parcel, int).

"@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mType);
dest.writeString(mName);
dest.writeInt(id);
}"

Using this method, you must add each of your data types to the Parcel with the correct write method for its data type.

If your class has child classes, you can use the describeContents() method to differentiate between child classes so that when you unparcel your parceled object, you can create the correct child object.

This is only half of the solution. Now that you have the facilities to write your object to a parcel, you also need to be able to rebuild your object in the called activity. First you will need a new constructor for your class. One that takes a parcel object and can populate it's data members from it;

'public Dog(Parcel dest) {
mType = dest.readString();
mName = dest.readString();
mId = dest.readInt();
}'

Note the order.
You must read your data types from your parcel in the same order you wrote them. Essentially you're flattening your data into one data stream, then reading it back on the other side.

Finally, you will need to create a parcelable creator in your class that will trigger your new parcelable constructor when needed:

"public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public LocalContact createFromParcel(Parcel source) {
return new LocalContact(source);
}

@Override
public LocalContact[] newArray(int size) {
return new LocalContact[size];
}
};"

One last thing I'll leave you with is the concept of chaining your parcelable objects. Lets say your Dog class has a custom object as one of its data members. You need to make sure that class also implements the parcelable interface. In order to support parcelizing your custom object inside your Dog class, you will need to change 2 methods.
First, Dog's writeToParcel(Parcel, int) method needs to tell your custom object to write itself to the parcel.
To do this, we can call writeParcelable(Object, int). This method will invoke your custom classes writeToParcel method:

"@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mType);
dest.writeString(mName);
dest.writeInt(id);
dest.writeParcelable(dogTag, flags);
}"

Here dogTag would be your custom class that could implement say, a phone number and address for where the dog lives. Second Dog's parcel constructor. Here we will call readParcelable(Classloader) to get the custom objects parceled data:

"public Dog(Parcel dest) {
mType = dest.readString();
mName = dest.readString();
mId = dest.readInt();
dogTag = dest.readParcelable(DogTag.class.getClassLoader());
}"

This should get you passing your data around to your activities!

Labels: , , , , , , , , , , , , ,


This page is powered by Blogger. Isn't yours?