Monday, December 29, 2014

Integrating Google AdMob with Banner in Android Applications


Overview :

AdMob brings together best-in-class technology in a single platform, so you can gain insights about your users, drive more in-app purchases, and maximize your ad revenue. No longer will you have to rely on a combination of tools or use precious development resources to build your own solution.

Step 1 :

First we add an account in AdMob publisher and Identify your publisher ID on the top right of your dashboard. Click here to sign up the AdMob publisher.

Step 2 :

Create a new project in Eclipse File ⇒ New ⇒ Android Application Project. Fill in the details and name your project AdmobProject.

Step 3 :

Here is a complete example of MainActivity.java


package com.sampleadmob;

import android.app.Activity;

import android.os.Bundle;

import com.google.android.gms.ads.AdListener;

import com.google.android.gms.ads.AdRequest;

import com.google.android.gms.ads.AdView;

import com.google.android.gms.ads.InterstitialAd;

public class MainActivity extends Activity {

private InterstitialAd interstitial;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

interstitial = new InterstitialAd(MainActivity.this);

// Insert the Ad Unit ID

interstitial.setAdUnitId("ca-app-pub-xxxxxxxxxxxx/xxxxxxxxxx");

AdView adView = (AdView) this.findViewById(R.id.adView);

AdRequest adRequest = new AdRequest.Builder().build();

adView.loadAd(adRequest);

interstitial.loadAd(adRequest);

interstitial.setAdListener(new AdListener() {

public void onAdLoaded() {

displayAd();

}

});

}

public void displayAd() {

// If Ads are loaded, show Interstitial else show nothing.

if (interstitial.isLoaded()) {

interstitial.show();

}

}

}


Step 4 :

In activity_main.xml we declare this

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

xmlns:ads="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context="com.example.sampleadmob.MainActivity" >

<com.google.android.gms.ads.AdView

android:id="@+id/adView"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

ads:adSize="BANNER"

// Insert the Ad Unit ID

ads:adUnitId="ca-app-pub-xxxxxxxxxxxxx/xxxxxxxx" />

</RelativeLayout>


Step 5 :

In Android manifest file we declare permissions to allow the internet connection and network state and declare activity for Google play services.


Declare Google services activity :

<meta-data

android:name="com.google.android.gms.version"

android:value="@integer/google_play_services_version" />

<activity

android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" >

</activity>


Internet and network state permission :


<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>


Screenshot :

 


Baalaji is a Software Engineer at Span Technology Services

Read More »

Object Dumper


Overview :

Object Dumper is used on your object to dump the result to the console. Sometimes we can't show the desired result on the console or for logging. I have used the Employee class to represent the working behavior of the Object Dumper class. Have a look at the class structure and the implementation as shown below:


LINQ-with-Object-Dumper.jpg


When I run the preceding code segment it shows me the error displayed below:


run-LINQ-with-Object-Dumper.jpg


Note: The reason for showing the error above is the ObjEmp object has multiple values in a collection.Even in Immediate window we can't see all the values in ObjEmp





Or while hovering on the object we have to keep on expanding the nodes to see the values it will be hectic for bigger List object.





To resolve this issue we have the Object Dumper class: 


Object-Dumper-class.jpg 

 
The Object Dumper class gives you the desired result as shown here:



output-Object-Dumper-class.jpg 


To use this we have to include a "ObjectDumper.cs" file to our solution and call the " ObjectDumper.Write(z1);" method from our code and it will write the output to console. It's a good debugging approach that can be used in Linq that we use everyday to see the records that we fetch from DB.


Sample Program : Console Application 

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Collections;
namespace Program
{
    public class Employee
    {
        public string EmpID { get; set; }
        public string Name { get; set; }
        public int YearOfJoining { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("With List Collections");
            List ObjEmp = new List
            {
                new Employee{ EmpID = "E001", Name = "Sachin", YearOfJoining = 2006},
                new Employee { EmpID = "E002", Name = "Rohit", YearOfJoining = 2005 },
                new Employee { EmpID = "E003", Name = "Deepak", YearOfJoining = 2007 }

            };
            //Console.WriteLine("Employee ID = {0}, Name = {1}, YearOfJoining = {2}", ObjEmp.EmpID, ObjEmp.Name, ObjEmp.YearOfJoining);
            //Console.ReadLine();

            ObjectDumper.Write(ObjEmp, 2);
            Console.ReadLine();
            Console.WriteLine("With Xml to Array List");

            string xml = "12";
            ArrayList arrayList = new ArrayList();
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            XmlNodeList idNodes = doc.SelectNodes("Ids/id");
            foreach (XmlNode node in idNodes)
                arrayList.Add(node.InnerText);

            ObjectDumper.Write(arrayList, 2);
            Console.ReadLine();
            Console.WriteLine("With XML to List");

            string xmltoList = "12";
            XDocument docList = XDocument.Parse(xmltoList);

            List list = docList.Root.Elements("id")
                               .Select(element => element.Value)
                               .ToList();
            Console.WriteLine("simplest use");

            var z = new
            {
                A = "1",
                B = "2"
            };

            ObjectDumper.Write(z);
            Console.ReadLine();
            Console.WriteLine(" nested collections");

            var z1 = new
            {
                Aaa = "Hello",
                Bbb = "There",
                Ccc = new[] { 1, 2, 3 }
            };

            ObjectDumper.Write(z1);
            Console.ReadLine();
            Console.WriteLine("within nested collections");

            var z2 = new
            {
                Aaa = "Hello",
                Bbb = "There",
                Ccc = new[] { 1, 2, 3 }
            };
            ObjectDumper.Write(z2, 1);
            Console.ReadLine();
        }
    }
}

