How to Create a Compass in Android Code – Tutorial and Source Code

android compass code example

Today I’m going to share a very simple compass in android code that you can use whenever you are creating an application with a compass feature.

It’s good to see the most devices nowadays has a motion sensor capability to make a compass run.

Unfortunately, there are still some android devices (like Huawei Y300 and Lenovo P700i) does not have full support of motions sensors so this code will not work for them.

We will cover the following in this post:

1.0 Android Compass Video Demo
2.0 Compass App Needed Files
3.0 Complete Compass in Android Code
3.1 MainActivity.java
3.2 activity_main.xml
3.3 Some Notes
4.0 Download Source Code
5.0 Further Readings

1.0 Compass in Android Code Video Demo

Our code for today will run just like the following video.

2.0 Compass App Needed Files

You need to create your own compass image. For this example, I’m using a stock photo. Your image must be a PNG with transparent background, do not use this jpg file I used. Please note that the “north” must be at the top part of the image.

compass in android code example

We will also need the two main code files seen in the complete code below.

3.0 Complete Android Compass Code

3.1 MainActivity.java where all the magic happens. The SensorManager was initialized in the onCreate() method and it was being moved or animated using the onSensorChanged() method.

package com.example.compassapp;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends Activity implements SensorEventListener {

    // define the display assembly compass picture
    private ImageView image;

    // record the compass picture angle turned
    private float currentDegree = 0f;

    // device sensor manager
    private SensorManager mSensorManager;

    TextView tvHeading;

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

        // our compass image 
        image = (ImageView) findViewById(R.id.imageViewCompass);

        // TextView that will tell the user what degree is he heading
        tvHeading = (TextView) findViewById(R.id.tvHeading);

        // initialize your android device sensor capabilities
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        
        // for the system's orientation sensor registered listeners
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                SensorManager.SENSOR_DELAY_GAME);
    }

    @Override
    protected void onPause() {
        super.onPause();
        
        // to stop the listener and save battery
        mSensorManager.unregisterListener(this);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {

        // get the angle around the z-axis rotated
        float degree = Math.round(event.values[0]);

        tvHeading.setText("Heading: " + Float.toString(degree) + " degrees");

        // create a rotation animation (reverse turn degree degrees)
        RotateAnimation ra = new RotateAnimation(
                currentDegree, 
                -degree,
                Animation.RELATIVE_TO_SELF, 0.5f, 
                Animation.RELATIVE_TO_SELF,
                0.5f);

        // how long the animation will take place
        ra.setDuration(210);

        // set the animation after the end of the reservation status
        ra.setFillAfter(true);

        // Start the animation
        image.startAnimation(ra);
        currentDegree = -degree;

    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // not in use
    }
}

3.2 activity_main.xml – Our layout file. Wrapped in RelativeLayout, the TextView is used to display the user’s current heading. The ImageView contains the compass image which is being animated like a compass using the code in our MainActivity.java

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff" >

    <TextView
        android:id="@+id/tvHeading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="40dp"
        android:layout_marginTop="20dp"
        android:text="Heading: 0.0" />

    <ImageView
        android:id="@+id/imageViewCompass"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tvHeading"
        android:layout_centerHorizontal="true"
        android:src="@drawable/img_compass" />

</RelativeLayout>

3.3 Some notes

1. My app orientation is locked to portrait mode.
2. There are no special permissions in the Manifest file.
3. North Magnetic Pole is the point on the surface of Earth’s
Northern Hemisphere.
4. True north, or the geodetic north, is the direction along the earth’s surface towards the geographic North Pole.
5. Android SensorManager uses the magnetic North Pole.

5.0 Download Source Code

You can get the source code by following the whole, well detailed and free tutorial above. But isn’t it more convenient if you can just download the complete source code we used, and play around it?

There’s a small fee in getting the complete source code, it is small compared to the:

✔ Value or skill upgrade it can bring you, or YES
✔ Income you can get from your website project or business. YES
✔ Precious time you save. YES

Buy now

5.0 Further Readings

This can help you learn more about creating compass in android code. You can visit them and do more customizations!

1. Android SensorManager
2. Android RotateAnimation
3. Android Motion Sensors
4. Magnetic North Pole vs. Geographic North Pole

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 Notification with Sound and Icon Tutorial

My app needed a simple Android notification with sound and icon. So here’s the code I used to make that happen. I know that there are many other types of notification in Android, but this time, I just want to show you a very simple code that can be a solution to your problem too!

I will probably create a series of blog posts regarding Android notifications, and make it like a cheat sheet for all of us. Anyway, here are some screenshots of today’s code output:

When you run this code

When you run this code

When you click the button “Show Notification”, the notification bar will have the ninja icon and you will hear a sound (make sure you’re not in silent mode).

When you click the button “Show Notification”,
the notification bar will have the ninja icon
and you will hear a sound
(make sure you’re not in silent mode).

