Test Script

Sunday, December 29, 2013

Android Card Layout

I have been using the Card layout in my apps for quite a while now and I absolutely love the look they provide. I recently came across the updated Book My Show app which leverages the Card Layout as well and I liked it. So I decided to write a small tutorial on how to use the Card Layout in your app, I have tried to replicate the BMS app to some extent(Also we won't be using any external libraries to get the Card Layout). Here is what the end result will look like :





Looks great, doesn't it ? So what are we waiting for lets get going. We are going to use 3 classes, 2 xml files and an image to achieve that.


Update : I have improved this tutorial by using nine patch images. I have the code updated on the Github Repo. I have now updated this tutorial to reflect the same. Now I set the background of the list_row.xml to the nine patch image.

 


MainActivity.java

package com.example.testcardlayout;

import java.util.ArrayList;
import java.util.List;
import android.app.ActionBar;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Menu;
import android.widget.ListView;

public class MainActivity extends Activity {

 private List rowItems;

    private static Integer[] images = {
            R.drawable.red,
            R.drawable.red,
            R.drawable.red,
            R.drawable.red,
            R.drawable.red,
            R.drawable.red,
            R.drawable.red,            
            R.drawable.red
    };

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  // Intialize and set the Action Bar Background to Holo Blue
  ActionBar actionBar = getActionBar();
  actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#33b5e5" )));
  
  ListView lv = (ListView) findViewById(R.id.myList);
  rowItems = new ArrayList();
   
         String[] titles = {"Movie1","Movie2","Movie3","Movie4","Movie5","Movie6","Movie7","Movie8"};
         String[] descriptions = {"First Movie","Second movie","Third Movie","Fourth Movie","Fifth Movie",
           "Sixth Movie","Seventh Movie","Eighth Movie"};
        
                //Populate the List
         for (int i = 0; i < titles.length; i++) {
             RowItem item = new RowItem(images[i], titles[i], descriptions[i]);
             rowItems.add(item);
         }

         // Set the adapter on the ListView
         LazyAdapter adapter = new LazyAdapter(getApplicationContext(), R.layout.list_row, rowItems);
         lv.setAdapter(adapter);
 }

}

Let me explain what we did there :


  1. Defined a set of images, I have all pointing to the same image in the drawable folder. These images are going to be used for the imageview. Typically in a real life scenario these images will be added dynamically from your server.
  2. We then initialized the ActionBar and set the background to HOLO Blue.
  3. We populated the rowItems list with RowItem objects(RowItem is a simple POJO class)
  4. We then create an instance of the LazyAdapter(Our Custom Adapter) and  set it to our listview.
  5. Also note we passed in the resource for each list item as R.layout.list_row. This defines what each list item will contain.

Now lets have a look at out Custom Adapter:

LazyAdapter.java

package com.example.testcardlayout;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

public class LazyAdapter extends ArrayAdapter {

    Context context;

    public LazyAdapter(Context context, int resourceId, List items){
        super(context, resourceId, items);
        this.context = context;
    }

    public class ViewHolder{
        ImageView image;
        TextView title;
        TextView description;
    }


    public View getView(int position, View convertView, ViewGroup parent){
        ViewHolder holder;
        RowItem rowItem = getItem(position);

        LayoutInflater mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null){
            convertView = mInflater.inflate(R.layout.list_row, null);
            holder = new ViewHolder();
            holder.image = (ImageView)convertView.findViewById(R.id.list_image);
            holder.title = (TextView)convertView.findViewById(R.id.title);
            holder.description = (TextView)convertView.findViewById(R.id.description);
            convertView.setTag(holder);
        } else
            holder = (ViewHolder)convertView.getTag();

        holder.image.setImageResource(rowItem.getImageId());
        holder.title.setText(rowItem.getTitle());
        holder.description.setText(rowItem.getDesc());

        return convertView;
    }

