Introducing The Code Of A Ninja’s Android App (Beta)

Introducing our favorite programming blog’s android app! For the past few days, I have some spare time to code this. Now you guys can browse our blog instantly in your Android phone or tablet. To download this free app, go to your Google Play store and then search using the keywords “code blog by mike dalisay“, you can see our app on the search result.

0-codeofaninja-android-app-search

I think the first advantage of having a mobile website android app is, an app has to be installed. It means that your website or blog will have its own program and icon in the device home screen or list of apps. Users can put it anywhere they want. Our awesome readers can simply tap it to instantly visit your site and see some updates.

The app (ninja) icon is in my home screen.

The app (ninja) icon is in my home screen.

As for the features of this app, we’ll have screenshots with captions below, this can also be a user’s guide.

The Blog View or the “Read Codes” section.  Launching the app will bring you here.

The Blog View or the “Read Codes” section.
Launching the app will bring you here.

The Navigation Drawer. You can see this view if you click the  ninja icon on the upper left corner OR did a swipe from left to right.

The Navigation Drawer. You can see this view if you click the
ninja icon on the upper left corner OR did a swipe from left to right.

Tapping the “About Blog” option will  show you some info about the blog.

Tapping the “About Blog” option will
show you some info about the blog.

“The Ninjas” section contains some information  about the people behind our blog.

“The Ninjas” section contains some information
about the people behind our blog.

Clicking the “share” icon on the upper right corner  of the app will enable you to share the URL of  what you are currently reading in the app.

Clicking the “share” icon on the upper right corner
of the app will enable you to share the URL of
what you are currently reading in the app.

Also, the action overflow will enable you to “refresh” or “copy” the URL of what you are currently reading.

Also, the action overflow will enable you to “refresh” or “copy”
the URL of what you are currently reading.

Now you might ask, what are the functions of those other icons in the navigation drawer?

  1. Like on Facebook – will open the Facebook app with our Facebook page loaded.
  2. Follow on Google+ – will open the Google+ app with our Google+ page.
  3. Follow on Twitter – opens the Twitter app with my twitter account.
  4. Subscribe via email – opens a browser with a feedburner form for email subscription.
  5. Send Feedback – will open the Gmail app pre-loaded with my email, subject and content.

Our app will automatically detect if one of those apps were not installed. It will tell the user “[app_name] does not exist!”

In the future, I want this app to have an offline feature, like the app is able to download useful tutorials or posts on the device so it can be viewed without internet connection.

As of the moment, I only tested this app on my phone and 10.1 tablet (both Jelly Bean). I looks good and works fine for me. You might encounter performance issues, bugs or crashes, the usual things for a beta release. Please don’t hesitate to report them to me, the same if you have any comments or suggestion for our app’s improvement. Thanks!

Thanks for reading this Introducing The Code Of A Ninja’s Android App (Beta)!

Android Date Picker Example App

I have a friend who often asks: “What day of the week is [insert date here]?” So I decided to create a simple app for him to easily know what day of the week is a certain date. After I made this simple app, I also find it fun to use, haha! Now I know what day of the week I was born, it was Monday (July 30, 1990)!

Video Demo

Here’s the final output of our code for today.

Video Demo Permalink

Live Demo

In case you want to try it yourself, I uploaded this simple app in my play store account. Download it here: Day Of Week Ninja, or you can just search for “day of week ninja” in your android device.

Let’s Code

MainActivity.java – code to run this android date picker example are just in this one file.

