Thursday, August 15, 2013

Android Tip: Checking the Availability of an Intent


Android developers are all too familiar with the concepts of Intent. But often, if you are not careful, calling an Intent using an action name that matches no activities will result in your application crashing.  In order to prevent that, you are advised to check for the availability of that Intent prior to calling it.

To check if an Intent is available, use the isIntentAvailable() method, defined below:

import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;

public static boolean isIntentAvailable(
Context context, String action)
{
    final PackageManager packageManager =     
        context.getPackageManager();
    final Intent i = new Intent(action);
    List list =
        packageManager.queryIntentActivities(i,
        PackageManager.MATCH_DEFAULT_ONLY);
    return list.size() > 0;
}

This method returns a true if there is at least one activity that matches your action name. You can call it as follows:

String action = "net.learn2develop.secondactivity";

//---check if intent is available---
if (isIntentAvailable(this, action)) {
    Intent i = new Intent(action);
    startActivity(Intent.createChooser(
        i, "List of Apps"));
} else {
    Toast.makeText(this, "Intent is not available",
    Toast.LENGTH_LONG).show();
}

iPad Courses on the 9 Sep 2013 (Mon)

Schedule at a Glance
Course
Date
Fee (S$)
MAC101 – Developing iBooks using iBooks Author
  • 9 Sep 2013 (Mon)
  • 9am to 12noon
$270 (nett; no GST)
MAC103 – Using iPad to Create Stunning Keynote Presentation Slides
  • 9 Sep 2013 (Mon)
  • 2pm to 5pm
$270 (nett; no GST)

MAC101 – Developing iBooks using iBooks Author


In this course, you will learn how to create your own iBooks using the new iBooks Author.  You will learn how to quickly create interactive iBooks and preview them on your iPad. You will also learn how to publish your iBooks on the iBookstore.
  • Exploring the templates
    • Basic, Contemporary, Modern Types, Classic, Editorial, and Craft
  • Components of an iBook
    • Title
    • Intro
    • Media
    • Table of Contents
    • Glossary
    • Chapters
    • Pages
    • Sections
  • Page Layouts
  • Adding Objects
    • Graphics
    • Figures
    • Shapes
    • Charts
    • Widgets
  • Previewing your iBook on the iPad

Duration 
    • 3 hours
Venue
Bayview Hotel Singapore
30 Bencoolen Street 
Singapore 189621

Application Form

Fee
    • $270 (nett; no GST)

You are required to bring along the following equipment for the course.
Hardware
Mac running OS X 10.8 or above (Mountain Lion)
iPad or iPad mini (required)
Software
iBooks Author (free download)
You will get a free 16GB thumb drive containing all the resources used for this course.

Inclusive of 1 tea break

MAC103 – Using iPad to Create Stunning Keynote Presentation Slides
In this session, you will learn how to create your own award winning Keynote presentation slides, all from the comfort of your iPad.  You will learn how to quickly create compelling presentation slides and incorporate multimedia elements into your presentation.
    • Exploring the Themes
      • White, Black, Gradient, Showroom, etc.
    • Basics of Keynote 
      • Changing Text color
      • Using Text 
      • Importing Graphics
      • Notes
    • Working With Media
      • Working with Images
      • Drawing Objects
      • Layering Graphics Objects
      • Movies
      • Animations 
    • Working with Tables
    • Displaying Charts
    • Builds and Transitions
    • Exporting Keynote to PDF, PPT, etc
Duration 
    • 3 hours
Venue
Bayview Hotel Singapore
30 Bencoolen Street 
Singapore 189621

Application Form


Fee
    • $270 (nett; no GST)

You are required to bring along the following equipment for the course.
Hardware
iPad or iPad mini (required)
Software
Keynote for iOS (you need to purchase this from the AppStore for US$9.99; you will be reimbursed for this purchase when you attend this course)
You will get a free 16GB thumb drive containing all the resources used for this course.

Inclusive of 1 tea break

Tuesday, August 13, 2013

Android NFC Course on 23 Aug (Fri) is now confirmed!