When you slide down the notification bar.

When you slide down the notification bar.

Download Code

AndroidNotificationBar.zip

Hide Notification

How to hide the notification? There are two ways:

1. First, you can click the “Cancel Notification” button.
2. Or, second, swipe the notification to left or right (swipe the notification in the third image).

These ways were set programatically, so read the code (with comments) below.

Let’s Code!

Here’s are our awesome code: MainActivity.java

package com.example.androidnotificationbar;

import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;

public class MainActivity extends Activity {

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

        // listener handler
        View.OnClickListener handler = new View.OnClickListener(){
            public void onClick(View v) {
                
                switch (v.getId()) {

                    case R.id.btnShowNotification:
                        showNotification();
                        break;
                    
                    case R.id.btnCancelNotification:
                        cancelNotification(0);
                        break;
                }
            }
        };
            
        // we will set the listeners
        findViewById(R.id.btnShowNotification).setOnClickListener(handler);
        findViewById(R.id.btnCancelNotification).setOnClickListener(handler);
        
    }
    
    public void showNotification(){

        // define sound URI, the sound to be played when there's a notification
        Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        
        // intent triggered, you can add other intent for other actions
        Intent intent = new Intent(MainActivity.this, NotificationReceiver.class);
        PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
        
        // this is it, we'll build the notification!
        // in the addAction method, if you don't want any icon, just set the first param to 0
        Notification mNotification = new Notification.Builder(this)
            
            .setContentTitle("New Post!")
            .setContentText("Here's an awesome update for you!")
            .setSmallIcon(R.drawable.ninja)
            .setContentIntent(pIntent)
            .setSound(soundUri)
            
            .addAction(R.drawable.ninja, "View", pIntent)
            .addAction(0, "Remind", pIntent)
            
            .build();
        
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        // If you want to hide the notification after it was selected, do the code below
        // myNotification.flags |= Notification.FLAG_AUTO_CANCEL;
        
        notificationManager.notify(0, mNotification);
    }
    
    public void cancelNotification(int notificationId){
        
        if (Context.NOTIFICATION_SERVICE!=null) {
            String ns = Context.NOTIFICATION_SERVICE;
            NotificationManager nMgr = (NotificationManager) getApplicationContext().getSystemService(ns);
            nMgr.cancel(notificationId);
        }
    }
    
}

I also put the ninja icon in our drawable folder, that’s the source of our icon.

Please share what Android notification example you want next!

Thanks for reading this Android Notification with Sound and Icon Tutorial!

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!

How to Send Data From Android to PHP Server? Android Post Request Help

Hi guys! Today we are going to code on how to send data from Android to PHP server. This is an example app that can post a file and text data to a web server with PHP file as a receiver. Having the ability to (do HTTP Post Request) post data from android app to remote server is required for most apps. Here are some example use of this functionality:

1. You want to get statistics on how your app is being used (you have to tell your user and they must agree of course!)
2. Your app has an upload file feature.
3. A user should register on your database before using more features of your app.

DOWNLOAD SOURCE CODE

Download HttpComponents Library

In this example, we are using a small library for posting a file, it is called the HttpComponents from the Apache Software Foundation. Please note that you won’t need this library if you’re just posting text data. The download can be found here: HttpComponents

  1. As of the moment, I downloaded the binary 4.2.3.zip
  2. When you extracted the zip file, find the lib folder and copy all the jar files there
  3. Copy those jar files to your project’s lib folder, here’s how to do that:
  4. Go to your workspace directory, find your project folder and inside, find the libs folder, put the jar files we extracted earlier
  5. Go back to eclipse and refresh your project files in the project explorer, now you can see the jar files inside your lib directory. See the screenshot below to visualize the goal of these 5 steps above.

Library Import - How to Send Data From Android to PHP Server?

How To Post Text Data?

// url where the data will be posted
String postReceiverUrl = "http://yourdomain.com/post_data_receiver.php";
Log.v(TAG, "postURL: " + postReceiverUrl);

// HttpClient
HttpClient httpClient = new DefaultHttpClient();

// post header
HttpPost httpPost = new HttpPost(postReceiverUrl);

// add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("firstname", "Mike"));
nameValuePairs.add(new BasicNameValuePair("lastname", "Dalisay"));
nameValuePairs.add(new BasicNameValuePair("email", "mike@testmail.com"));

httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
HttpEntity resEntity = response.getEntity();

if (resEntity != null) {
    
    String responseStr = EntityUtils.toString(resEntity).trim();
    Log.v(TAG, "Response: " +  responseStr);
    
    // you can add an if statement here and do other actions based on the response
}

How To Post A File?

You can use this code to post other file types such as an image.

// the file to be posted
String textFile = Environment.getExternalStorageDirectory() + "/sample.txt";
Log.v(TAG, "textFile: " + textFile);