Here I implement a custom Adapter for our ListView. I have made use of the Holder pattern to make sure the performance of our ListView is maximum. But if none of this makes sense to you at the moment, don't worry I am planning to write a small tutorial on the same soon. For now trust me and agree with me on this.

There is one final java class which is the POJO class:

RowItem.java
package com.example.testcardlayout;

public class RowItem {
    private int imageId;
    private String title;
    private String description;

    public RowItem(int imageId, String title, String desc) {
        this.imageId = imageId;
        this.title = title;
        this.description = desc;
    }
    public int getImageId() {
        return imageId;
    }
    public void setImageId(int imageId) {
        this.imageId = imageId;
    }
    public String getDesc() {
        return description;
    }
    public void setDesc(String desc) {
        this.description = desc;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    @Override
    public String toString() {
        return title + "\n" + description;
    }
}

Now let us have a look at the XML files which define our layouts :

1. activity_main.xml

This layout defines a plain simple ListView within a Linear Layout



    




2. list_row.xml

This layout defines a an ImageView and 2 TextViews to be displayed as an individual list item. Also look at how I set the background of this layout to @drawable/card_greenborder. That gives it the Card look.



       
    
    



    







That's all ! Congratulations, you have successfully built the Card Layout and can now use it in your app. A few things to note here though :

  • I have used a Nine Patch drawable for better performance.
  • This was just a simple demo of how to achieve the Card UI in your app without using any external libraries, you can customize the list_row.xml to suit your needs.
  • A big thanks to Andrew Ruffalo for his help on the card background.
  • Also beginning from this tutorial onwards I will be maintaining a Github repo to post all the source code I develop for tutorials.
Source Code :  Github

Feel free to drop me a comment below if you like my tutorial or if you run into any problem. I would really appreciate it if you could share this post if you liked it.

Tuesday, December 17, 2013

Shared Preferences In Android


So a lot of times you see a few of your favorite apps make the app more customisable and friendlier to you by letting you choose your favorite theme, font and whole bunch of other stuff. Ever wondered how they do it? Wished your apps had such personalisation? Well, look no further today in this tutorial I will be covering something called Shared Preferences in Android which is exactly the magic behind the personalisation of your app for each user.



Shared Preference - It is named so because the preference value  is shared between different components of your app. These are a lightweight mechanism to store key value pairs and use those data later on in the app. You see the bigger picture now don't you? Each of your choice(theme, font etc) are stored as a preference. Thus every time the app starts it reads the stored preferences and customises the entire app for you. Exciting, isn't it ? Enough of my ranting, lets go see how you can setup this awesome thing in your apps.


So to better demonstrate the concept, let me assume that we wish to save the username of the user, so that the next time he opens the app he doesn't need to type the password.

The code snippet below explains how to save a key value pair in a shared preference :


String USERNAME_KEY ="UserName";
String prefName = "userNamePref";

public void savePreferences(){

  SharedPreferences  prefs = getSharedPreferences(prefName, MODE_PRIVATE);
  SharedPreferences.Editor prefEditor = prefs.edit();
  prefEditor.putString(USERNAME_KEY, "user123");
  prefEditor.commit();

 }


Let me quickly explain what we did there :

