Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Android

Android - Stock Market Watch (COINS) in C# using Visual Studio 2010

4.90/5 (102 votes)
24 Mar 2013CPOL23 min read 282.8K   10.1K  
Describes the power of C# in building professional application - Stock Market Watch with Charts on Android platform using Mono C#.

Main Screenshots

Revision History

Major revision on 13th September, 2012 - Add Stock Chart (new feature) from Stock Detail Activity

Introduction

Welcome to COINS Mobile - All Exchange Market Watch

"COINS Mobile" allows you to watch Stock Market Data. It illustrates proper application architecture layering and uses a common code base for the Business Layer and Data Layer. It then separates out the User Interface and Application Layer into the appropriate device-applications.

This article discusses the power of C# to build a Professional Application for Android. The purpose of writing this article is to understand what you can do with C# using Visual Studio 2010 similar to how you would develop a Windows Application in C#. All credit goes to Xamarin to provide such a beautiful platform for .NET developers to build application in Android.

Being a .NET developer (even though I started building Android Applications a few years back), I started using Java/Davlink using Eclipse Java. With a little bit effort, within a couple of weeks I built a sample application in Java, but I faced few problems in consuming web methods (.NET Web Services). I had to use Android ksoap (lightweight SOAP client library for the Android platform) which is not very straightforward. Moreover there are still learning curves to understand and get acquainted with the Java language and Eclipse IDE (specially for .NET developers). So, I started evaluating Xamarin Mono using C# as a base language for Android.

This is not intended to be a comprehensive discussion of each feature but I will try my level best to break down the whole application and elaborate, step by step, how to build a professional Android Application in C#. I am sure you'll be able to leverage your existing knowledge of C# and Visual Studio to quickly build a Professional Android Application.

Background  

This application is based on "Stock Market Watch" - Pulling Real Time Stock Quotes from most of the Exchange. "COINSMobile" is targeted to the millions of Stock Traders in the world who desperately need a system available in their hands to watch their stock details (and in the form of a beautiful Android app no less).

I named it "COINS". I will use the term "COINS" in several areas in the article description which will actually refer the Application itself.

What COIN Does

It pulls real time stock data through the web service and displays the details of the stock (a multitude of stock data can be viewed in a single screen). It also provides a further drill-down, detailed view of each stock and chart analysis. The user can create their own custom stock script and view their added stock details.

This Article Covers

  • Using C# and Visual Studio to Develop an Android Application 
  • Understanding Activities and Layouts 
  • Connect to Web Service
  • Using SQLite Database for Local Data Storage
  • Step by Step Guide to Build Professional Android Application
  • Run Methods in a Thread
  • Interactive Layout Design 
  • Creating Action Bar - Menus in Android 
  • Run and Test Application in Emulator 
  • Building Professional Application "COINS - All Exchange Market Watch"

How to start?  

This article is specially written for developers who are working in C#. Whether they are working in Windows, Web, Silverlight, WPF or Windows Tablet, it doesn't matter. You need to know C# and be familiar with Visual Studio.

So here are two things, you need to start developing Android Apps in C#

If you don't have Visual Studio, you can still use Mono Development Environment that comes with the SDK.

Creating "COINSMobile" Project

As I have already mentioned the article is also for Beginners so I thought I would include a quick guide on how to create Android Project in Visual Studio. You can jump this step if already have a decent knowledge of using Mono C# for Android.

The download and installation of Mono Android will take a maximum of 25-40 minutes depending upon your internet speed. Once the SDK is installed, open your Visual Studio.

Click on File>New>Project

You will see a screen below. In the left Pane, select "Mono for Android". Then select "Android Application". Provide a file name and then click "OK" button.

Image 2

Here you go and can see the first screen with some generated C# code. As you can see, all the things are quite familiar like namespace, class and also the generated code itself.

Image 3

The top most part where you see "using namespace" is the default namespace you will be using. If you want to do a special task that is not in the Reference List you need to use "Add Reference" from the solution explorer to add a component (the same as we would do while coding in C#/VB.NET). Like, if you want to do an operation with SQLite (light database), you need to add a reference to "Mono.Data.Sqlite".

One thing I would like to emphasize in the code is the "OnCreate" overridden method

C#
public class MainActivity : Activity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        StartActivity(typeof(MarketWatchActivity));
    }
}

What is OnCreate()?

This is called when the activity is first created. This is where you should do all of your normal static set up: creating views, binding data to lists, etc. This method also provides you with a Bundle containing the activity's previously frozen state

Oops! Activities, and Views - what are these? I will explain these a bit later. Let's have a look at the Activity Life Cycle, which is similar to the ASP.NET Page Life Cycle.

For the time being, think of Activity as a Windows Form or ASP.NET Page.  

Activity Life Cycle 

If we compare Activity with a web page, Activity resembles a web page's 'code behind' in ASP.NET. So, just like a web page we write the code behind in C# and activity is the code behind of Layout.

Layout is an XML called AXML just like in WPF - we call XAML. If you have prior experience working in WPF or Silverlight, it will be easier to understand AXML Layout. 

The application starts with an Activity which will typically has a Layout for displaying the Activity. It clearly defines a Model-View-Controller (MVC) pattern. Layout is the form (or page, or whatever you call the screen) we see in Android. The language is XML. You need to understand Layout very thoroughly to build innovative Android applications. 

Understanding Files in Solution Explorer 

Image 5

We will be concentrating on three folders 

  • Drawable : containing all graphic contents e.g. images 
  • Layout  : contains all layouts (screens we see in Android Application); 
  • Values : Global variables that we will use throughout the application 

Activity1.cs (auto created when you create a project) in the image above is the code behind of the layout. If you need to create a custom class you can create a folder under root and place your classes there.

Understanding Layout - UI 

Layout is kind of a foreign concept if you are a Windows/Web developer using C#. It will be easier to understand if you have knowledge in XAML or ASP.NET in MVC.

It doesn't matter if you are new to this Term. I will try to provide the brief fundamentals of Layouts, but I do prefer to write a separate article on Layout as this is one of the most important things we need to concentrate on, especially when you are shifting from Windows/Web development to Mobile.

Let's begin with a scenario where we need to place a caption in a line, textbox in the second line and a button in the third line.

It’s simple when you use HTML or aspx to design. You create three divs, make the div style clear right and place each control within the div.