For those of you who are interested in emerging technologies, come join us in the Developing NFC (Near Field Communication) Android Apps course on the 23 Aug 2013. 

This course will show you how to write apps that read and write to NFC tags. You will also learn how to transmit data between two Android devices using a feature known as Android Beam. 


P.S. You need to bring along your NFC-enabled Android device. NFC tags will be provided (you get to keep them after the course). 

Wednesday, August 07, 2013

Foundation of Android Programming - 9-10 Sep 2013

Come and join us in the Foundation of Android Programming course on the 9-10 Sep 2013. You will learn all the important topics to start developing Android applications - activities, intent, broadcasts and broadcast receivers, consuming web services, data storage, databases, and more!

Download the course outline and application form here.

Venue
Bayview Hotel
30 Bencoolen Street
Singapore 189621

Date
9-10 Sep 2013 (Mon to Tue)

Time
9am to 5pm

Fee
S$997 (nett; GST N.A.)

Developing with Google Maps v2 for Android

In one of my previous articles, I talked about embedding Google Maps in Android applications. Much has changed as Google went about revamping a lot of existing APIs in Android. In version 1 of Google Maps for Android, Google used the MapView to display map data. In version 2, the MapView is deprecated; instead, you have to use a MapFragment. In addition, you no longer need to create a project that targets the Google APIs platform, as Google has migrated a lot of services into Google Play services.
In this article, I will walk you through the steps needed to get Google Maps v2 for Android to work, and show you some of the new APIs you can use in your applications.

Tuesday, August 06, 2013

Windows Phone Tip: JSON to Data Contract Generator

If you are consuming a JSON web service, you can use the DataContractJsonSerializer class to deserialize a JSON string into an object so that you can manipulate the JSON string like an ordinary object. However, it is always a challenge to convert a JSON string into its class representation.

A good and easy way to convert a JSON string into its class representation is to use the tool at http://jsontodatacontract.azurewebsites.net/.

Suppose you have the following JSON string to convert:

{
    "postalcodes": [
        {
            "adminCode3":"70828",
            "adminName2":"Reutte",
            "adminName3":"Reutte",
            "adminCode2":"708",
            "postalcode":"6600",
            "adminCode1":"T",
            "countryCode":"AT",
            "lng":10.724044444,
            "placeName":"Ammerwald",
            "lat":47.490988888,
            "adminName1":"Tirol"
        },
        {
            "adminCode3":"70805",
            "adminName2":"Reutte",
            "adminName3":"Breitenwang",
            "adminCode2":"708",
            "postalcode":"6600",
            "adminCode1":"T",
            "countryCode":"AT",
            "lng":10.7050916669573,
            "placeName":"Bad Kreckelmoos",
            "lat":47.4900855904715,
            "adminName1":"Tirol"
        }
    ]
}

All you need to do is to navigate to http://jsontodatacontract.azurewebsites.net/ and paste it your JSON string. Also, give a name to the root class that will be generated for you (in this case I have called it PostalResult, select the language you want it to generate in (C#), and select the DataContract serialization model. Click the Generate code! button.



The following classes are automatically generated:

// Type created for JSON at <>
[System.Runtime.Serialization.DataContractAttribute()]
public partial class PostalResult
{   
    [System.Runtime.Serialization.DataMemberAttribute()]
    public Postalcodes[] postalcodes;
}

// Type created for JSON at <> --> postalcodes
[System.Runtime.Serialization.DataContractAttribute(Name="postalcodes")]
public partial class Postalcodes
{   
    [System.Runtime.Serialization.DataMemberAttribute()]
    public string adminCode3;
   
    [System.Runtime.Serialization.DataMemberAttribute()]
    public string adminName2;
   
    [System.Runtime.Serialization.DataMemberAttribute()]
    public string adminName3;
   
    [System.Runtime.Serialization.DataMemberAttribute()]
    public string adminCode2;
   
    [System.Runtime.Serialization.DataMemberAttribute()]
    public string postalcode;
   
    [System.Runtime.Serialization.DataMemberAttribute()]
    public string adminCode1;
   