// the URL where the file will be posted
String postReceiverUrl = "http://yourdomain.com/post_data_receiver.php";
Log.v(TAG, "postURL: " + postReceiverUrl);

// new HttpClient
HttpClient httpClient = new DefaultHttpClient();

// post header
HttpPost httpPost = new HttpPost(postReceiverUrl);

File file = new File(textFile);
FileBody fileBody = new FileBody(file);

MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("file", fileBody);
httpPost.setEntity(reqEntity);

// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
HttpEntity resEntity = response.getEntity();

if (resEntity != null) {
    
    String responseStr = EntityUtils.toString(resEntity).trim();
    Log.v(TAG, "Response: " +  responseStr);
    
    // you can add an if statement here and do other actions based on the response
}

Complete Android Code on How to Send Data From Android to PHP Server

This is our MainActivity.java code. In this code, we are:

  • Using AsyncTask to prevent the network on main thread error.
  • To test posting the text data, you must change the actionChoice variable value to 1.
  • Else if you are to test posting a sample file, you must change the actionChoice to 2. Also, don’t forget to put a sample.txt file in your SD card root directory.
package com.example.androidpostdatatophpserver;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

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 {

    private static final String TAG = "MainActivity.java";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // we are going to use asynctask to prevent network on main thread exception
        new PostDataAsyncTask().execute();
        
    }

    public class PostDataAsyncTask extends AsyncTask<String, String, String> {

        protected void onPreExecute() {
            super.onPreExecute();
            // do stuff before posting data
        }

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

                // 1 = post text data, 2 = post file
                int actionChoice = 2;
                
                // post a text data
                if(actionChoice==1){
                    postText();
                }
                
                // post a file
                else{
                    postFile();
                }
                
            } catch (NullPointerException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String lenghtOfFile) {
            // do stuff after posting data
        }
    }
    
    // this will post our text data
    private void postText(){
        try{
            // url where the data will be posted
            String postReceiverUrl = "http://yourdomain.com/post_data_receiver.php";
            Log.v(TAG, "postURL: " + postReceiverUrl);
            
            // HttpClient
            HttpClient httpClient = new DefaultHttpClient();
            
            // post header
            HttpPost httpPost = new HttpPost(postReceiverUrl);
    
            // add your data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("firstname", "Mike"));
            nameValuePairs.add(new BasicNameValuePair("lastname", "Dalisay"));
            nameValuePairs.add(new BasicNameValuePair("email", "mike@testmail.com"));
            
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    
            // execute HTTP post request
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity resEntity = response.getEntity();
            
            if (resEntity != null) {
                
                String responseStr = EntityUtils.toString(resEntity).trim();
                Log.v(TAG, "Response: " +  responseStr);
                
                // you can add an if statement here and do other actions based on the response
            }
            
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // will post our text file
    private void postFile(){
        try{
            
            // the file to be posted
            String textFile = Environment.getExternalStorageDirectory() + "/sample.txt";
            Log.v(TAG, "textFile: " + textFile);
            
            // the URL where the file will be posted
            String postReceiverUrl = "http://yourdomain.com/post_data_receiver.php";
            Log.v(TAG, "postURL: " + postReceiverUrl);
            
            // new HttpClient
            HttpClient httpClient = new DefaultHttpClient();
            
            // post header
            HttpPost httpPost = new HttpPost(postReceiverUrl);
            
            File file = new File(textFile);
            FileBody fileBody = new FileBody(file);
    
            MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
            reqEntity.addPart("file", fileBody);
            httpPost.setEntity(reqEntity);
            
            // execute HTTP post request
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity resEntity = response.getEntity();
    
            if (resEntity != null) {
                
                String responseStr = EntityUtils.toString(resEntity).trim();
                Log.v(TAG, "Response: " +  responseStr);
                
                // you can add an if statement here and do other actions based on the response
            }
            
        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The code above should give you a lot of clue on how to send data from Android to PHP server. But we have few more steps to do, continue to read below.

PHP file that will receive the posted data

This is the post_date_receiver.php code. You must upload it in your server and specify the URL to our MainActivity.java

<?php
// if text data was posted
if($_POST){
    print_r($_POST);
}

// if a file was posted
else if($_FILES){
    $file = $_FILES['file'];
    $fileContents = file_get_contents($file["tmp_name"]);
    print_r($fileContents);
}
?>

AndroidManifest.xml Code

Well, we are just having an INTERNET permission here.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.androidpostdatatophpserver"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.INTERNET" />
    
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.androidpostdatatophpserver.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Output Screenshots

Response is what post_date_receiver.php outputs when it receives the posted data.

android http example - posting text data output

Posting Text Data. The response array have our key-value pairs.

Posting Text File. The response is the content of my sample.txt file.

Posting Text File. The response is the content of my sample.txt file.

What do you think fo this code I came up with? If you have a better solution about how to send data from Android to PHP server, please let us know in the comments section below! We will add your solution or update this post if it deserves to, thanks!