Wednesday, January 02, 2013

Android: Checking if Internet is available

The following method is very useful in android when you have to check if the internet is available on the device.

public boolean isNetworkAvailable(Context c) {

ConnectivityManager cm = (ConnectivityManager)c.getSystemService(Context.CONNECTIVITY_SERVICE);

return cm.getActiveNetworkInfo() != null


&& cm.getActiveNetworkInfo().isConnectedOrConnecting();

}

Android: Downloading a file to an external directory

In most of our applications we encounter a scenario where we have to download a file and then open it from our app. The file may be a pdf or an image.

So lets see the code for the same. I will be using the same HttpResponseContainerVO described previously.

Since we are downloading a file, instead of encoding the response in the VO, I am storing the file in the path and returning the absolute path of the file in response.

Downloading file:

public static HttpResponseContainerVO downloadPDFFile(String url,

String name)

throws ClientProtocolException, IOException {



if (!isExternalStorageAvailable()) {

throw new IOException("External Storage is not Available");
//Use internal storage or Cache or Temp folder to store the files.
}
HttpResponseContainerVO responseVo = new HttpResponseContainerVO();

DefaultHttpClient client = new DefaultHttpClient();


String filePath = getFilePath(name);
HttpGet get = new HttpGet(url);

 
// Add the headers....

HttpResponse response = client.execute(get);

HttpEntity entity = response.getEntity();


responseVo.setResponseCode(response.getStatusLine().getStatusCode());

Header[] headers = response.getAllHeaders();
for (Header hdr : headers) {
//Set the headers
 }


InputStream inputStream = entity.getContent();
FileOutputStream content = new FileOutputStream(new File(filePath));

// Read response into a buffered stream

int readBytes = 0;

byte[] sBuffer = new byte[512];

while ((readBytes = inputStream.read(sBuffer)) != -1) {


content.write(sBuffer, 0, readBytes);

}

content.flush();

content.close();

responseVo.setResponse(filePath);
return responseVo;

}


Getting external file path:

private static String getFilePath(String name) {


String fileDir = Environment.getExternalStorageDirectory()
.getAbsolutePath() +"YOUR DIRECTORY HERE";

String fileName = name + "Extension";

File dir = new File(fileDir);

if (!dir.exists()) {


dir.mkdirs();

}
return fileDir + fileName;


}

Now you have successfully downloaded and stored the file in the external / internal storage. How do you open this file from your app? Simple, follow the code below.


Uri path = Uri.fromFile(new File(VO.getResponse()));

Intent intent = new Intent(Intent.ACTION_VIEW);


intent.setDataAndType(path,
        "MIME TYPE OF THE CONTENT");

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

try {

startActivity(intent);
} catch (ActivityNotFoundException e) {

Toast.makeText(CONTEXT, MESSAGE,

Toast.LENGTH_LONG).show();


}

 

Android: Posting data to server & reading response

In the last post we saw how to do a get request using HttpClient in android. Now lets see how to do a post request, wherein we send some data to the server and then read the response.
 
The below code uses the HttpResponseContainerVO object from the previous post to retrieve the data.
 
 
public static HttpResponseContainerVO getPostResponse(String url,
final byte[] data)
throws IOException {
 
 
HttpResponseContainerVO responseVo = new HttpResponseContainerVO();
 

HttpPost post = new HttpPost(url);
// Add the headers
post.addHeader(new BasicHeader("Accept","application/json"));
 
post.setEntity(new HttpEntity() {
 

@Override
public void writeTo(OutputStream outstream) throws IOException {
 
outstream.write(data);
}

@Override
public boolean isStreaming() {
return false;
 
}

@Override
public boolean isRepeatable() {
return false;
 
}

@Override
public boolean isChunked() {
return false;
 
}

@Override
public Header getContentType() {
return new BasicHeader("Content-Type","application/json");
 
}

@Override
public long getContentLength() {
return data.length;
 
}

@Override
public Header getContentEncoding() {
return null;
 
}

@Override
public InputStream getContent() throws IOException,
 
IllegalStateException {
InputStream is = new ByteArrayInputStream(data, 0, data.length);
return is;
 
}

@Override
public void consumeContent() throws IOException {
 

}
});

DefaultHttpClient client = new DefaultHttpClient();
 
HttpResponse response = client.execute(post);
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
ByteArrayOutputStream content = new ByteArrayOutputStream();
 
responseVo.setResponseCode(response.getStatusLine().getStatusCode());
Header[] headers = response.getAllHeaders();
for (Header hdr : headers) {
//Store the required headers
 
}

// Read response into a buffered stream
int readBytes = 0;
byte[] sBuffer = new byte[512];
while ((readBytes = inputStream.read(sBuffer)) != -1) {
 
content.write(sBuffer, 0, readBytes);
}
responseVo.setResponse(new String(content.toByteArray()));
 

return responseVo;
 
}

That's all :)

Friday, December 28, 2012

Android: Using HttpClient to execute GET requests

The following code shows a simple utility method that will execute a HTTP GET Request and return the response in a simple Value Object.

Class that is used to hold the HTTP Response from the server.

public class HttpResponseContainerVO {

//Add any additional headers you require.
private int responseCode;

private long contentLength;

private long requestTime;

private int cacheControl;

private String contentType;

private String response;

 // Getters and Setters for all the fields.
}