package com.example.datepickerlistener;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import android.os.Bundle;
import android.app.Activity;
import android.view.Gravity;
import android.widget.DatePicker;
import android.widget.DatePicker.OnDateChangedListener;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends Activity {

    DatePicker datePickerBirthday;
    TextView textViewUserDate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // create the date picker
        datePickerBirthday = new DatePicker(this);
        
        // hide the whole calendar view (works in api 11 or greater)
        int currentapiVersion = android.os.Build.VERSION.SDK_INT;
        if (currentapiVersion >= 11) {
            datePickerBirthday.setCalendarViewShown(false);
        }

        // create the TextView
        textViewUserDate = new TextView(this);
        textViewUserDate.setGravity(Gravity.CENTER);
        
        // initialize the date to current date
        SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
        String dateStr = sdfDateTime.format(new Date(System.currentTimeMillis()));
        
        String[] dateSplit = dateStr.split("-");
        int currentYear = Integer.parseInt(dateSplit[0]);
        int currentMonth = Integer.parseInt(dateSplit[1]);
        int currentDay = Integer.parseInt(dateSplit[2]);
        
        // to show date and day of week in the TextView
        setHumanReadableDate(currentYear, currentMonth, currentDay);

        // initialize date picker listener
        // currentMonth - 1, because on the picker, 0 is January
        datePickerBirthday.init(currentYear, currentMonth - 1, currentDay, birthdayListener);

        // add to the container
        LinearLayout linearLayoutCalTvContainer = new LinearLayout(this);
        linearLayoutCalTvContainer.setOrientation(LinearLayout.VERTICAL);
        linearLayoutCalTvContainer.addView(datePickerBirthday);
        linearLayoutCalTvContainer.addView(textViewUserDate);

        // set the views for the activity
        setContentView(linearLayoutCalTvContainer);

    }

    // the date picker listener
    OnDateChangedListener birthdayListener = new OnDateChangedListener() {
        
        @Override
        public void onDateChanged(DatePicker birthDayDatePicker,
                int newYear, int newMonth, int newDay) {

            try{
                
                // currentMonth + 1, to retrieve proper month
                setHumanReadableDate(newYear, newMonth + 1, newDay);
                
            } catch (NullPointerException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    
    // show the user a better date format
    public void setHumanReadableDate(int newYear, int newMonth, int newDay){
        try {
            
            String clickedDate = newYear + "-" + newMonth + "-" + newDay;
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date d = sdf.parse(clickedDate);

            SimpleDateFormat sdfDateTime = new SimpleDateFormat("MMMM dd, yyyy 'is' EEEE", Locale.US);
            String dateStr = sdfDateTime.format(d);
            
            textViewUserDate.setText(dateStr);
            
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

}

You can share your thoughts on this Android date picker example code!

Android Table Scroll with Fixed Header and Column

Here’s a sample code I used when I was tasked to make an Android scroll-able table with static header and column. Please note that this code is not yet fully optimized but it can help you have an idea on how this functionality was coded.

Video Demo

The final output of our code for today!

Code Basis

In order to be successful at something, you have to first visualize it. So here’s a simple visualization of what views will be included in our code.

android-fixed-header-and-column

Code

MainActivity.java – executes the table layout

package com.example.tablefreezepane;

import com.Table.TableMainLayout;

import android.os.Bundle;
import android.app.Activity;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new TableMainLayout(this));
    }
}

SampleObject.java – used for populating some table data, like the rows and table headers.

package com.Table;

public class SampleObject {
    
    String header1;
    String header2;
    String header3;
    String header4;
    String header5;
    String header6;
    String header7;
    String header8;
    String header9;
    
    public SampleObject(String header1, String header2, String header3,
            String header4, String header5, String header6,
            String header7, String header8, String header9){
        
        this.header1 = header1;
        this.header2 = header2;
        this.header3 = header3;
        this.header4 = header4;
        this.header5 = header5;
        this.header6 = header6;
        this.header7 = header7;
        this.header8 = header8;
        this.header9 = header9;
        
    }
}

TableMainLayout.java – where everything were constructed.

*Custom horizontal and vertical scroll views were used to sync the movement of table scrolling effect.

package com.Table;


import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class TableMainLayout extends RelativeLayout {

    public final String TAG = "TableMainLayout.java";
    
    // set the header titles
    String headers[] = {
        "Header 1 n multi-lines",
        "Header 2",
        "Header 3",
        "Header 4",
        "Header 5",
        "Header 6",
        "Header 7",
        "Header 8",
        "Header 9"
    };
    
    TableLayout tableA;
    TableLayout tableB;
    TableLayout tableC;
    TableLayout tableD;
    
    HorizontalScrollView horizontalScrollViewB;
    HorizontalScrollView horizontalScrollViewD;

    ScrollView scrollViewC;
    ScrollView scrollViewD;
    
    Context context;
    
    List<SampleObject> sampleObjects = this.sampleObjects();
    
    int headerCellsWidth[] = new int[headers.length];
    
    public TableMainLayout(Context context) {
        
        super(context);
        
        this.context = context;
        
        // initialize the main components (TableLayouts, HorizontalScrollView, ScrollView)
        this.initComponents();
        this.setComponentsId();
        this.setScrollViewAndHorizontalScrollViewTag();
        
        
        // no need to assemble component A, since it is just a table
        this.horizontalScrollViewB.addView(this.tableB);
        
        this.scrollViewC.addView(this.tableC);
        
        this.scrollViewD.addView(this.horizontalScrollViewD);
        this.horizontalScrollViewD.addView(this.tableD);
        
        // add the components to be part of the main layout
        this.addComponentToMainLayout();
        this.setBackgroundColor(Color.RED);
        
        
        // add some table rows
        this.addTableRowToTableA();
        this. addTableRowToTableB();
        
        this.resizeHeaderHeight();
        
        this.getTableRowHeaderCellWidth();
        
        this.generateTableC_AndTable_B();
        
        this.resizeBodyTableRowHeight();
    }

    // this is just the sample data
    List<SampleObject> sampleObjects(){
        
        List<SampleObject> sampleObjects = new ArrayList<SampleObject>();
        
        for(int x=1; x<=20; x++){
            
            SampleObject sampleObject = new SampleObject(
                "Col 1, Row " + x, 
                "Col 2, Row " + x + " - multi-lines",
                "Col 3, Row " + x,
                "Col 4, Row " + x,
                "Col 5, Row " + x,
                "Col 6, Row " + x,
                "Col 7, Row " + x,
                "Col 8, Row " + x,
                "Col 9, Row " + x
            );
            
            sampleObjects.add(sampleObject);
        }
        
        return sampleObjects;
    
    }
    
    // initalized components 
    private void initComponents(){
        
        this.tableA = new TableLayout(this.context); 
        this.tableB = new TableLayout(this.context); 
        this.tableC = new TableLayout(this.context); 
        this.tableD = new TableLayout(this.context);
        
        this.horizontalScrollViewB = new MyHorizontalScrollView(this.context);
        this.horizontalScrollViewD = new MyHorizontalScrollView(this.context);
        
        this.scrollViewC = new MyScrollView(this.context);
        this.scrollViewD = new MyScrollView(this.context);
        
        this.tableA.setBackgroundColor(Color.GREEN);
        this.horizontalScrollViewB.setBackgroundColor(Color.LTGRAY);
        
    }
    
    // set essential component IDs
    private void setComponentsId(){
        this.tableA.setId(1);
        this.horizontalScrollViewB.setId(2);
        this.scrollViewC.setId(3);
        this.scrollViewD.setId(4);
    }
    
    // set tags for some horizontal and vertical scroll view
    private void setScrollViewAndHorizontalScrollViewTag(){
        
        this.horizontalScrollViewB.setTag("horizontal scroll view b");
        this.horizontalScrollViewD.setTag("horizontal scroll view d");
        
        this.scrollViewC.setTag("scroll view c");
        this.scrollViewD.setTag("scroll view d");
    }
    
    // we add the components here in our TableMainLayout
    private void addComponentToMainLayout(){
        
        // RelativeLayout params were very useful here
        // the addRule method is the key to arrange the components properly
        RelativeLayout.LayoutParams componentB_Params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        componentB_Params.addRule(RelativeLayout.RIGHT_OF, this.tableA.getId());
        
        RelativeLayout.LayoutParams componentC_Params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        componentC_Params.addRule(RelativeLayout.BELOW, this.tableA.getId());
        
        RelativeLayout.LayoutParams componentD_Params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
        componentD_Params.addRule(RelativeLayout.RIGHT_OF, this.scrollViewC.getId());
        componentD_Params.addRule(RelativeLayout.BELOW, this.horizontalScrollViewB.getId());
        
        // 'this' is a relative layout, 
        // we extend this table layout as relative layout as seen during the creation of this class
        this.addView(this.tableA);
        this.addView(this.horizontalScrollViewB, componentB_Params);
        this.addView(this.scrollViewC, componentC_Params);
        this.addView(this.scrollViewD, componentD_Params);
            
    }
    

    
    private void addTableRowToTableA(){
        this.tableA.addView(this.componentATableRow());
    }
    
    private void addTableRowToTableB(){
        this.tableB.addView(this.componentBTableRow());
    }
    
    // generate table row of table A
    TableRow componentATableRow(){
        
        TableRow componentATableRow = new TableRow(this.context);
        TextView textView = this.headerTextView(this.headers[0]);
        componentATableRow.addView(textView);
        
        return componentATableRow;
    }
    
    // generate table row of table B
    TableRow componentBTableRow(){
        
        TableRow componentBTableRow = new TableRow(this.context);
        int headerFieldCount = this.headers.length;
        
        TableRow.LayoutParams params = new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT);
        params.setMargins(2, 0, 0, 0);
        
        for(int x=0; x<(headerFieldCount-1); x++){
            TextView textView = this.headerTextView(this.headers[x+1]);
            textView.setLayoutParams(params);
            componentBTableRow.addView(textView);
        }
        
        return componentBTableRow;
    }
    
    // generate table row of table C and table D
    private void generateTableC_AndTable_B(){
        
        // just seeing some header cell width
        for(int x=0; x<this.headerCellsWidth.length; x++){
            Log.v("TableMainLayout.java", this.headerCellsWidth[x]+"");
        }
        
        for(SampleObject sampleObject : this.sampleObjects){
            
            TableRow tableRowForTableC = this.tableRowForTableC(sampleObject);
            TableRow taleRowForTableD = this.taleRowForTableD(sampleObject);
            
            tableRowForTableC.setBackgroundColor(Color.LTGRAY);
            taleRowForTableD.setBackgroundColor(Color.LTGRAY);
            
            this.tableC.addView(tableRowForTableC);
            this.tableD.addView(taleRowForTableD);
            
        }
    }
    
    // a TableRow for table C
    TableRow tableRowForTableC(SampleObject sampleObject){
        
        TableRow.LayoutParams params = new TableRow.LayoutParams( this.headerCellsWidth[0],LayoutParams.MATCH_PARENT);
        params.setMargins(0, 2, 0, 0);
        
        TableRow tableRowForTableC = new TableRow(this.context);
        TextView textView = this.bodyTextView(sampleObject.header1);
        tableRowForTableC.addView(textView,params);
        
        return tableRowForTableC;
    }
    
    TableRow taleRowForTableD(SampleObject sampleObject){

        TableRow taleRowForTableD = new TableRow(this.context);
        
        int loopCount = ((TableRow)this.tableB.getChildAt(0)).getChildCount();
        String info[] = {
            sampleObject.header2,
            sampleObject.header3,
            sampleObject.header4,
            sampleObject.header5,
            sampleObject.header6,
            sampleObject.header7,
            sampleObject.header8,
            sampleObject.header9
        };
        
        for(int x=0 ; x<loopCount; x++){
            TableRow.LayoutParams params = new TableRow.LayoutParams( headerCellsWidth[x+1],LayoutParams.MATCH_PARENT);
            params.setMargins(2, 2, 0, 0);
            
            TextView textViewB = this.bodyTextView(info[x]);
            taleRowForTableD.addView(textViewB,params);
        }
        
        return taleRowForTableD;
        
    }
    
    // table cell standard TextView
    TextView bodyTextView(String label){
        
        TextView bodyTextView = new TextView(this.context);
        bodyTextView.setBackgroundColor(Color.WHITE);
        bodyTextView.setText(label);
        bodyTextView.setGravity(Gravity.CENTER);
        bodyTextView.setPadding(5, 5, 5, 5);
        
        return bodyTextView;
    }
    
    // header standard TextView
    TextView headerTextView(String label){
        
        TextView headerTextView = new TextView(this.context);
        headerTextView.setBackgroundColor(Color.WHITE);
        headerTextView.setText(label);
        headerTextView.setGravity(Gravity.CENTER);
        headerTextView.setPadding(5, 5, 5, 5);
        
        return headerTextView;
    }
    
    // resizing TableRow height starts here
    void resizeHeaderHeight() {
        
        TableRow productNameHeaderTableRow = (TableRow) this.tableA.getChildAt(0);
        TableRow productInfoTableRow = (TableRow)  this.tableB.getChildAt(0);

        int rowAHeight = this.viewHeight(productNameHeaderTableRow);
        int rowBHeight = this.viewHeight(productInfoTableRow);

        TableRow tableRow = rowAHeight < rowBHeight ? productNameHeaderTableRow : productInfoTableRow;
        int finalHeight = rowAHeight > rowBHeight ? rowAHeight : rowBHeight;

        this.matchLayoutHeight(tableRow, finalHeight);
    }
    
    void getTableRowHeaderCellWidth(){
        
        int tableAChildCount = ((TableRow)this.tableA.getChildAt(0)).getChildCount();
        int tableBChildCount = ((TableRow)this.tableB.getChildAt(0)).getChildCount();;
        
        for(int x=0; x<(tableAChildCount+tableBChildCount); x++){
            
            if(x==0){
                this.headerCellsWidth[x] = this.viewWidth(((TableRow)this.tableA.getChildAt(0)).getChildAt(x));
            }else{
                this.headerCellsWidth[x] = this.viewWidth(((TableRow)this.tableB.getChildAt(0)).getChildAt(x-1));
            }
            
        }
    }
    
    // resize body table row height
    void resizeBodyTableRowHeight(){
        
        int tableC_ChildCount = this.tableC.getChildCount();
        
        for(int x=0; x<tableC_ChildCount; x++){
        
            TableRow productNameHeaderTableRow = (TableRow) this.tableC.getChildAt(x);
            TableRow productInfoTableRow = (TableRow)  this.tableD.getChildAt(x);
    
            int rowAHeight = this.viewHeight(productNameHeaderTableRow);
            int rowBHeight = this.viewHeight(productInfoTableRow);
    
            TableRow tableRow = rowAHeight < rowBHeight ? productNameHeaderTableRow : productInfoTableRow;
            int finalHeight = rowAHeight > rowBHeight ? rowAHeight : rowBHeight;

            this.matchLayoutHeight(tableRow, finalHeight);      
        }
        
    }
    
    // match all height in a table row
    // to make a standard TableRow height
    private void matchLayoutHeight(TableRow tableRow, int height) {
        
        int tableRowChildCount = tableRow.getChildCount();
        
        // if a TableRow has only 1 child
        if(tableRow.getChildCount()==1){
            
            View view = tableRow.getChildAt(0);
            TableRow.LayoutParams params = (TableRow.LayoutParams) view.getLayoutParams();
            params.height = height - (params.bottomMargin + params.topMargin);
            
            return ;
        }
        
        // if a TableRow has more than 1 child
        for (int x = 0; x < tableRowChildCount; x++) {
            
            View view = tableRow.getChildAt(x);
            
            TableRow.LayoutParams params = (TableRow.LayoutParams) view.getLayoutParams();

            if (!isTheHeighestLayout(tableRow, x)) {
                params.height = height - (params.bottomMargin + params.topMargin);
                return;
            }
        }

    }

    // check if the view has the highest height in a TableRow
    private boolean isTheHeighestLayout(TableRow tableRow, int layoutPosition) {
        
        int tableRowChildCount = tableRow.getChildCount();
        int heighestViewPosition = -1;
        int viewHeight = 0;

        for (int x = 0; x < tableRowChildCount; x++) {
            View view = tableRow.getChildAt(x);
            int height = this.viewHeight(view);

            if (viewHeight < height) {
                heighestViewPosition = x;
                viewHeight = height;
            }
        }

        return heighestViewPosition == layoutPosition;
    }

    // read a view's height
    private int viewHeight(View view) {
        view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        return view.getMeasuredHeight();
    }

    // read a view's width
    private int viewWidth(View view) {
        view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        return view.getMeasuredWidth();
    }

    // horizontal scroll view custom class
    class MyHorizontalScrollView extends HorizontalScrollView{

        public MyHorizontalScrollView(Context context) {
            super(context);
        }
        
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            String tag = (String) this.getTag();
            
            if(tag.equalsIgnoreCase("horizontal scroll view b")){
                horizontalScrollViewD.scrollTo(l, 0);
            }else{
                horizontalScrollViewB.scrollTo(l, 0);
            }
        }
        
    }

    // scroll view custom class
    class MyScrollView extends ScrollView{

        public MyScrollView(Context context) {
            super(context);
        }
        
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            
            String tag = (String) this.getTag();
            
            if(tag.equalsIgnoreCase("scroll view c")){
                scrollViewD.scrollTo(0, t);
            }else{
                scrollViewC.scrollTo(0,t);
            }
        }
    }

    
}