    [System.Runtime.Serialization.DataMemberAttribute()]
    public string countryCode;
   
    [System.Runtime.Serialization.DataMemberAttribute()]
    public double lng;
   
    [System.Runtime.Serialization.DataMemberAttribute()]
    public string placeName;
   
    [System.Runtime.Serialization.DataMemberAttribute()]
    public double lat;
   
    [System.Runtime.Serialization.DataMemberAttribute()]
    public string adminName1;
}

You can paste the above classes into your project. To make use of it, use the following code snippet:

using System.Runtime.Serialization.Json;
using System.Diagnostics;
using System.IO;
using System.Text;

        private void JSON_Demo()
        {
            string json = @"
                {
                    ""postalcodes"": [
                    {
                        ""adminCode3"":""70828"",
                        ""adminName2"":""Reutte"",
                        ""adminName3"":""Reutte"",
                        ""adminCode2"":""708"",
                        ""postalcode"":""6600"",
                        ""adminCode1"":""T"",
                        ""countryCode"":""AT"",
                        ""lng"":10.724044444,
                        ""placeName"":""Ammerwald"",
                        ""lat"":47.490988888,
                        ""adminName1"":""Tirol""
                    },
                    {
                        ""adminCode3"":""70805"",
                        ""adminName2"":""Reutte"",
                        ""adminName3"":""Breitenwang"",
                        ""adminCode2"":""708"",
                        ""postalcode"":""6600"",
                        ""adminCode1"":""T"",
                        ""countryCode"":""AT"",
                        ""lng"":10.7050916669573,
                        ""placeName"":""Bad Kreckelmoos"",
                        ""lat"":47.4900855904715,
                        ""adminName1"":""Tirol""
                    }]
                }";

            //---convert the json string into a memorystream
            // object---
            MemoryStream stream = new
                MemoryStream(Encoding.UTF8.GetBytes(json));

            var serializer = new DataContractJsonSerializer(
                typeof(PostalResult));

            PostalResult result = (PostalResult)
                serializer.ReadObject(stream);

            for (int i = 0;
                 i <= result.postalcodes.Length - 1;
                 i++)
            {
                //---print out the place name---
                Debug.WriteLine(
                  result.postalcodes[i].placeName.ToString());

                //---print out the latitude---
                Debug.WriteLine(
                  result.postalcodes[i].lat.ToString());

                //---print out the longitude---
                Debug.WriteLine(
                  result.postalcodes[i].lng.ToString());
                Debug.WriteLine("----------");
            }
        }

The above code will print out the following result:

Ammerwald
47.490988888
10.724044444
----------
Bad Kreckelmoos
47.4900855904715
10.7050916669573
----------


Monday, August 05, 2013

iOS Tip: Displaying the Activity Indicator View


If your application is performing some long-runing task, it is often good UI design to offer feedback to the user. One of the easiest way is to display a spinner (formally known as the Activity Indicator View) that animates by, what else, spinning. You can display the spinner either within your application, or in the status bar of the iOS device.  

Assuming you have dragged and dropped a Activity Indicator View onto the View window and create an outlet for it named activityIndicator, you can set the following property in the viewDidLoad event:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //---make the view disappear when you stop 
    // animating it---
    self.activityIndicator.hidesWhenStopped = YES;
}

The hidesWhenStopped property indicates if the Activity Indicator View should be hidden when it has stopped animating. In this case, you set it to YES so that it can automatically be hidden when you asked it to stop animating.

To make the Activity Indicator View animate, call the startAnimating method:

    //---start the animation---
    [self.activityIndicator startAnimating];
   
If you want the Activity Indicator View to appear in the status bar, use the networkActivityIndicatorVisible property of the UIApplication object and set it to YES:

    //---make the activity indicator appear in the
    // status bar---
    [UIApplication sharedApplication].
        networkActivityIndicatorVisible = YES;

To stop the Activity Indicator View from animating, call the stopAnimating method:

    //---stop the animation---
    [self.activityIndicator stopAnimating];
   