Something like in HTML

XML
<div style="clear:right">Code</div> 
<div style="clear:right"><Input type="text" id="text1"/></div> 
<div style="clear:right"><input type="button" id="button1" value="Ok"/></div>

HTML Layout 

Here in Android Layout of the above e.g, 

Axml Layout

You need to play around a bit with the controls to get a better idea. You can view the controls using View>Toolbox

So in brief, here is the actual definition of Layout: 

Layout is the architecture for the user interface in an Activity. It defines the layout structure and holds all the elements that appear to the user.

We can declare layout in two ways: 

  1. Declare in AXML
  2. Create controls at runtime

In the "COINS" Application, you will see - heavy use of creating controls dynamically in Activity Classses. 

How many types of Layout?

  • LinearLayout (Vertical) 
  • LinearLayout (Horizontal)
  • RelativeLayout
  • FrameLayout
  • TableLayout
  • TableRow 

Jump to COINSMobile Application 

We have some pretty fair ideas of the Android Activity Class and Layouts though, I have not gone into details of Activity.cs. We will gather more in-depth knowledge while showing you step by step method of creating Professional Android Application.

We will be building primarily five screens:

  1. Spash Screen 
  2. Market Watch 
  3. Stock Script Detail View
  4. Add Stock 
  5. Get Stock Quote
  6. Show Stock Charts  

Image 8

Image 9

First Step - Connecting to Web Service

We will be using a .NET Web Service to get real time stock data. Web Services plays an important role to talk to an external database whatever the database is. If you want to store data into Mobile, you can use Android's light Database - SQLite. If you would like to talk to external remote database, you need a Web Service or WCF to talk to the database. 

In this example, two Web Methods will be consumed from COINS Application

  • StockExists 
  • GetStockQuote
  • GetStockChart 

In the actual code, please replace the URL for web service to point to your localhost service (webservice project uploaded)

The webservice get Market Data Feed from Yahoo API and then uploadthe web service source. 

Disclaimer: Although great care has been taken in developing Stock Web Service, it is provided without any guarantee of reliability, accuracy of information, or correctness of operation. I am not responsible for any damage that may occur as a result of using this web service. Use this program entirely at your own risk.

Image 10

GetStockQuotes(): Send multiple stocks in a comma separated string and pass it as a parameter. This will return the XML of all the Stocks.

StockExist(): Send multiple stock scripts in a comma separated string and pass it as a parameter. This will return the "Exchange" of the Stock. If a stock script is Invalid, the XML will return "NA" (Not Applicable). Well, we now have two Web Methods which will be sufficient to create Market Watch for All Exchange Stock.

Though the web service is an important layer to fetch the stock details in this Application, the URL provided is used for Proof of Concept. There is no guarantee that the Web Service used will fetch real time data.

Well, let's see, how can we consume Web Methods from Android applications? It is as simple as consuming Web Methods like we all do in Windows or web applications.

Add a Web Reference to the stock service. 

add reference

Now we are ready to consume Web Methods. To get the stock data:

C#
using COINSMobile.stockwebservice;
string strXML = string.Empty;
stockwebservice.StockWebservice quoteObject = null;
try
{
    quoteObject = new stockwebservice.StockWebservice();
    strXML = quoteObject.GetStockQuote(_stocks);
}
finally
{
    quoteObject.Dispose();
    quoteObject = null;
}
//if error occurred while connect8ing to web service
if (strXML.Substring(0, 5) == "error")
{
    var t = Toast.MakeText(this, "Error connecting to web service. Please check your Internet connection...", ToastLength.Short);
    t.SetGravity(GravityFlags.Center, 0, 0);
    t.Show();
    return;
}
if (strXML.ToLower() == "exception")
{
    var t = Toast.MakeText(this, "Service not available now. Please try after sometime...", ToastLength.Short);
    t.SetGravity(GravityFlags.Center, 0, 0);
    t.Show();
    return;
}
//load the xml to XmlDocument
XmlDocument doc = new XmlDocument();
doc.LoadXml(strXML);

The important thing to note here is we use the GetStockQuote method and load the XML string in the XMLDocument to parse the XML. Thus, you can consume Web Methods to talk to Remote Database.

This is not very simple using Android/Java as there are several steps you need to perform in order to consume .NET Web Service using ksoap. 

Before going into further detail, let's see the XML string returned from Wen Method - "GetStockQuote". Here I will be sending two scripts - "GOOG,MSFT" as an input parameter to the "GetStockQuote()" web method.

GOOG: Google Inc (Exchange:Nasdaq)
MSFT: Microsoft Corporation (Exchange:Nasdaq)  

Sample XML Output from Web Method

A Brief Look at SQLite

SQLite is a relational database management system contained in a small (~350 KiB) C programming library. In contrast to other database management systems, SQLite is not a separate process that is accessed from the client application, but is an integral part of it. SQLite is a popular choice as an embedded database for local/client storage in application software such as web browsers, Mobile Device, Tablet PC. It is arguably the most widely deployed database engine, as it is used today by several widespread browsers, operating systems, and embedded systems.

To start with SQLite, you first need to add a reference to Mono.Data.Sqlite.dll;

C#
using Mono.Data.Sqlite;

In the "COINS" application, we will be creating a database and one single Table with subsequent methods to Fetch, Add and Delete stocks that we will be using Market Watch - Favorite List.

Let's have a look at two classes, one we will be for creating a Data Repository and the other for all Database Operations.

Stock Class in CRMMobile.Core Project within the Business Layer.

C#
public class Stock : Java.Lang.Object
{
    public long Id { get; set; }
    public string StockName { get; set; }
    public Stock()
    {
        Id = -1;
        StockName = string.Empty;
    }
    public Stock(long id, string stockName)
    {
        Id = id;
        StockName = stockName;
    }
    public override string ToString()
    {
        return StockName.ToString();
    }
}

The class above is simple enough to understand. Let's have a look in the StockDatabase class in the DataLayer of the Core Project.