You can share your thoughts (in the comments section below) about this scroll-able android TableLayout with fixed header and column code!
Thanks for reading this Android Table Scroll with Fixed Header and Column!

How to Install Android Development Environment

A lot has been changed since I wrote this post: Getting Started with Google Android Development. I’m not going to remove that page but I rather keep it as an archive about how Android development environment installation was done before.
Installing the Android development environment was a lot easier nowadays, thanks Google! I’m not sure when it started, but there are only two things you have to download now. First is JAVA and second is the Android SDK ADT Bundle.

In this post, I’m going to try to walk you through on how is the latest way to install an Android development environment on your PC. By the way, I’m using Windows 7, but I think that the files to be downloaded and steps are almost the same for other OS, so this post can give you an idea if ever you can’t find (on other websites) how it was done in your platform. I actually wrote how to Install Android Development Environment on Ubuntu last year, I hope the changes are minimal so it can still help if you’re using Ubuntu.

Step 1: Download JAVA in this link: Java SE Downloads

Download the Java Platform (JDK), the one on the left side.

Download the Java Platform (JDK), the one on the left side.

Step 2: Download the SDK(ADT Bundle for Windows) here: Android SDK

Click the blue button “Download the SDK”

Click the blue button “Download the SDK”

Agree with the terms and conditions. I have a 32 bit computer. Click the blue button again.