ObjectDumper.cs - Code

using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;

// See the ReadMe.html for additional information
public class ObjectDumper {

    public static void Write(object element)
    {
        Write(element, 0);
    }

    public static void Write(object element, int depth)
    {
        Write(element, depth, Console.Out);
    }

    public static void Write(object element, int depth, TextWriter log)
    {
        ObjectDumper dumper = new ObjectDumper(depth);
        dumper.writer = log;
        dumper.WriteObject(null, element);
    }

    TextWriter writer;
    int pos;
    int level;
    int depth;

    private ObjectDumper(int depth)
    {
        this.depth = depth;
    }

    private void Write(string s)
    {
        if (s != null) {
            writer.Write(s);
            pos += s.Length;
        }
    }

    private void WriteIndent()
    {
        for (int i = 0; i < level; i++) writer.Write("  ");
    }

    private void WriteLine()
    {
        writer.WriteLine();
        pos = 0;
    }

    private void WriteTab()
    {
        Write("  ");
        while (pos % 8 != 0) Write(" ");
    }

    private void WriteObject(string prefix, object element)
    {
        if (element == null || element is ValueType || element is string) {
            WriteIndent();
            Write(prefix);
            WriteValue(element);
            WriteLine();
        }
        else {
            IEnumerable enumerableElement = element as IEnumerable;
            if (enumerableElement != null) {
                foreach (object item in enumerableElement) {
                    if (item is IEnumerable && !(item is string)) {
                        WriteIndent();
                        Write(prefix);
                        Write("...");
                        WriteLine();
                        if (level < depth) {
                            level++;
                            WriteObject(prefix, item);
                            level--;
                        }
                    }
                    else {
                        WriteObject(prefix, item);
                    }
                }
            }
            else {
                MemberInfo[] members = element.GetType().GetMembers(BindingFlags.Public | BindingFlags.Instance);
                WriteIndent();
                Write(prefix);
                bool propWritten = false;
                foreach (MemberInfo m in members) {
                    FieldInfo f = m as FieldInfo;
                    PropertyInfo p = m as PropertyInfo;
                    if (f != null || p != null) {
                        if (propWritten) {
                            WriteTab();
                        }
                        else {
                            propWritten = true;
                        }
                        Write(m.Name);
                        Write("=");
                        Type t = f != null ? f.FieldType : p.PropertyType;
                        if (t.IsValueType || t == typeof(string)) {
                            WriteValue(f != null ? f.GetValue(element) : p.GetValue(element, null));
                        }
                        else {
                            if (typeof(IEnumerable).IsAssignableFrom(t)) {
                                Write("...");
                            }
                            else {
                                Write("{ }");
                            }
                        }
                    }
                }
                if (propWritten) WriteLine();
                if (level < depth) {
                    foreach (MemberInfo m in members) {
                        FieldInfo f = m as FieldInfo;
                        PropertyInfo p = m as PropertyInfo;
                        if (f != null || p != null) {
                            Type t = f != null ? f.FieldType : p.PropertyType;
                            if (!(t.IsValueType || t == typeof(string))) {
                                object value = f != null ? f.GetValue(element) : p.GetValue(element, null);
                                if (value != null) {
                                    level++;
                                    WriteObject(m.Name + ": ", value);
                                    level--;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private void WriteValue(object o)
    {
        if (o == null) {
            Write("null");
        }
        else if (o is DateTime) {
            Write(((DateTime)o).ToShortDateString());
        }
        else if (o is ValueType || o is string) {
            Write(o.ToString());
        }
        else if (o is IEnumerable) {
            Write("...");
        }
        else {
            Write("{ }");
        }
    }
}
 

Finally the Object Dumper is an .NET object and dumps the object into a TextWriter, string or file and dumps the elements of sequences (arrays, lists, dictionaries, etc.). It is mainly used for debugging purpose for complex type objects.


Amala N is a Junior Software Engineer at Span Technology Services

Read More »

Tuesday, December 23, 2014

Why a good bug reporting is important for QA?

1. Prioritize a Bug
BUG Life cycle
Figure: BUG Life cycle

QA should learn to Prioritize the bugs by identifying the most important bugs in the initial stage, helping the company or developer make sense of the bugs is ten times more helpful then testing for mere volume.

2. Learn from a mistake

Everyone makes mistake, but learning from others and from your own mistakes will make you better tester. Ask questions to yourself!
  • -How can you improve your bug report next time?
  • -How can you prioritize better during the next test cycle?
  • -How can you communicate better with the development team?

3. Do not assume

Don’t think in the mind before going for testing that “Oh, I know this software well” or “I’ve used this before” are at risk of overlooking important bugs. Test with an open mind; look at the software from the User Perspective.

4. Question everything

  • -Does this work as intended?
  • -Does it work on all devices?
  • -Does it work under every possible use-case, every time?
  • -Why is it like this?
  • -Can it be better?

5. Think like an user

Before the Product reaches to the User – Think like a User and test, Pair your technical skills with an end-user’s mindset and you will find the best, most valuable bugs possible.

6. Report it clearly

Attaching screen shots and providing detailed bug reports will give the developer the information he or she needs to understand the bug and fix i.e. bug report should contain

  • -Where did it occur? 
  • -When it occur?
  • -How many times?
  • -On what devices?
  • -Which operating system?
  • -Under what circumstances?

Provide every possible detail/information will help the developers to make it easy to understand the issue.

7. Distinguish Average Bug Report vs Good Bug Report

  •  -If your bug is not reproducible it will never get fixed. You should mention clearly a step by step way to reproduce the bug.
  •  -Be Specific on creating a bug and do not write unnecessarily long description about the problem. Try to summarize the problem in minimum words. 
  • -Reproduce the bug three times before raising a Bug.

A good bug report will always help the developers to solve the problem easy. Through this way we can avoid misunderstanding problems from both sides
.
Read More »

Monday, December 22, 2014

Place Auto complete Using Google places API

Overview 


The Google Places Autocomplete API is a web service that returns Place information based on text search terms and, optionally, geographic bounds. The API can be used to provide autocomplete functionality for text-based geographic searches, by returning Places such as businesses, addresses, and points of interest as a user types.

private static final String LOG_TAG = ExampleApp";
private static final String PLACES_API_BASE = "https://maps.googleapis.com/maps/api/place";
private static final String TYPE_AUTOCOMPLETE = "/autocomplete";
private static final String OUT_JSON = "/json";
private static final String API_KEY = "YOUR_API_KEY";
private ArrayList autocomplete(String input) {
ArrayList resultList = null;
HttpURLConnection conn = null;
StringBuilder jsonResults = new StringBuilder();
try {
StringBuilder sb = new StringBuilder(PLACES_API_BASE +
TYPE_AUTOCOMPLETE + OUT_JSON);
sb.append("?key=" + API_KEY);
sb.append("&amp;components=country:uk");
sb.append("&amp;input=" + URLEncoder.encode(input, "utf8"));
URL url = new URL(sb.toString());
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
// Load the results into a StringBuilder
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
jsonResults.append(buff, 0, read);
}
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error processing Places API URL", e);
return resultList;
} catch (IOException e) {
Log.e(LOG_TAG, "Error connecting to Places API", e);
return resultList;
} finally {
if (conn != null) {
conn.disconnect();
}
}
return resultList;
}

 We will need a custom ListAdapter (ArrayAdapter implements the ListAdapter interface) to provide Place Autocomplete results to the AutoCompleteTextView.

private class PlacesAutoCompleteAdapter extends ArrayAdapter
implements Filterable {
private ArrayList resultList;
public PlacesAutoCompleteAdapter(Context context, int textViewResourceId)
{
super(context, textViewResourceId);
}

@Override

public int getCount() {

return resultList.size();

}

@Override

public String getItem(int index) {
return resultList.get(index);

}
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@Override

protected FilterResults performFiltering(CharSequence constraint)
{
FilterResults filterResults = new FilterResults();

if (constraint != null) {
// Retrieve the autocomplete results.
resultList = autocomplete(constraint.toString());
// Assign the data to the FilterResults
filterResults.values = resultList;
filterResults.count = resultList.size();
}
return filterResults;
}

@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
if (results != null && results.count > 0) {
notifyDataSetChanged();
}
else {
notifyDataSetInvalidated();
}
}};
return filter;
}
}

Detect when a suggestion has been selected by the user, implement the OnItemClickListener interface and assign it to the AutoCompleteTextView.

public class PlacesAutocompleteActivity extends Activity implements

OnItemClickListener {

@Override

public void onCreate(Bundle savedInstanceState) {

AutoCompleteTextView autoCompView = (AutoCompleteTextView)

findViewById(R.id.autocomplete);

autoCompView.setAdapter(new PlacesAutoCompleteAdapter(this,
R.layout.list_item));

autoCompView.setOnItemClickListener(this);

public void onItemClick(AdapterView adapterView, View view, int
position, long id) {

String str = (String) adapterView.getItemAtPosition(position);

Toast.makeText(this, str, Toast.LENGTH_SHORT).show();

}

}
To instantiate an ArrayAdapter, We must include a reference to a layout file that contains a
TextView, Which corresponds to the Android layout file res/layout/list_item.xml
<!-- res/layout/list_item.xml -->
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" />

API keys

The Place Autocomplete service is part of the Google Places API, and uses an API key to identify your application. API keys are managed through the Google APIs Console.

Read More »

Hello World! Build Your First iPhone App Using Swift

Overview

A major topic at this year's WWDC(2014) was building applications using Swift Programming Language. And then, out of the blue, Swift came along and the world will never be the same. The brand new programming language is definitely the most exciting thing announced this year and I couldn’t wait for the Xcode download to finish so I can play with it. Instead rewriting the same tutorial in Objective-C, we’ll show you how to create the  “Hello World” app in Swift. What’s more, we create a screencast for you.

When learning a new programming language you usually start from “Hello World”. Apple provided a great book for Swift and that starts precisely with “Hello World!”. You will  need to use Xcode 6 (or up) to work on the Hello World project. If you haven’t upgraded to Xcode 6.

Step 1 →  Launch Xcode. Click Create a new Xcode project and Select “single View Application”.

Step 2 → Give the Product name as “Hello World” and Choose Language “Swift”. Click the Next Button to save the project.

Screen Shot 2014-12-22 at 4.32.50 pm.png

Step 3 →  Xcode automatically creates the “Hello World” project based on all the options you provided.

Screen Shot 2014-12-22 at 4.41.46 pm.png

Xcode creates a few template files for us, AppDelegate.swift and ViewController.swift. When using Swift you don’t have headers, all the code goes in the same .swift file. We still have a storyboard file and Xcode 6 allows us to do some extra magic. Running the app now will show an empty view, so let’s start adding our own UI controls.

When opening the storyboard we will notice that the view controller created by Xcode has a different size, neither iPhone or iPad size. This is related to the extra magic that I was talking about. Let’s ignore this for now and just drag a label, a text field and a button to our view. Align them so that everything looks like this:

Screen Shot 2014-12-22 at 4.50.09 pm.png

Step 4 →  We’re going to setup these controls in our view controller so we can write more Swift code and get used to it, but in order to do that we need to create outlets. At least that’s what you would have done in Objective C.

Screen Shot 2014-12-22 at 4.56.22 pm.png

You should now have 3 outlets: helloLabel, nameTextField, sayHelloButton

   @IBOutlet var helloLabel: UILabel!
   @IBOutlet var nameTextField: UITextField!
   @IBOutlet var sayHelloButton: UIButton!

Step 5 → We have our outlets let’s start customising them. In Swift the method declaration will look like this

import UIKit

class ViewController: UIViewController {

   @IBOutlet var helloLabel: UILabel!
   @IBOutlet var nameTextField: UITextField!
   @IBOutlet var sayHelloButton: UIButton!
   
   
   override func viewDidLoad() {
       super.viewDidLoad()
       
       helloLabel.text = "Hello Swift!"
       helloLabel.textColor = UIColor.redColor()
       helloLabel.textAlignment = NSTextAlignment.Center
       
       nameTextField.placeholder = "Enter your name"
       
       sayHelloButton.setTitle("Say Hello", forState: .Normal)
       
       // Do any additional setup after loading the view, typically from a nib.
   }

   override func didReceiveMemoryWarning() {
       super.didReceiveMemoryWarning()
       // Dispose of any resources that can be recreated.
   }

}

Step 6 →  Add an action for our button. In Interface Builder, bring up the Assistant editor and Ctrl + drag from the UIButton to the view controller. Change from Outlet to Action and name the method sayHelloAction:

Screen Shot 2014-12-22 at 5.12.32 pm.png

We want to change the text of the label to use the text entered in the text field entered.

   @IBAction func sayHelloAction(sender: AnyObject) {
       
       let name = nameTextField.text
       
       helloLabel.text = "Hello \(name)!"
       
   }

Step 7 → Run our app on an iPhone 5s simulator

Screen Shot 2014-12-22 at 5.37.25 pm.png
Read More »