C#
public class StockDatabase
{
    private static string db_file = "stockdata.db3";
    private string stockName = string.Empty;
    private static string sMessage;
    public string StockName
    {
        get { return stockName; }
        set { stockName = value; }
    }
    private static SqliteConnection GetConnection()
    {
        var dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal)
                     , db_file);
        bool exists = File.Exists(dbPath);
        if (!exists)
            SqliteConnection.CreateFile(dbPath);
        var conn = new SqliteConnection("Data Source=" + dbPath);
        if (!exists)
            CreateDatabase(conn);
        return conn;
    }
    private static void CreateDatabase(SqliteConnection connection)
    {
        var sql = "CREATE TABLE STOCKTABLE (Id INTEGER PRIMARY KEY AUTOINCREMENT, 
            StockName VARCHAR);";
        connection.Open();
        using (var cmd = connection.CreateCommand())
        {
            cmd.CommandText = sql;
            cmd.ExecuteNonQuery();
        }
        connection.Close();
    }
    public static IEnumerable<Stock> GetStocks()
    {
        try
        {
            var sql = "SELECT * FROM STOCKTABLE ORDER BY ID;";
            using (var conn = GetConnection())
            {
                conn.Open();
                using (var cmd = conn.CreateCommand())
                {
                    cmd.CommandText = sql;
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                            yield return new Stock(reader.GetInt32(0), reader.GetString(1));
                    }
                }
            }
        }
        finally
        {
            StockManager.Message = sMessage;
        }
    }
    public static bool IsStockExists(string _stockname)
    {
        bool Ok = false;
        var sql = string.Format("SELECT * FROM STOCKTABLE WHERE STOCKNAME='{0}';", 
            _stockname);
        try
        {
            using (var conn = GetConnection())
            {
                conn.Open();
                using (var cmd = conn.CreateCommand())
                {
                    cmd.CommandText = sql;
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                            Ok = true;
                    }
                }
            }
        }
        finally
        {
            StockManager.Message = sMessage;
        }
        return Ok;
    }
    public static bool SaveStock(string _stockname)
    {
        try
        {
            bool Ok = IsStockExists(_stockname.Trim().ToUpper());
            if (Ok)
            {
                sMessage = string.Format("Stock Script '{0}' is already added.",
                    _stockname);
                return false;
            }
            using (var conn = GetConnection())
            {
                conn.Open();
                using (var cmd = conn.CreateCommand())
                {
                    try
                    {
                        // Do an insert
                        cmd.CommandText = 
                            "INSERT INTO STOCKTABLE (StockName) VALUES (@StockName);";
                        cmd.Parameters.AddWithValue("@StockName", 
                            _stockname.ToUpper());
                        cmd.ExecuteNonQuery();
                        sMessage = string.Format(
                            "Stock Script '{0}' is added successfully.", _ stockname.ToUpper());
                        return true;
                    }
                    catch (SqliteException ex)
                    {
                        sMessage = ex.Message;
                        return false;
                    }
                }
            }
        }
        finally
        {
            StockManager.Message = sMessage;
        }
    }
    public static bool DeleteAllStocks()
    {
        try
        {
            using (var conn = GetConnection())
            {
                conn.Open();
                using (var cmd = conn.CreateCommand())
                {
                    try
                    {
                        // Do an insert
                        cmd.CommandText = "DELETE FROM STOCKTABLE;";
                        cmd.ExecuteNonQuery();
                        sMessage = 
                        "All Stocks are deleted successfully...\nTo view the stocks" +
                        "in Market Watch, you need to add your custom stock";
                        return true;
                    }
                    catch (SqliteException ex)
                    {
                        sMessage = ex.Message;
                        return false;
                    }
                }
            }
        }
        finally
        {
            StockManager.Message = sMessage;
        }
    }
}

I have used SqLite Helper class to do all database operations. The code is self explained and nothing much within the code to detail. If you are new to SQLite, just play around with the code to explore more.

One point to mention: in the application I used only one Table for adding custom stock script.

SQL
CREATE TABLE STOCKTABLE (
     Id INTEGER PRIMARY KEY AUTOINCREMENT, 
     StockName VARCHAR
);

We will be using Web Service and Database quite frequently in the activity classes.

Now we build the application.

Building Splash Screen (First Tiny Screen with Tiny Code)

Right click solution explorer. Click Add > New Item > Activity (from Android New Window). Name the file MainActivity.cs

C#
[Activity(MainLauncher = true, Theme = "@style/Theme.Splash", NoHistory = true)]
public class MainActivity : Activity
{
   protected override void OnCreate(Bundle bundle)
   {
       base.OnCreate(bundle);
       StartActivity(typeof(MarketWatch));
   }
}

Let's look at the code

[Activity(MainLauncher = true, Theme = "@style/Theme.Splash", NoHistory = true)]
Main Launcher=True

This means the startup Activity. When the application loads it launches this activity.

XML
Theme="@style/Theme.Splash"

Did you notice in Solution Explorer there is an XML file under Resources>Values? This is Strings.xml where we define global variables that can be accessed by the Application.

To start a theme you need to create a graphics file and add it in Resources>Drawable. Once you add it, you will see a reference in "ResourceDesigner.cs" like

C#
public partial class Drawable
{
    public const int splash = 2130837511;
    .....
}

Here is the XML for splash in strings.xml

XML
<style name="Theme.Splash" parent="android:Theme">
    <item name="android:windowBackground">@drawable/splash</item>
    <item name="android:windowNoTitle">true</item>
</style>

So, when we write "@style/Theme.Splash" - activity points to the splash image. The name of the image here is splash.png.

StartActivity(typeof(MarketWatch)); - Here MarketWatch is another Activity class which is called from splash screen. So, this is the starting point of the application.

That’s powerful stuff! Isn't it so simple? Just create a graphics file, add add the file using "Add>Add Existing Item" from Drawable, add the definition of a graphics file in strings.xml and write only two lines of code. Fair enough, let's look into the next screen "Market Watch"

Start with - Market Watch

Here we will be creating a dynamic control "TableView". The reason for creating a dynamic control is that we are not sure in design time how many Table Rows we will have. Table Rows will be created dynamically depending upon the records in the stock table (initially the stock table is blank, but it will grow subsequently upon adding stock script into SQLite Database). So, let's have a look at how we create dynamic control in Android Activity Class.

XML
<ScrollView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TableLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:stretchColumns="1"
        android:id="@+id/deatlWatchLayout" />
</ScrollView>

Note: I have used "ScrollView" just at the top of TableLayout. The reason is, if you have stocks that don't fit in the screen you will see vertical scroll bar, which you can use to scroll the view.