Agree with the terms and conditions. I have a 32 bit computer. Click the blue button again.

Wait for the download to finish. File size is around 400+ MB. Excited to code?

Wait for the download to finish. File size is around 400+ MB. Excited to code?

Step 3: Install JAVA. Run the file we’ve downloaded earlier during Step 1.

Step 4: Extract the SDK ADT Bundle we’ve downloaded earlier during Step 2.

extract-adt-bundle

Step 5: Go to the eclipse folder inside the SDK ADT Bundle folder and create a shortcut to your desktop.

eclipse-desktop-shortcut

Step 6: Run eclipse from your Desktop shortcut.

Eclipse is loading.

Eclipse is loading.

Choose your worksapce.

Choose your worksapce.

Sometimes you will be prompted to update your SDK tools. Just follow the prompt to update your SDK.

Now you have your Android development environment. Enjoy!

My old codes were in this workspace.

My old codes were in this workspace.

Next steps would be the undying “Hello World!” simple program. The official Android training is also helpful.

Who are the Developers of Android?

Android powered devices like mobile phones, tablet computers and home appliances are everywhere nowadays. It is a delight for us to experience a high technology which is less expensive, more powerful and efficient. You know what Android is, you might be grateful, and now you are asking…
“Who are the developers of Android?”
Android growth in device activations. Image from Android Developers.