To stop the Activity Indicator View in the status bar, set the networkActivityIndicatorVisible property to NO:

    //---make the activity indicator disappear
    // in the status bar---
    [UIApplication sharedApplication].
        networkActivityIndicatorVisible = NO;

Friday, August 02, 2013

New Flipboard Magazines for Developers

If you are a developer, here is a good way for you to keep up to-date with the latest in the software development world. I have created four Flipboard magazines focusing on the following areas - iOS, Android, Windows Phone, and Xamarin. Each magazine covers the tips and tricks of each development platform. Click on the following magazines to start reading!

  

  


iOS Tip: Specifying Hardware Requirements

If your application uses special hardware (such as front camera) in order to work, you need to specify that in your info.plist file. Failure to do so will likely anger users who have downloaded (or even paid) for your application only to realize that the app does not work on their devices because they don’t have the correct hardware. Specifying the hardware requirements thus prevents users who do not have the appropriate hardware (as required by your app) from being to purchase your app. But what about specifying hardware that the users should not have? For example, you only want your app to run on the iPod touch and iPad. Hence you need to specify that the device must not have the telephony feature.

To specify the hardware required by your app, you simply need to specify the hardware features in the info.plist file in your project:


However, by default the Property List editor only allows you to set the Required device capabilities key (the raw key name is UIRequiredDeviceCapabilities ) as an array type. This means that you can only set the hardware required by your app, and not the features that you want to exclude. In the above example, your app will require a device running on armv7, has telephony feature (i.e. iPhones), and has a front-facingcamera.

If you want to specify feature(s) that your app do not need, you need to represent the UIRequiredDeviceCapabilities as a dictionary type.

This is how you do it. Right-click on the -info.plist file and select Open As | Source Code. This will show the .plist file as an XML file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleDisplayName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundleExecutable</key>
    <string>${EXECUTABLE_NAME}</string>
    <key>CFBundleIdentifier</key>
    <string>net.learn2develop.${PRODUCT_NAME:rfc1034identifier}
</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.0</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>armv7</string>
        <string>telephony</string>
        <string>front-facing-camera</string>
    </array>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
</dict>
</plist>
As you can see, our three requirements are specified in the element, each represented by a element. To change the UIRequiredDeviceCapabilities to the dictionary type, add in the following statements in bold:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleDisplayName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundleExecutable</key>
    <string>${EXECUTABLE_NAME}</string>
    <key>CFBundleIdentifier</key>
    <string>net.learn2develop.${PRODUCT_NAME:rfc1034identifier}
</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>${PRODUCT_NAME}</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.0</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>UIRequiredDeviceCapabilities</key>
    <dict>
        <key>armv7</key>
        <true/>
        <key>telephony</key>
        <false/>
        <key>front-facing-camera</key>
        <true/>
    </dict>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
</dict>
</plist>

In the example above, we specified that the telephony feature as false. That is, our app can only run on an iPod touch,  iPad, or iPad mini.

If you now right-click the info.plist file and select Open As | Property List, you will see the following:


Thursday, August 01, 2013

Android Tip: Handling Events in a Fragment

In an activity, handling the Click event of a Button is very easy using the android:onClick attribute and assigning it a method name as the event handler. You then implement the method in your activity. However, if you have a Button in a fragment, using the android:onClick attribute does not cause the event handler to fire in the Fragment class; instead it will fire in the Activity class.

In the spirit of loose coupling in Software Engineering, a better way is to handle the Click event of your button in the fragment directly in the Fragment class.

Assuming in your XML file (activity_detail.xml) for your fragment you have a Button with an id of:

    <Button
       android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:text="OK" />

In your Fragment Java class, you need to have the following to handle the Button's click event:

public class DetailFragment extends Fragment 
    implements OnClickListener 
{
    Button btn;

    @Override
    public View onCreateView(LayoutInflater inflater,
    ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(
            R.layout.activity_detail, container, false);
        
        btn = (Button) view.findViewById(R.id.button1);
        btn.setOnClickListener(this);       

        return view;
    }

    @Override
    public void onClick(View v) {
        Toast.makeText(this.getActivity(), 
            "Button is clicked!", Toast.LENGTH_LONG).show();

    }