C#
private void PopulateDataToControls(string _stocks)
{
    //we have now the stocks delimited by comma
    //this string will be passed to Webservice as a paramete to fetch the stock block in xml
    string strXML = string.Empty;
    stockwebservice.StockWebservice quoteObject = null;
    try
    {
        quoteObject = new stockwebservice.StockWebservice();
        strXML = quoteObject.GetStockQuote(_stocks);
    }
    finally
    {
        quoteObject.Dispose();
        quoteObject = null;
    }
    //if error occurred while connect8ing to web service
    if (strXML.Substring(0, 5) == "error")
    {
        var t = Toast.MakeText(this, "Error connecting to web service. Please " + 
          "check your Internet connection...", ToastLength.Short);
        t.SetGravity(GravityFlags.Center, 0, 0);
        t.Show();
        return;
    }
    if (strXML.ToLower() == "exception")
    {
        var t = Toast.MakeText(this, "Service not available now. " + 
          "Please try after sometime...", ToastLength.Short);
        t.SetGravity(GravityFlags.Center, 0, 0);
        t.Show();
        return;
    }
    //load the xml to XmlDocument
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(strXML);
    tablelayout.RemoveAllViews();
    tablelayout.RefreshDrawableState();
    XmlNodeList xnList = doc.SelectNodes("/stock/symbol");
    foreach (XmlNode xn in xnList)
    {
        if (xn != null)
        {
            TableRow demoTableRow = new TableRow(this);
            TextView tv_l = new TextView(this);
            TextView tv_r = new TextView(this);
                    
            tv_l.SetPadding(3, 3, 3, 3);
            tv_r.SetPadding(3, 3, 3, 3);
            tv_r.Gravity = GravityFlags.Right;
            tv_l.SetTextSize(Android.Util.ComplexUnitType.Px, 9);

            tv_l.Text = xn["code"].InnerText.Trim() + 
                "-" + xn["exchange"].InnerText.Trim();
            tv_r.Text = "(" + xn["change"].InnerText.Trim() + 
                ") " + xn["last"].InnerText.Trim( );
            demoTableRow.Clickable = true;
            demoTableRow.Click += (sender, e) =>
            {
                doRowClick(sender);
            };
            demoTableRow.AddView(tv_l);
            demoTableRow.AddView(tv_r);
            tablelayout.AddView(demoTableRow);
            View vLineRow = new View(this);
            vLineRow.SetMinimumHeight(1);
            vLineRow.SetBackgroundColor(Color.Rgb(88, 88, 88));
            tablelayout.AddView(vLineRow);
        }
    }
}

The code we will be concentrating on is the part where we dynamically create TableView controls. TableView is just like a Table we use in HTML.

TableView contains TableRows. Each Table Row contains TextView

C#
TableRow demoTableRow = new TableRow(this);
TextView tv_l = new TextView(this);
TextView tv_r = new TextView(this);
tv_l.Text = "Column 1 data";
tv_r.Text = "Column 2 data"
//here we are adding TextView to TableRow
demoTableRow.AddView(tv_l);
demoTableRow.AddView(tv_r);
//add TableRow control to the Layout we define in MarketWatch.axml
tablelayout.AddView(demoTableRow);

The only tricky part here is to create a Click Event Handler for the TableView control. Remember, we can have multiple TableRows in a TableLayout. Each stock script saved in the database will create one row. So, if we have 20 stock scripts, we will be creating 20 odd Rows by using a "for loop". To attach an event handler (OnClick) to the TextView,

C#
demoTableRow.Clickable = true;
demoTableRow.Click += (sender, e) =>
{ 
    doRowClick(sender);
}
 