Who are the people behind this amazing technology? Today’s article focuses on bringing you a brief answer to that question. So here it is – I think there are three major developers of Android, they are:
  1. Google
  2. Open Handset Alliance
  3. End Users
Who are the Developers of Android? - Google

Google bought Android Inc. on August 2005, and that makes Google as the lead developer of the Android platform. Under Google, Android has seen many updates which vastly improved the operating system. Major version names were named after a sweet dessert:

  • Android 1.5 – Cupcake (April 2009)
  • Android 1.6 – Donut (September 2009)
  • Android 2.0 – Eclair (October 2009)
  • Android 2.2 – Froyo (May 2010)
  • Android 2.3 – Gingerbread (December 2010)
  • Android 3.0 – Honeycomb (February 2011)
  • Android 4.0 – Ice Cream Sandwich (October 2011)
  • Android 4.1 – Jelly Bean (July 2012)
  • Android 5.0 – Key Lime Pie (Unofficial, expected to be released this second quarter of 2013)
Where are the letters ‘A’ and ‘B’? I think they are the Android 1.0 and Android 1.1, but no official names were announced. Google also developed and maintain an online electronic store called Google Play (formerly Android Market) where users can download useful applications (a lot of them are free!) and entertainment products.
Who are the Developers of Android? - Open Handset Alliance

The Open Handset Alliance is an association of 80+ technology and mobile companies from around the world who work together for the development of Android. Now imagine what Android can achieve! I believe that these companies have the talent, resources and power to create or develop the Android technology as the best mobile operating system. Companies include:

  • Mobile Operators – Sprint Nextel, T-mobile, Telus, Vodafone, etc.
  • Handset Manufacturers – Acer Inc, HTC Corp., LG Electronics, Motorola, Samsung, etc.
  • Semiconductor Companies – Intel Corp, MediaTek, NVIDIA Corp, Qualcomm, etc.
  • Software Companies – eBay, Google, Nuance, etc.
  • and Commercialization Companies like Accenture, Wind River, Teleca AB, etc.
Who are the Developers of Android? - End Users
Some android users. Image from autocadws.

Yes, I think that we, the users have always been involved with the development of Android. The technical developers gets feedback and innovative or crazy ideas from us to make apps and the platform better. It is us that voices out what we really want to use and experience. We have the power to make Android better than we can imagine!

Copy or Move File From One Directory to Another on Android

