Wednesday, May 25, 2011

Basic calls for getting the location data from Android

The following is some basic calls to the GPS to retreive either the WIFI or cellular locations. The following code is NOT battery optimized, but serve as the starting point for location retreival

LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
updateLocation(location);  // define your own function here
}

public void onStatusChanged(String provider, int status, Bundle extras) {
Log.v(TAG, "onStatusChanged");
}

public void onProviderEnabled(String provider) {
Log.v(TAG, "onProviderEnabled");
}

public void onProviderDisabled(String provider) {
Log.v(TAG, "onProviderDisabled");
}
};

LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
Constant.GPS_REQUEST_TIME, 0, locationListener);
} else {
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,
Constant.GPS_REQUEST_TIME, 0, locationListener);
}


The location object will give you access to the longtitude and latitude.

Friday, May 13, 2011

Android - a rounded corner background panel

This example demonstrates how you can create an image by xml declaration. You will use the <shape> xml object and this file will need to be put in the image directories. The following example shows how to build a red oval panel and a white box panel.


drawable-mdpi/white_box.xml - white rounded corner box

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#FFFFFF"/>
    <corners android:radius="5px"/>
    <padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>

drawable-mdpi/red_box.xml - red oval shaped box

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#FF0000"/>
    <corners android:radius="20px"/>
    <padding android:left="5dp" android:top="0dp" android:right="5dp" android:bottom="0dp" />
</shape>

res/values/styles.xml


We will create a customStyle to use these panels.


<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="customStyle">
        <item name="android:textColor">#ffffff</item>
        <item name="android:textStyle">bold</item>
        <item name="android:textSize">12dip</item>
        <item name="android:gravity">center</item>
        <item name="android:background">@drawable/red_box</item>
  </style>
</resources>

Using the white box panel

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<TextView android:id="@+id/tv" android:layout_width="wrap_content" style="@style/customStyle"
android:layout_height="wrap_content" android:layout_margin="50dip" android:text="demo text"/>
</RelativeLayout>

Friday, May 6, 2011

Android - How to add a header and a footer to listView

In the following example we add a previous button in the header, next button in the footer.


Activity Code:

ListView list = getListView();
View headerView = View.inflate(this, R.layout.header, null);
list.addHeaderView(headerView);
View footerView = View.inflate(this, R.layout.footer, null);
list.addFooterView(footerView);


Header XML Layout - header.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:padding="5dip">

<Button android:id="@+id/previous"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" />

</RelativeLayout>


Footer XML Layout - footer.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:padding="5dip">

<Button android:id="@+id/next"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" />

</RelativeLayout>

Thursday, May 5, 2011

Android - How to Boot a Service When You Turn on the Phone

A typical usage for booting services when a phone starts is a message pull notification system. In the following, I have written a BoardcastReceiver to listen to the system boot event.


First, Create a BroadcastReciever:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class ActivateAtBootReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {

Intent i = new Intent();
i.setAction("com.pof.android.MessageService");
context.startService(i);

}
}

}

In AndroidManifest.xml,

Add the following permission inside the manifest tag:

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


Add the following to inside the application tag:


<service android:name=".MessageService"
android:process=":MessageService"
android:label="Message Notification">
<intent-filter>
<action android:name="com.pof.android.MessageService">
</action>
</intent-filter>
</service>

<receiver android:name=".ActivateAtBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED">
</action>
<category android:name="android.intent.category.HOME">
</category>
</intent-filter>
</receiver>

Note: MessageService is created by me. You will want to replace that with your own service.

Android - How to Hide a Button Dynamically

The following shows how to hide the view image button when a user's profile has no images.

Button viewImagesButton = (Button) findViewById(R.id.view_images_button);
if(images.size() <= 0) {
viewImagesButton.setVisibility(android.view.View.INVISIBLE);
}

Similarily you can show the button by:

viewImagesButton.setVisibility(android.view.View.VISIBLE);

Wednesday, May 4, 2011

Android Java - how to stream UTF-8 bytes using HttpURLConnection

Here's the code I have written for communication between the Android app and the backend server. You may want to encrypt your byte data.

Note that in the following code, I do not depend on the Content-Length to get the data. I use a 4096 byte buffer to read data until there are no data. I used to depend on the Content-Length to retrieve data from the data. However, when I was testing using Nexus S on Android SDK 2.3, the content length was null. After some investigation, I found that the server was sending gzip data and it wipes out the content length variable.


Here's the http connection code:

public static String getHttpWithResponse(String urlStr, byte[] data) {
 
  String responseFromServer = null;
  HttpURLConnection con = null;
 
  try {

   URL url = new URL(urlStr);
   con = (HttpURLConnection) url.openConnection();
   con.setReadTimeout(50000);
   con.setConnectTimeout(20000);

   con.setRequestProperty("Connection", "Keep-Alive");

   con.setInstanceFollowRedirects(true);
   con.setRequestProperty("Content-Type",
     "application/x-www-form-urlencoded");

   con.setRequestMethod("GET");

   con.setDoInput(true);
  
   if (data != null) {

    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****************************************";

    con.setRequestMethod("POST");
    con.setDoOutput(true);
    con.setRequestProperty("Content-Type",
      "multipart/form-data;boundary=" + boundary);
    con.setRequestProperty("Content-Disposition",
      "multipart/form-data");
    OutputStream o = con.getOutputStream();
    o.write(data, 0, data.length);
    o.close();
   } else {
    con.setInstanceFollowRedirects(true);
    con.setRequestProperty("Content-Type",
      "application/x-www-form-urlencoded");

    con.setRequestMethod("GET");
   }
  
   if (con.getResponseCode() != HttpURLConnection.HTTP_OK) {
    throw new Exception("Response is not empty");
   }
  
   InputStream i = con.getInputStream();
  
   ByteArrayOutputStream bs = new ByteArrayOutputStream();
   byte[] bytesToRead = new byte[4096];

   int actuallyRead = 0;

   while (true) {
    int currentlyRead = i.read(bytesToRead, 0,
      bytesToRead.length);

    if (currentlyRead <= 0)
     break;

    bs.write(bytesToRead, 0, currentlyRead);
    actuallyRead += currentlyRead;

   }

   bytesToRead = null;
   i.close();

   if (actuallyRead < 0) {
    throw new Exception("Nothing Read");
   }

   bytesToRead = bs.toByteArray();

   responseFromServer = new String(bytesToRead, "UTF-8");
  
  } catch (Exception e) {
   responseFromServer = null;
  } finally {
   if (con != null) {
    con.disconnect();
   }
  }

  return responseFromServer;
 }

Tuesday, May 3, 2011

How to dynamically change TextView font color in Android

The following is an easy way to change the font color dynamically in activities.

Activity Code:

String msg = "Hello World!";
TextView tv = (TextView) findViewById(R.id.tv);
txt.setText(Html.fromHtml("<font color='green'>" + msg + "</font>"));

XML layout Code:

<TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content"/>