private void doRowClick(object Sender)
{
    TableRow tr = Sender as TableRow;
    if (tr != null)
    {
        TextView v = tr.GetChildAt(0) as TextView;
        string _script = v.Text.Trim();
        int _index = _script.IndexOf('-');
        if (_index >

You have probably noticed I used Intent to pass a value from one Activity to another.

Intent provides a facility for performing late runtime binding between the code in different applications. Its most significant use is in the launching of activities, where it can be thought of as the glue between activities. It is basically a passive data structure holding an abstract description of an action to be performed.

So in the StockDetails Activity, we will get the value that we pass from MarketWatch Activity. In brief, when we click a row, we pass the sender to the custom method. From sender, we get the TextView Control and get the "Stock Name". We then pass the value of the Stock Name to another Activity - "Stock Details Activity" where we will again talk to Web Service to fetch detailed values of the stock.

Image 13

Now we have a look into "MarketWatch.axml" - Layout for Market Watch. The only concerned part in the Layout is to design a TextView at the top left and a refresh the icon at the top right

Using RelativeLayout will solve our problem of placing two controls side by side.

XML
<RelativeLayout
    android:layout_width="fill_parent"
    android:background="@color/medium_gray"
    android:layout_height="30dp"
    android:paddingTop="3dip">
    <TextView
        android:id="@+id/symbolcaption"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:textColor="@android:color/white"
        android:background="@color/medium_gray"
        android:layout_marginLeft="0px"
        android:paddingTop="2px" />
    <ImageView
        android:id="@+id/buttonRefresh"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:lines="1"
        android:clickable="true"
        android:src="@drawable/refresh_icon" />
    <ImageView
        android:id="@+id/buttonHome"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_margin="24dip"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:clickable="true"
        android:src="@drawable/home_icon" />
</RelativeLayout>

Let's recapitulate, what's this "@drawable/refresh" in the ImageView Tag? When you dd a Refresh icon, a line is generated automatically in Drawable Class in Resource.Designer.cs

C#
public partial class Drawable
{
    // aapt resource value: 0x7f020000
    public const int refresh = 2130837504;
        .......
}

So we have seen how to pass a value from one Activity to another Activity. In the StockDetails Activity, we will see how we get the value that we pass from the MarketWatch Activity. We also have a fair idea of how to create Controls dynamically.

Second Step - Build Stock Detail View Using a Press/Touch

In the screen above, you will probably have noticed that the value we pass from the MarketWatch Activity is to send to Web Service to get the stock details. Let's look at the code. How will we get the variable and pass it to Web Service to get the XML?

First, you need to create a New Activity from "Add > Add Item > Activity". Name the file "StockDetailsActivity.cs"

C#
_script = Intent.GetStringExtra("Script");
if (_script == string.Empty)
{
    var t = Toast.MakeText(this, "Invalid Script...", ToastLength.Long);
    t.SetGravity(GravityFlags.Center, 0, 0);
    t.Show();
    return;
}
ImageView btnRefresh = FindViewById<ImageView>(Resource.Id.buttonRefresh);
btnRefresh.Click += (sender, e) =>
{
    if (!IsLoading)
    {
        ProgressDialog progress = ProgressDialog.Show(this, 
            "", "Loading Quote...", true);
        new Thread(new ThreadStart(() =>
        {
            this.RunOnUiThread(() =>
            {
                doLoadDetails();
                progress.Dismiss();
            });
        })).Start();
        IsLoading = false;
    }
};
ImageView btnHome = FindViewById<ImageView>(Resource.Id.buttonHome);
btnHome.Click += (sender, e) =>
{
    StartActivity(typeof(MarketWatchActivity));
    return;
};
ProgressDialog progressMain = ProgressDialog.Show(this, 
    "", "Loading Quote...", true);
new Thread(new ThreadStart(() =>
{
    this.RunOnUiThread(() =>
    {
        doLoadDetails();
        progressMain.Dismiss();
    });
})).Start();

I hope you have found how we get the value from Indent.

C#
_script = Intent.GetStringExtra("Script");
if (_script == string.Empty)
{
    var t = Toast.MakeText(this, "Invalid Script...", ToastLength.Long);
    t.SetGravity(GravityFlags.Center, 0, 0);
    t.Show();
    return;
}

Intent.GetStringExtra("Script") will return the value that we pass from the previous Activity. We will do a simple check before passing the value to Web Service to pull the real time stock data.

What is a Toast?

A toast is a view containing a quick little message for the user. We use "Toast" to display any information or warning message. The text appears for some time and then vanishes so that users can have a good idea of what is going on with the application.

Now we will see how we pass the stock name or script name to a Web Service and pull the XML and show the data in TableView Controls. This part is very similar to Market Watch.

C#
//conecting to webservice and get the xml
string strXML = string.Empty;
stockwebservice.StockWebservice quoteObject = null;
try
{
    quoteObject = new stockwebservice.StockWebservice();
    strXML = quoteObject.GetStockQuote(_script);
}
finally
{
    quoteObject.Dispose();
    quoteObject = null;
}
//if error occurred while connect8ing to web service
if (strXML.Substring(0, 5) == "error")
{
    var t = Toast.MakeText(this, 
    "Error connecting to web service. Please check your Internet connection...", ToastLength.Short);
    t.SetGravity(GravityFlags.Center, 0, 0);
    t.Show();
    return;
}
if (strXML.ToLower() == "exception")
{
    var t = Toast.MakeText(this, 
    "Service not available now. Please try after sometime...", ToastLength.Short);
    t.SetGravity(GravityFlags.Center, 0, 0);
    t.Show();
    return;
}
LinearLayout stockdetailsLinearLayout = FindViewById<LinearLayout>(Resource.Id.linearLayoutstockdetails);
symbolCaption = FindViewById<TextView>(Resource.Id.symbolcaption);
symbolCaption.SetTextAppearance(this, Resource.Style.boldText);
priceCaption = FindViewById<TextView>(Resource.Id.pricecaption);
priceCaption.SetTextAppearance(this, Resource.Style.boldText19);
changeCaption = FindViewById<TextView>(Resource.Id.changecaption);
changeCaption.SetTextAppearance(this, Resource.Style.boldText19);

datetimeCaption = FindViewById<TextView>(Resource.Id.datetimecaption);
datetimeCaption.SetTextAppearance(this, Resource.Style.smallText);
//load the xml to XmlDocument
XmlDocument doc = new XmlDocument();
doc.LoadXml(strXML);
XmlNodeList xnList = doc.SelectNodes("/stock/symbol");
foreach (XmlNode xn in xnList)
{
    data[0, 0] = "Symbol";
    data[0, 1] = xn["code"].InnerText.Trim();
    data[1, 0] = "Name";
    data[1, 1] = xn["company"].InnerText.Trim();
    symbolCaption.Text = xn["company"].InnerText.Trim();
    datetimeCaption.Text = DateTime.Now.ToString("dd-MM-yyyy hh:mm:ss");
    priceCaption.Text = xn["last"].InnerText.Trim() + " " + 
        xn["currency"].InnerText.Trim();
    changeCaption.Text = xn["change"].InnerText.Trim();
    View vLinePrice = new View(this);
    vLinePrice.SetMinimumHeight(2);
    vLinePrice.SetBackgroundColor(Color.Rgb(164, 164, 164));
    stockdetailsLinearLayout.AddView(vLinePrice);
    data[2, 0] = "Exchange";
    data[2, 1] = xn["exchange"].InnerText.Trim();
    data[3, 0] = "Open";
    data[3, 1] = xn["open"].InnerText.Trim();
    data[4, 0] = "Day's High";
    data[4, 1] = xn["high"].InnerText.Trim();
    data[5, 0] = "Day's Low";
    data[5, 1] = xn["low"].InnerText.Trim();
    data[6, 0] = "Change";
    data[6, 1] = xn["change"].InnerText.Trim();
    data[7, 0] = "Change %";
    data[7, 1] = xn["changepercent"].InnerText.Trim();
    data[8, 0] = "Volume";
    data[8, 1] = xn["volume"].InnerText.Trim();
    data[9, 0] = "Previous Close";
    data[9, 1] = xn["previousclose"].InnerText.Trim();
    data[10, 0] = "Trade Time";
    data[10, 1] = xn["tradetime"].InnerText.Trim();
    data[11, 0] = "Market Capital";
    decimal marketcapital = 0;
    if (decimal.TryParse(xn["marketcapital"].InnerText.Trim(), out marketcapital))
        data[11, 1] = string.Format("{0:#,0}", marketcapital);
    else
        data[11, 1] = xn["marketcapital"].InnerText.Trim();

    TableLayout tableLayout = FindViewById<TableLayout>(Resource.Id.deatlLayout);
    tableLayout.RemoveAllViews();
    tableLayout.RefreshDrawableState();
    for (int i = 2; i < 12; i++)
    {
        // add all inforamation to your tablerow in such a maaner that you want to display on screen.
        TableRow demoTableRow = new TableRow(this);
        TextView tv_l = new TextView(this);
        TextView tv_r = new TextView(this);
        tv_l.SetPadding(3, 3, 3, 3);
        tv_r.SetPadding(3, 3, 3, 3);
        tv_r.Gravity = GravityFlags.Right;
        tv_l.Text = data[i, 0];
        tv_r.Text = data[i, 1];
        demoTableRow.AddView(tv_l);
        demoTableRow.AddView(tv_r);
        if (i == 0)
        {
            tv_l.SetTextAppearance(this, Resource.Style.boldText);
        }

        tableLayout.AddView(demoTableRow);
        View vLineRow = new View(this);
        vLineRow.SetMinimumHeight(1);
        vLineRow.SetBackgroundColor(Color.Rgb(88, 88, 88));
        tableLayout.AddView(vLineRow);
    }
}

The code is self explanatory and there's not much detail to it. I would rather explain the refresh icon functionality, which when clicked or touched, refreshes the view. We will also show a "loading message" the time the application does the background process of calling the web service, pulling the XML data and creating the view with the data. "Refresh" is also done in Market Watch, but I thought it would be nicer to explain that a bit later after understanding - "calling of web service" and "creating controls dynamically".

C#
ImageView btnRefresh = FindViewById<ImageView>(Resource.Id.buttonRefresh);
btnRefresh.Click += (sender, e) =>
{
    if (!IsLoading)
    {
        ProgressDialog progress = ProgressDialog.Show(this, "", "Loading Quote...", true);
        new Thread(new ThreadStart(() =>
        {
            this.RunOnUiThread(() =>
            {
                doLoadDetails();
                progress.Dismiss();
            });
        })).Start();
        IsLoading = false;
    }
};

We will be using a new thread to run the method doLoadDetails(). Before that we will use one extra thing, ProcessDialog. A progress dialog is part of the Android API and can be used to display either a progress bar or a spinning progress symbol.

So, the basic idea is to show the process dialog first. Then start a new Thread and Run the Method within that thread. Once the method executes, we will Dismiss the process using progress.Dismiss().

Third Step - View Stock Chart from Action Bar - Menu

When we are talking about Market Watch, it would not be fair if we don't provide Chart option to user. Users are quite often interested in viewing charts for different Parameters to understand the Stock Movement Trend.

Image 14

What are the Chart Parameters?

  • 1 Day
  • 5 Days
  • 3 Months
  • 6 Months
  • 1 Year
  • 2 Years
  • 5 Years

The Web Method - "GetStockChart" expects two input parameters - Stck Code and Chart Parameters. The method will return the chart image as byte array. Let's look at the code,

C#
byte[] image_data;
stockwebservice.StockWebservice quoteObject = null;
try
{
    quoteObject = new stockwebservice.StockWebservice();
    image_data = quoteObject.GetStckChart(_stock, _type);
}
finally
{
    quoteObject.Dispose();
    quoteObject = null;
}

So, we have now the byte array and how simple it is to convert the byte array to ImageView Control.

C#
//convert byte array to image
Bitmap bitmapChart = BitmapFactory.DecodeByteArray(image_data, 0, image_data.Length);
imgChart.SetImageBitmap(bitmapChart);
imgChart.SetBackgroundResource(Resource.Color.transparent); 

Now, we need to place seven buttons and add onClick Handler which when clicked will call the web method - StockGetChart with the different chart parameters.

C#
btn1D.Click += (sender, e) => { doLoadChart(sender, "1D"); };
btn5D.Click += (sender, e) => { doLoadChart(sender, "5D"); };
btn3M.Click += (sender, e) => { doLoadChart(sender, "3M"); };
btn6M.Click += (sender, e) => { doLoadChart(sender, "6M"); };
btn1Y.Click += (sender, e) => { doLoadChart(sender, "1Y"); };
btn2Y.Click += (sender, e) => { doLoadChart(sender, "2Y"); };
btn5Y.Click += (sender, e) => { doLoadChart(sender, "5Y"); };

In the above method "doLoadChart" calls the Web Method - GetStckChart" and return image as byte array. Have a look into the web service code, how image is converted to byte array and send back to client. We will run the method in a Thread to show the Process Dialog till the image is fully loaded in the ImageView Control.

Now before going to the next step, let's have a quick look into the Stock Chart Layout (StckChart.axml)

C#
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:minWidth="25px"
    android:minHeight="25px">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="28dp"
        android:id="@+id/linearLayoutstockdetails"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="4dp">
        <TextView
            android:id="@+id/stockchartcaption"
            android:layout_width="206dp"
            android:layout_height="fill_parent"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:textColor="@android:color/white"
            android:removed="#000000"
            android:layout_marginLeft="0px"
            android:textSize="14dp"
            android:textStyle="bold"
            android:paddingTop="2dp"
            android:layout_gravity="center_horizontal" />
        <Button
            android:text="1D"
            android:layout_width="28dp"
            android:layout_height="18dp"
            android:textSize="12dp"
            android:id="@+id/button1D"
            android:textColor="#ffffff"
            android:padding="3dp"
            android:background="#1C1C1C"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="4dp"
            android:layout_marginRight="2dp"
            android:layout_marginLeft="6dp" />
        <Button
            android:text="5D"
            android:layout_width="28dp"
            android:layout_height="18dp"
            android:textSize="12dp"
            android:textColor="#ffffff"
            android:padding="3dp"
            android:background="#1C1C1C"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="4dp"
            android:layout_marginRight="2dp"
            android:id="@+id/button5D" />
        <Button
            android:text="3M"
            android:layout_width="28dp"
            android:layout_height="18dp"
            android:textSize="12dp"
            android:textColor="#ffffff"
            android:padding="3dp"
            android:background="#1C1C1C"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="4dp"
            android:layout_marginRight="2dp"
            android:id="@+id/button3M" />
        <Button
            android:text="6M"
            android:layout_width="28dp"
            android:layout_height="18dp"
            android:textSize="12dp"
            android:textColor="#ffffff"
            android:padding="3dp"
            android:background="#1C1C1C"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="4dp"
            android:layout_marginRight="2dp"
            android:id="@+id/button6M" />
        <Button
            android:text="1Y"
            android:layout_width="28dp"
            android:layout_height="18dp"
            android:textSize="12dp"
            android:textColor="#ffffff"
            android:padding="3dp"
            android:background="#1C1C1C"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="4dp"
            android:layout_marginRight="2dp"
            android:id="@+id/button1Y" />
        <Button
            android:text="2Y"
            android:layout_width="28dp"
            android:layout_height="18dp"
            android:textSize="12dp"
            android:textColor="#ffffff"
            android:padding="3dp"
            android:background="#1C1C1C"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="4dp"
            android:layout_marginRight="2dp"
            android:id="@+id/button2Y" />
        <Button
            android:text="5Y"
            android:layout_width="28dp"
            android:layout_height="18dp"
            android:textSize="12dp"
            android:textColor="#ffffff"
            android:padding="3dp"
            android:background="#1C1C1C"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="4dp"
            android:layout_marginRight="2dp"
            android:id="@+id/button5Y" />
    </LinearLayout>
    <ImageView
        android:id="@+id/imageChart"
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:clickable="true"
        android:layout_marginTop="2dp" />
</LinearLayout>

If you see the TextView and the buttons for showing different charts are kept in a LinearLayout with orientation:horizontal. We have already discussed, placing controls in a Linearayout (orientation:horizontal) simply means the control will be placed side by side.

One vital information, I missed in the beginning of this section is we will be forcing the screen to be viewed in Landscape. As the chart will not be best fitted in portrait, we will be forcing the screen to be opened in Landscape.

The simple trick for doing this,

C#
[Activity(Label = "Stock Chart", ScreenOrientation = Android.Content.PM.ScreenOrientation.Landscape)] 

Forth Step - Add Custom Stock to SQLite Database 

In this Activity we will be adding Stock to SQLite Database. The stocks that are added will be shown in summary in Market Watch and detail in StockDetails Activity.

Let's focus on the screen first.

Add Stock Layout

The Layout for AddStock Activity is pretty simple. Have a look into the AddStock Layout

XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/linearLayout1">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Enter the full Stock Symbol for your exchange. Valid Stock will be added only."
        android:layout_marginTop="36px"
        android:layout_marginBottom="14px"
        android:layout_marginLeft="8px"
        android:textSize="13sp"
        android:layout_marginRight="8px" />
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="40px"
        android:id="@+id/textStock"
        android:textColor="@android:color/black"
        android:hint="Enter Stock Symbol"
        android:layout_marginLeft="8px"
        android:layout_marginBottom="12px"
        android:layout_marginRight="80px"
        android:padding="4px"
        android:textColorHint="#323232"
        android:textSize="15sp" />
    <Button
        android:id="@+id/buttonAddStock"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Add Stock..."
        android:layout_marginLeft="8px" />
</LinearLayout>
As we are placing the controls one after another, we only need a Linear Layout orientation "Vertical". We have primarily three controls,
  • TextView
  • EditText
  • Button 
You have probably noticed that some padding has been given to get the spacing between each control.  One thing I will stress here is the Hint, i.e. a grayed-out text within the EditText control. This is something like the "placeholder" attribute of a input text in HTML. While designing the screen layout in a mobile device we need to be very sure about the spaces. We don't have too many spaces in a screen to fit all controls. So Hint is often used in Mobile where we get rid of one extra control to let the user identify what the EditText does.
android:hint="Enter Stock Symbol"
android:textColorHint="#323232"

AddStock Activity Class

We will do some basic validation while we click the Add button. Then we will check whether the stock script the user enters is a valid script. If it is not a valid script, we need to display the Message in a Torch. The last important validation is we need to ensure that users don't add duplicate stock. So, we will check whether the Stock Script entered exists in the database. 
C#
private bool doCheckStockScript(string _stockscript)
{
    //conecting to webservice and get the xml
    string strXML = string.Empty;
    stockwebservice.StockWebservice quoteObject = null;
    try
    {
        quoteObject = new stockwebservice.StockWebservice();
        strXML = quoteObject.StockExists(_stockscript);
    }
    finally
    {
        quoteObject.Dispose();
        quoteObject = null;
    }
    //if error occurred while connect8ing to web service
    if (strXML.Substring(0, 5) == "error")
    {
        var t = Toast.MakeText(this, 
        "Error connecting to web service. Please check your Internet connection...", 
        ToastLength.Short);
        t.SetGravity(GravityFlags.Center, 0, 0);
        t.Show();
        return false;
    }
    if (strXML.ToLower() == "exception")
    {
        var t = Toast.MakeText(this, 
        "Service not available now. Please try after sometime...", ToastLength.Short);
        t.SetGravity(GravityFlags.Center, 0, 0);
        t.Show();
        return false;
    }
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(strXML);
    XmlNodeList xnList = doc.SelectNodes("/stock/symbol");
    foreach (XmlNode xn in xnList)
    {
        if (xn["exchange"].InnerText.Trim().ToUpper() == "NA")
            return false;
    }
    return true;
}
private bool AddStockScript(string _stockscript)
{
    bool Ok = false;
    StockManager.Message = string.Empty;
    Ok = StockManager.SaveStock(_stockscript);
    if (StockManager.Message != string.Empty)
    {
        var t = Toast.MakeText(this, StockManager.Message, ToastLength.Short);
        t.SetGravity(GravityFlags.Center, 0, 0);
        t.Show();
    }
    return Ok;
}
Once added successfully we will show a quick message in "Toast" and return back to Market Watch Activity.

Fifth Step - Get Stock Details  

Get Stock Details is a customized search of a Stock. The user will enter the script and press the "Get Stock" button and the stock Quote details are displayed on the screen. Here is a screen shot of how Get Stock looks after fetching stock data. In the example I have used script "GOOG" which is the Stock Script of Google Inc. 

Image 16

Let's look at the GetStockActivity class:

C#
private bool IsLoading = false;
protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    View titleView = Window.FindViewById(Android.Resource.Id.Title);
    //update the default title
    if (titleView != null)
    {
        IViewParent parent = titleView.Parent;
        if (parent != null && (parent is View))
        {
            View parentView = (View)parent;
            parentView.SetBackgroundColor(Color.Rgb(28, 28, 28));
            parentView.SetMinimumHeight(32);
            parentView.SetMinimumHeight(32);
        }
    }
    // Set our view from the "main" layout resource
    SetContentView(Resource.Layout.GetStock);
    ImageView btnHome = FindViewById<ImageView>(Resource.Id.buttonHomeget);
    btnHome.Click += (sender, e) =>
    {
        StartActivity(typeof(MarketWatchActivity));
        return;
    };
    EditText textStock = FindViewById<EditText>(Resource.Id.textGetStock);
    Button btnGetStock = FindViewById<Button>(Resource.Id.buttonGetStock);
    btnGetStock.Click += (sender, e) =>
    {
        if (textStock.Text == string.Empty)
        {
            //message if no text is entered in script
            var t = Toast.MakeText(this, "Please eneter Stock Script", ToastLength.Short);
            t.SetGravity(GravityFlags.Center, 0, 0);
            t.Show();
            textStock.Focusable = true;
            return;
        }
        //check script from webservice to see, if it is a valid script
        if (doCheckStockScript(textStock.Text.Trim()))
        {
            ProgressDialog progressMain = ProgressDialog.Show(this, "", "Loading Quote...", tru                   e);
            new Thread(new ThreadStart(() =>
            {
                //Thread.Sleep(4 * 1000);
                this.RunOnUiThread(() =>
                {
                    doLoadDetails(textStock.Text.Trim());
                    progressMain.Dismiss();
                });
            })).Start();
        }
        else
        {
            //message if no text entered is not a valid script
            var t = Toast.MakeText(this, "You have eneterd invalis Stock Script. Please eneter a valid Stock Script", ToastLength.Short);
            t.SetGravity(GravityFlags.Center, 0, 0);
            t.Show();
            textStock.Focusable = true;
            return;
        }
    };
}
private bool doCheckStockScript(string _stockscript)
{
     //check, if the stock script is Valid 
}
protected void doLoadDetails(string _script)
{
     //connect to web service to pull the real time stock data and display the result on the screen 
}

Nothing much to explain in details. If you look at the method "doCheckStockScript()", it checks the validity of the stock script entered. If the script entered is invalid, a message will pop out using "Toast".

Wrapping up the Application 

So we have almost covered all areas, but there are a few things I didn't discuss earlier in the article, so I will discuss them now. Did you thought while going through the discussion, how we navigate from one page to another (apart from Home icon at the top right)?

There are several ways we follow for the navigation. But depending on the application requirement, I will be using "OptionMenu" to be visible in Action Bar to navigate or jump from one Activity to another.

Image 17

C#
public override bool OnCreateOptionsMenu(IMenu menu)
{
    menu.Add("Get Quote").SetIcon(Resource.Drawable.ic_stock_get); ;
    menu.Add("Add Stock").SetIcon(Resource.Drawable.ic_quote_add);
    menu.Add("Delete Stocks").SetIcon(Resource.Drawable.ic_stock_delete);
    return true;
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
    switch (item.TitleFormatted.ToString())
    {
        case "Delete Stocks":
            doDeleteStocks(); break;
        case "Add Stock":
            doOpenAddStock(); break;
        case "Get Quote":
            doOpenGetStock(); break;
    }
    return base.OnOptionsItemSelected(item);
}
//delete all saved stocks from database 
protected void doDeleteStocks()
{
    StockManager.DeleteAllStocks();
    if (!IsLoading)
    {
        ProgressDialog progress1 = ProgressDialog.Show(this, "", "Deleting Stock...", true);
        new Thread(new ThreadStart(() =>
        {
            this.RunOnUiThread(() =>
            {
                doLoadMarketWatch();
                progress1.Dismiss();
            });
        })).Start();
        IsLoading = false; 
    };
}
protected void doOpenAddStock()
{
    StartActivity(typeof(AddStockActivity));
}
protected void doOpenGetStock()
{
    StartActivity(typeof(GetStockActivity));
}

We are overriding the method OnCreateOptionsMenu(IMenu menu). We will use "menu" to create menu items in Action Bar.

IMenu is an interface which exposes three important methods - Add, AddMenu, AddSubMenu. We can further enhance the menu building in an Android application depending upon the requirements.

You are Done - Building Professional Android Application 

You have now completed building Professional Android applications. Even though we've only covered a small part of the features and controls I have used in this application, it is within everyone's ability to build upon and enhance their skills to the level of "professional Android developer." This article will give you a fair idea how to create a professional Android application using C# and Visual Studio 2010.

The last step is how you run and test the application. Like all device applications we can run the application in an emulator before installing it into the actual device. In the next section I will describe how to deploy and run the application in the emulator.

Deploy and Run the Application 

After you build successfully, go to Debug>Start without Debugging. You can use also Start with Debugging, if you need to debug. Once you click "Start" a window will appear, where you need to select "Start emulator image".

Image 18

The API Version denotes the Targeted device - supported Android Version  I will be selecting API 10, means the Android version supported is 2.3.

Once you select the version and continue, you will find a screen below:

Select Emulator

Click "OK" to continue. It will take some time estimated 1 minute to 4 minutes depending upon your Processor speed. So, I would suggest keeping open the emulator while you work with coding. This will save your valuable time. Once the Emulator loads the Activity, it will look like: 

Running COINS in Emulator

Note: Though it is free to run and test the application free in Emulator, you need a License to install the application to the physical device. 

Important Notes on Mono Android SDK 

The Application is built on Mono Android SDK for Visual Studio 2010. For Visual Studio 2012, you can download the Mono Android from this link: Install Mono for Android SDK (Visual Studio 2012).

Please note: If you want to run the application in 2012, you need to convert it to VS 2012 and use the right sdk.

Future Scope    

Mobile, iPad, and Tablet PCs are gaining popularity day by day. We are not at all restricted to gaming applications only. We can create powerful business applications for Small/Medium/Enterprise. It is possible to build applications in all the above devices using Mono C#. Apple uses their own O/S iOS. MonoTouch supports C# for writing professional application using Mono C#.

We are already developing Windows Mobile applications in .NET. So, in conclusion, Visual Studio(C#) is the language we can explore to develop cross platform applications in almost all the above devices in today's market.

Comments    

Your comments are valuable. I would highly appreciate to have your comments, suggestions and feedbacks. I'll try to be as responsive as I can.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)