Today we are going to take a look at how to programmatically “copy” or “move” a file from one directory to another on Android. In case you want to be clarified about the difference, copying a file means the file will be seen on another directory (target location) without deleting the original file from the source location. Moving a file means the file will be seen in another directory and the original file will be deleted from its former location.

Logcat output when we successfuly copied a file. Click to enlarge.

Logcat output when we successfuly copied a file. Click to enlarge.

Here are some situations where I found these functionalities helpful:

  • Copying a file to another directory is useful when you have to save a file’s version or state in specific time.
  • Moving a file to another directory can be an advantage when you want to remove a file from a main folder of your application and make it an archive.

Download Code

Before running this code, you have to:

  • Place an example text file named “sample.txt” (with any text inside) in your SD card root.
  • Create a directory called “MyNewFolder” in your SD card root directory also.

Our MainActivity.java

package com.example.copyfilefromdirectorytoanother;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.app.Activity;

public class MainActivity extends Activity {

    private static final String TAG = "MainActivity.java";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // your sd card
        String sdCard = Environment.getExternalStorageDirectory().toString();
        
        // the file to be moved or copied
        File sourceLocation = new File (sdCard + "/sample.txt");
        
        // make sure your target location folder exists!
        File targetLocation = new File (sdCard + "/MyNewFolder/sample.txt");

        // just to take note of the location sources
        Log.v(TAG, "sourceLocation: " + sourceLocation);
        Log.v(TAG, "targetLocation: " + targetLocation);
        