Method to query and retrieve the Contents of a URL

public static HttpResponseContainerVO getResponse(String url,
Map params)
throws IOException {
 
HttpResponseContainerVO responseVo = new HttpResponseContainerVO();

DefaultHttpClient client = new DefaultHttpClient();

HttpGet get = new HttpGet(url);
if (params != null && !params.isEmpty()) {
// Add the params to GET object in the URL
// ? & ...
}

 
//Setting headers
get.addHeader(new BasicHeader("User-Agent", "--VALUE---"));

 
HttpResponse response = client.execute(get);
HttpEntity entity = response.getEntity();

responseVo.setResponseCode(response.getStatusLine().getStatusCode());
Header[] headers = response.getAllHeaders();
for (Header hdr : headers) {
  
//Read all the headers and set value to responseVO

}

InputStream inputStream = entity.getContent();
ByteArrayOutputStream content = new ByteArrayOutputStream();

// Read response into a buffered stream
int readBytes = 0;
byte[] sBuffer = new byte[512];
while ((readBytes = inputStream.read(sBuffer)) != -1) {
content.write(sBuffer, 0, readBytes);
}
responseVo.setResponse(new String(content.toByteArray()));

return responseVo;
}

Thursday, December 27, 2012

Android Tips n Tricks

Putting together some android tricks that I had to adopt to make my application work on all the different screen resolutions.

One of the first troubles I had with android was making sure that the header we had developed looked the same for every screen resolution in both the portrait and landscape mode.

The header image we developed consisted of 3 parts

  1. Logo on the left
  2. Logout button on the right
  3. Page heading at the center.

Sample shown below:

Now that you have seen the image, lets come to the problem. Even if we generate the image in the 3:4:6:8 ratios that android suggest we still face the problem on screens with different resolutions with the image being stretched and looking awkward. < br/> In order to overcome this we simply split the images into 3 parts. You can split it into 'n' parts depending on your requirement.
The three parts corresponding to the three things we needed to display as as follows.

Now to get a consistent header all we had to do was use a Relative Layout and arrange the images as follows:

1. Arrange the image with logo to the left of the screen.
2. Arrange the image with logout to the right of the screen.
3. Arrange the blank background image such that its left edge touches the right edge of the logo and the right edge touches the left edge of the logout. Thus stretching the plain image on every screen resolution.

Simple enough. Use similar techniques in your projects to get consistent look and feel across various screen resolutions.

Monday, December 17, 2012

The Angel

I had made my peace with my maker. I was just counting days till I met him. Locked up in the darkest room in the dungeon I was at peace finally.

In a world where surviving each day is difficult, I tried to stand up to the weak. To uphold the values of truth & justice. That was my fatal flaw. Hoping that the common man would rise with me if I started the rebellion. I had heard that all it took was one person to start a revolution. When I saw no one else stepping up, I tried and failed.

Captured, Tortured and Branded a traitor to the realm, I was sentenced to die by hanging at the next full moon. It was seven days away.

It was then that I realized that there was only one way to survive in this world. Be selfish. Do whatever is good for you and your family. Do not care about others - for no one will stand with you when the chips are down. As the saying goes - we win as a team and fail as individuals. I had failed and accepted it.

As I laid there - chained and hungry - unaware of the time that had passed since I was condemned, I heard footsteps for the first time. With great effort I pulled myself up to stand. I did not want them to see my weakness. I did not want them seeing me lying down ready to die. I had to be defiant to my executioners. I know I had stood up for a right thing and I would die in that knowledge.

As the footsteps grew louder I tried to focus my vision to see my executioners. At last I saw something moving towards me. They had a light. Dear sweet light. Light I had not seen in an eternity. All I could make with my blurred vision was a piercing light moving towards me. I just stood there frozen with eyes closed. Finally the shadows spoke - "Water". It was not my executioners. It was the voice of an angel. I opened my eyes and tried to see who it was but she was already moving away from me. All I could see was her shadow falling on me as she moved away with the light and a bowl of water laid down in front of me.

That was all I needed, dropping to me knees I picked up the bowl and drank from it as if there was no tomorrow. As I put the bowl down and lifted my head I saw her turn to have a look at the man who was branded a traitor and condemned to die.

For the first time since my capture I could see someone who felt pity for me. I could see that much in her face. I was not expecting it but after seeing me in the eye she turned around and walked back to me.

She walked up to me and sat down with her legs crossed putting the light between us. I could see her clearly now. I knew at that instant - in an other time, in an other life, if things had been different I would have knelt in front of her with a flower and asked her to marry me.

Looking at her and dreaming, I forgot to speak. It was her voice that broke the silence. She said she understood why I had started the rebellion and from the bottom of her heart she supported my cause. She said had she had any training with the swords she would have picked up one and fought beside me, unfortunately she was just a simple girl who worked in the prison serving food.

After that I was hardly able to comprehend what she was saying, my mind drifted. I did not know if it was the hunger or the water. I just laid down and I could hear her voice - as if she was speaking from a very distant location. Slowly the light around me started to fade and the voice grew distant. Finally the light went out and all I could hear was a distant blur of a noise and then everything just went blank.

Silence. Peace. No more pain, no more worries. As death embraced me in its arms and carried me to a better place, I was given one final glimpse of the dungeon. There I saw my lifeless body and the angel sitting next to me and patting my head.

The End.