  1. Created a instance of SharedPreferences called 'prefs', using the getSharedPreferences() method. This method opens the preference named userNamePref if it already exists or creates a new preference if it doesn't exist.
  2. Opened the editor to modify the value stored within the preference.
  3. Inserted the username of the user(i.e. user123 in this case) into the preference.
  4. Lastly, after you have edited the preference you always need to call the commit() on the Editor, else the preference value won't be stored. This is a very common mistake and I forget it quite a few times as well.

So now that you have created a new preference you would like to read it every time the user opens the app so that you can fetch the saved username and display it to the user. So let us see how we read it :

SharedPreferences userPrefs = getSharedPreferences(prefName, MODE_PRIVATE);
String userName = userPrefs.getString(USERNAME_KEY, "");


That's all there is to reading the SharedPreference, the getString() method takes 2 parameters : key and a default value which is returned if the shared preference is not found. In this case if the shared preference is not found then we return an empty string. That's all there is to a simple Shared Preference.

This Shared Preference is available only to components within your app. There are a few extra methods to change the accessibility of the shared preferences but I will be covering that in a follow-up post sometime next week. If you have any queries feel free to drop me a comment below !

Friday, December 13, 2013

Android Invisible App

Have you ever been in a situation where you wished you could have a transparent/invisible activity. May be the next killer spy app or probably a screen monitoring or recording app? Well guess what you are in luck ! In this tutorial I will be showing you how to create a transparent activity in Android. So lets see how we can create our hidden/invisible Activity.



All the magic is going to happen through a simple XML file, the styles.xml in your res folder(if the file already exists then just add the new style at the end) :


    


That's it, now you just need to apply this to the Activity which you want to be transparent in the AndroidManifest.xml




Congratulations, you now have a transparent activity ready for your spying app! So now whenever you start this activity the user won't see any UI as it is completely invisible. You can now perform any actions in the MainActivity.java and the user wont even know that there is something happening.

That's all great but with great power comes great responsibility, so there are two things which you need to make sure as an efficient Android developer :

1. Our transparent activity is still registering touches, so the user is going to be pissed at you if he can't see your activity but his touches don't get registered on the screen. So we would want to make our app to stop listening for touch events so that the user's touches are registered on the visible UI screen.

This is pretty simple as well, all we need to do is add a single line of code in our MainActivity.java

 getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);   // Do not listen for touch events

Basically what that does is, it tells Android to stop registering Touch Events for this activity. Now the user can click the screen as normal without even knowing that your activity is is there spying on him. :P

2. I would not recommend the use of this unless absolutely necessary because since the activity is invisible it will be running and hogging the resources from the device. You can call the finish() method but even after that the app will be in the background consuming resource until the OS kills it. So please make sure you use this only if absolutely necessary and there is no other way of achieving what you want.



That's all from my end, feel free to drop me a comment below if you have any queries !

Saturday, December 7, 2013

How To Send SMS In Android

Hi guys, today in this tutorial we will be looking at how you can send SMS in Android through your next killer app you are designing.



You can use two methods to send out SMS :

1. SmsManager API

2. Built In SMS Application

Using the SmsManager API - using this API you can send SMS directly from within your apps. Here is how

SmsManager smsManager = SmsManager.getDefault();
 smsManager.sendTextMessage("1234567890", null, "SMS Text goes here!", null, null);


That's it, its that simple !
1.  The first parameter is where you send the mobile number to which you wish to send the SMS to.
2.  The 3rd parameter contains the text of the SMS to be sent out.
3.  We create an instance of the SmsManager and using the sendTextMessage method we send out the SMS.
This will send the message using the user's credits, so it is always advised to confirm with the user once before sending out the SMS.

Using the Built-In SMS App - using this method you can redirect the user from your application to the default Messaging app in the device where the user can proceed further as needed.

Here is how we can invoke the default SMS app :

Intent sendIntent = new Intent(Intent.ACTION_VIEW);
 sendIntent.putExtra("sms_body", "The SMS text goes here!"); 
 sendIntent.setType("vnd.android-dir/mms-sms");
 startActivity(sendIntent);

Here is what we did :

1.  Create a new intent with the action as Intent.ACTION_VIEW
2.  Set the body of the SMS using the putExtra method, make sure you put the key as " sms_body".
3.  Set the type to  "vnd.android-dir/mms-sms".
4.  Start the activity.

The user will now be redirected to his default/chosen SMS app. Also for both the above methods to work you need to have the Send SMS permission so add the following permission in the Android Manifest :



That's all there is to send out a SMS through your app. Also if your targeting devices on Android 4.4 and above make sure to check this link :  Android 4.4 SMS Changes

Feel free to drop me any comments/queries. 
UA-42774700-1