        try {
            
            // 1 = move the file, 2 = copy the file
            int actionChoice = 2;
            
            // moving the file to another directory
            if(actionChoice==1){
                
                if(sourceLocation.renameTo(targetLocation)){
                    Log.v(TAG, "Move file successful.");
                }else{
                    Log.v(TAG, "Move file failed.");
                }
                
            }
            
            // we will copy the file
            else{
                
                // make sure the target file exists
                
                if(sourceLocation.exists()){
                    
                    InputStream in = new FileInputStream(sourceLocation);
                    OutputStream out = new FileOutputStream(targetLocation);
        
                    // Copy the bits from instream to outstream
                    byte[] buf = new byte[1024];
                    int len;
                    
                    while ((len = in.read(buf)) > 0) {
                        out.write(buf, 0, len);
                    }
                    
                    in.close();
                    out.close();
                    
                    Log.v(TAG, "Copy file successful.");
                    
                }else{
                    Log.v(TAG, "Copy file failed. Source file missing.");
                }
                
            }
            
        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Logcat ouput when we move a file looks like this:

Click to enlarge.

Click to enlarge.

Logcat output when copying a file failed:

Click to enlarge.

Click to enlarge.


Thanks for reading this Copy or Move File From One Directory to Another on Android!

Android XML Parser Example with XML from SD Card, URL or Assets

XML parsing could be one of the most basic requirement on your Android application. In today’s tutorial, we are going to read XML files using three input sources. There can be three sources of your XML:

1. XML from device SD Card. Your dynamic XML file could be downloaded first for offline use.
2. XML from a URL. You could be parsing data from your online database or RSS feed. Works if device is online only.
3. XML from your app’s assets folder. Your XML file is not dynamic so it is better to put it in the asset’s folder where it cannot be change.

By the way, we’ll be using SAX parser here. I think that for mobile apps, SAX parser is better to use than DOM parser.

DOM parser consumes more memory because it loads the whole XML data to the device memory while SAX parser does an event driven approach. SAX parser processes each line of the XML without loading it to the device memory first.

xml-parsing-tutorial-output

DOWNLOAD SOURCE CODE HERE

Our XML structure looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<Contents>
    <Owners>
        <Owner>
            <Name>Joselito Dimaculangan</Name>
            <Age>16</Age>
            <EmailAddress>joselito123@gmail.com</EmailAddress>
        </Owner>
        <Owner>
            <Name>Noemi De Galileo</Name>
            <Age>14</Age>
            <EmailAddress>noemi111@gmail.com</EmailAddress>
        </Owner>
    </Owners>
    <Dogs>
        <Dog>
            <Name>Barky</Name>
            <Birthday>June 29, 2012</Birthday>
        </Dog>
        <Dog>
            <Name>Jumbo</Name>
            <Birthday>December 30, 2012</Birthday>
        </Dog>
    </Dogs>
</Contents>

MainActivity.java code – Here you can change the value of x to 1,2 or 3 to change the input source. Read comments on code.

package com.example.androidparsexml;

import java.io.File;
import java.io.FileInputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.app.Activity;

public class MainActivity extends Activity {

    public static final String LOG_TAG = "MainActivity.java";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {

            // parse our XML
            new parseXmlAsync().execute();

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * @We are using an AsyncTask to avoid
     * android.os.NetworkOnMainThreadException when parsing from a URL
     *
     * @If you don't know a thing about AsyncTasks,there are a lot of excellent
     * tutorial out there, see this thread
     */
    private class parseXmlAsync extends AsyncTask<String, String, String> {

        @Override
        protected String doInBackground(String... strings) {

            try {

                /*
                 * You may change the value of x to try different sources of XML
                 *
                 * @1 = XML from SD Card
                 *
                 * @2 = XML from URL
                 *
                 * @3 = XML from assets folder
                 */
                int x = 2;

                // initialize our input source variable
                InputSource inputSource = null;

                // XML from sdcard
                if (x == 1) {

                    // make sure sample.xml is in your root SD card directory
                    File xmlFile = new File(
                            Environment.getExternalStorageDirectory()
                                    + "/sample.xml");
                    FileInputStream xmlFileInputStream = new FileInputStream(
                            xmlFile);
                    inputSource = new InputSource(xmlFileInputStream);
                }

                // XML from URL
                else if (x == 2) {
                    // specify a URL
                    // make sure you are connected to the internet
                    URL url = new URL(
                            "http://demo.codeofaninja.com/AndroidXml/sample.xml");
                    inputSource = new InputSource(url.openStream());
                }

                // XML from assets folder
                else if (x == 3) {
                    inputSource = new InputSource(getAssets()
                            .open("sample.xml"));
                }

                // instantiate SAX parser
                SAXParserFactory saxParserFactory = SAXParserFactory
                        .newInstance();
                SAXParser saxParser = saxParserFactory.newSAXParser();

                // get the XML reader
                XMLReader xmlReader = saxParser.getXMLReader();

                // prepare and set the XML content or data handler before
                // parsing
                XmlContentHandler xmlContentHandler = new XmlContentHandler();
                xmlReader.setContentHandler(xmlContentHandler);

                // parse the XML input source
                xmlReader.parse(inputSource);

                // put the parsed data to a List
                List<ParsedDataSet> parsedDataSet = xmlContentHandler
                        .getParsedData();

                // we'll use an iterator so we can loop through the data
                Iterator<ParsedDataSet> i = parsedDataSet.iterator();
                ParsedDataSet dataItem;

                while (i.hasNext()) {

                    dataItem = (ParsedDataSet) i.next();

                    /*
                     * parentTag can also represent the main type of data, in
                     * our example, "Owners" and "Dogs"
                     */
                    String parentTag = dataItem.getParentTag();
                    Log.v(LOG_TAG, "parentTag: " + parentTag);

                    if (parentTag.equals("Owners")) {
                        Log.v(LOG_TAG, "Name: " + dataItem.getName());
                        Log.v(LOG_TAG, "Age: " + dataItem.getAge());
                        Log.v(LOG_TAG,
                                "EmailAddress: " + dataItem.getEmailAddress());
                    }

                    else if (parentTag.equals("Dogs")) {
                        Log.v(LOG_TAG, "Name: " + dataItem.getName());
                        Log.v(LOG_TAG, "Birthday: " + dataItem.getBirthday());
                    }

                }

            } catch (NullPointerException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String lenghtOfFile) {
            // your do stuff after parsing the XML
        }
    }

}

XmlContentHandler.java – We’ll extend the default handler.

package com.example.androidparsexml;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

public class XmlContentHandler extends DefaultHandler {

    private static final String LOG_TAG = "XmlContentHandler";

    // used to track of what tags are we
    private boolean inOwner = false;
    private boolean inDog = false;

    // accumulate the values
    private StringBuilder mStringBuilder = new StringBuilder();

    // new object
    private ParsedDataSet mParsedDataSet = new ParsedDataSet();

    // the list of data
    private List<ParsedDataSet> mParsedDataSetList = new ArrayList<ParsedDataSet>();

    /*
     * Called when parsed data is requested.
     */
    public List<ParsedDataSet> getParsedData() {
        Log.v(LOG_TAG, "Returning mParsedDataSetList");
        return this.mParsedDataSetList;
    }

    // Methods below are built in, we just have to do the tweaks.

    /*
     * @Receive notification of the start of an element.
     *
     * @Called in opening tags such as <Owner>
     */
    @Override
    public void startElement(String namespaceURI, String localName,
            String qName, Attributes atts) throws SAXException {

        if (localName.equals("Owner")) {
            // meaning new data object will be made
            this.mParsedDataSet = new ParsedDataSet();
            this.inOwner = true;
        }

        else if (localName.equals("Dog")) {
            this.mParsedDataSet = new ParsedDataSet();
            this.inDog = true;
        }

    }

    /*
     * @Receive notification of the end of an element.
     *
     * @Called in end tags such as </Owner>
     */
    @Override
    public void endElement(String namespaceURI, String localName, String qName)
            throws SAXException {

        // Owners
        if (this.inOwner == true && localName.equals("Owner")) {
            this.mParsedDataSetList.add(mParsedDataSet);
            mParsedDataSet.setParentTag("Owners");
            this.inOwner = false;
        }

        else if (this.inOwner == true && localName.equals("Name")) {
            mParsedDataSet.setName(mStringBuilder.toString().trim());
        }

        else if (this.inOwner == true && localName.equals("Age")) {
            mParsedDataSet.setAge(mStringBuilder.toString().trim());
        }

        else if (this.inOwner == true && localName.equals("EmailAddress")) {
            mParsedDataSet.setEmailAddress(mStringBuilder.toString().trim());
        }

        // Dogs
        if (this.inDog == true && localName.equals("Dog")) {
            this.mParsedDataSetList.add(mParsedDataSet);
            mParsedDataSet.setParentTag("Dogs");
            this.inDog = false;
        }

        else if (this.inDog == true && localName.equals("Name")) {
            mParsedDataSet.setName(mStringBuilder.toString().trim());
        }

        else if (this.inDog == true && localName.equals("Birthday")) {
            mParsedDataSet.setBirthday(mStringBuilder.toString().trim());
        }

        // empty our string builder
        mStringBuilder.setLength(0);
    }

    /*
     * @Receive notification of character data inside an element.
     *
     * @Gets be called on the following structure: <tag>characters</tag>
     */
    @Override
    public void characters(char ch[], int start, int length) {
        // append the value to our string builder
        mStringBuilder.append(ch, start, length);
    }
}

ParsedDataSet.java – You can use your own object class if the XML you’re parsing is for a more specific data object. For example, you are parsing only for “Owners” and NOT “Owners & Dogs” like what we have.

package com.example.androidparsexml;

public class ParsedDataSet {

	private String parentTag = null;
	private String name = null;
	private String age = null;
	private String emailAddress = null;
	private String birthday = null;

	// parent tag
	public String getParentTag() {
		return parentTag;
	}

	public void setParentTag(String parentTag) {
		this.parentTag = parentTag;
	}

	// name
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	// age
	public String getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}

	// emailAddress
	public String getEmailAddress() {
		return emailAddress;
	}

	public void setEmailAddress(String emailAddress) {
		this.emailAddress = emailAddress;
	}

	// birthday
	public String getBirthday() {
		return birthday;
	}

	public void setBirthday(String name) {
		this.birthday = name;
	}
}

Our AndroidManifest.xml will have internet permissions because we use a URL input

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

Our code output on the device look simply like this:

Device output.

Ways to Create a Splash Screen for Android App

Today we’re going to create a splash screen for your Android app. A splash screen is usually an image or a view that appears to the user while the app is loading, it is also a way to make your brand or logo easier to be recognize by the user. Some android apps that uses splash screens include Facebook, Pocket and of course, the game apps. I’m going to show you two ways to create android splash screens.

Example logo to be seen in our splash screen.

Example logo to be seen in our splash screen.

Splash Screen With Two Activities

The first way I’m gonna teach you is using two activities, the first activity will be our splash screen and the second activity will be our app’s main screen. The splash screen activity will be shown for four seconds and then it will show the next activity. Download the code here:

Download Code

Here are the files we need:

Highlighted are the files we have to create.

Highlighted are the files we have to create.

SplashScreenActivity.java – The initial activity executed. This activity will end with an animation that depends on the device.

        // remove title bar
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        // our layout xml
        setContentView(R.layout.activity_splash_screen);

        // we're gonna use a timer task to show the main activity after 4 seconds
        TimerTask task = new TimerTask() {

            @Override
            public void run() {

                // go to the main activity
                Intent nextActivity = new Intent(SplashScreenActivity.this,
                        MainActivity.class);
                startActivity(nextActivity);

                // make sure splash screen activity is gone
                SplashScreenActivity.this.finish();

            }

        };

        // Schedule a task for single execution after a specified delay.
        // Show splash screen for 4 seconds
        new Timer().schedule(task, 4000);

    }

}

MainActivity.java – Our app’s main screen, where the main functions of your app should be seen.

package com.example.splashscreenexample;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // remove title bar
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        // our main activity layout
        setContentView(R.layout.activity_main);
        
    }
}

codeofaninja350pxwidth.png – An example image used in the splash screen. This is included in the code download.

Splash Screen with One Activity

The second way to create a splash screen is using just one activity – your MainActivity. It should be covered with an ImageView first and then after few seconds, it will disappear with a simple fade-out animation to make it look smooth. Download code this code:

Download Code

Files we need are highlighted below:

We’ll work on three files in this example.

We’ll work on three files in this example.

MainActivitity.java – The file with double purpose, it will show our splash screen and then main screen.

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // remove title bar.
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.activity_main);

        // our timer task.
        TimerTask task = new TimerTask() {

            @Override
            public void run() {

                // we have to run it on UI thread so we won't get view error
                MainActivity.this.runOnUiThread(new Runnable() {
                    public void run() {

                        // get the splash image
                        ImageView splashImage = (ImageView) MainActivity.this
                                .findViewById(R.id.imageViewSplashLogo);
                        
                        // make the splash image invisible
                        splashImage.setVisibility(View.GONE);

                        // specify animation
                        Animation animFadeOut = AnimationUtils.loadAnimation(MainActivity.this,
                                R.anim.splash_screen_fadeout);
                        
                        // apply the animattion
                        splashImage.startAnimation(animFadeOut);
                        
                    }
                });

            }

        };

        // Schedule a task for single execution after a specified delay.
        // Show splash screen for 4 seconds
        new Timer().schedule(task, 4000);

    }

}

splash_screen_fadeout.xml – It will make our splash screen gone beautifully – a simple fade-out animation.

<?xml version="1.0" encoding="utf-8"?>
<!--
    -zAdjustment makes sure the activity is on top
    -interpolator defines the rate of change of an animation
    -we use decelerate_interpolator to reduce animation speed from visible (Alpha 1.0) to invisible (Alpha 0.0)
-->
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromAlpha="1.0"
    android:interpolator="@android:anim/decelerate_interpolator"
    android:toAlpha="0.0"
    android:zAdjustment="top" />

codeofaninja350pxwidth.png – our example logo.

Output screenshots:

Splash screen.

Splash screen.

Main Activity.

Main Activity.

Thanks for reading this Ways to Create a Splash Screen for Android App!