Translate

Sunday, April 27, 2014

Reading from a file in Android

There are couple ways to read from a file in android. The file can be included as part of the Android Project in to the res directory Or the file can also be read from SD Card or internal storage. I will share couple ways to read the content of a file.

Method 1: Reading from res directory
Lets say we have a file called test.txt. The first thing we need to do is create a new folder called raw within the res directory and store the file there. So out file location will look like this

res/raw/test.txt

The following code snippet will read the content of this file into a String.
 
InputStream inputStream = this.getResources().openRawResource(
    R.raw.test);
  ByteArrayOutputStream bos = new ByteArrayOutputStream();
  
 
   int i = 0;
   try {
    while((i = inputStream.read())!=-1) {
     bos.write(i);
    }
    bos.close();
    inputStream.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  
  String content = bos.toString();
  Log.i("File Content is", content);



Method 2: Reading from External Storage/SD Card
say we have a file called test.txt in the root of sdcard. The following code snippet will read the file into a String object.
 
  File file = new File(Environment.getExternalStorageDirectory() + "/test.txt");
  try {
   FileReader fr = new FileReader(file);
   BufferedReader br = new BufferedReader(fr);
   StringBuffer sb = new StringBuffer();
   String line = "";
   while((line=br.readLine())!=null) {
    sb.append(line);
   }
   String content = sb.toString();
   Log.i("File Content is", content);
   br.close();
   fr.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }

This method requires Read External Storage permission declared in the manifest file
 
android.permission.READ_EXTERNAL_STORAGE


Let me know if you have any question on the comments...


Saturday, March 29, 2014

Encryption In Android

Andorid suppports javax.crypto package which offers different types of encryption. Here we will take a look at how AES encryption works in Android. We will write a utility class that offers both encryption and decryption. Following are the major classes we will be using to achieve the encryption and decryption


  • SecretKeySpec
  • IvParameterSpec
  • Cipher


At first we need to come up with a secret key and Initialization Vector Parameter which must be same in both the encrypt and decrypt method. Since these keys are constant we will declare them as final static.

 
private final static String key = "po#p!adfqwt#a$#2";
private final static String ivParam = "a#%^&*asksfafgha";

We can then instantiate SecretKeySpec and IvParameterSpec like this:

 
SecretKeySpec sKey = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivSpec = new IvParameterSpec(ivParam.getBytes());
Finally we use Cipher class to encrypt or decrypt whatever we are interested in like this:

 
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//For encryption
cipher.init(Cipher.ENCRYPT_MODE, sKey, ivSpec);
//For decryption
cipher.init(Cipher.DECRYPT_MODE, sKey, ivSpec);
byte[] encrptedBytes = cipher.doFinal("somePassword".getBytes());
Here is the entire class:

 

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec;

public class Encryption { private final static String key = "po#p!adfqwt#a$#2"; private final static String ivParam = "a#%^&*asksfafgha";

public String encrypt(String word) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { SecretKeySpec sKey = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivSpec = new IvParameterSpec(ivParam.getBytes()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, sKey, ivSpec); byte[] encryptedBytes = cipher.doFinal(word.getBytes()); return new String(encryptedBytes); }
public String decrypt(String word) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { SecretKeySpec sKey = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivSpec = new IvParameterSpec(ivParam.getBytes()); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, sKey, ivSpec); byte[] decryptedBytes = cipher.doFinal(word.getBytes()); return new String(decryptedBytes); } }



Saturday, September 21, 2013

Android App Development 201 5th tutorial; Consuming Web Service in Android: A Dictionary App!

In this tutorial we will look at how we can consume a SOAP based web service in android. Since android doesn't natively support SOAP protocol, we have to create custom functions that generates the request message dynamically and parses the response message to valuable content we are looking for. For this tutorial we will consume a Dictionary web service located here. We analyze the wsdl first to understand what are the functions available and how the request and response message look like. To analyze the WSDL we go to http://wsdlbrowser.com/. We will then enter the WSDL URL(http://services.aonaware.com/DictService/DictService.asmx?WSDL) and click on Browse. All the functions available will be listed in the left. The function we are interested in is the "define" function. When we click on the define function, it opens a page with editable request xml which allows us to enter a word and call the funtion. Here is the screenshot of how it looks like when we call a function with a word.
We will write a utility class that will have a method which returns us the request xml document with the word we are interested in. Here is how this method looks like
 
        @Override
 public Document generateRequestXml(String word) throws ParserConfigurationException {
  // TODO Auto-generated method stub
  Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
  document.setXmlVersion("1.0");
  Element rootElement = document.createElement("SOAP-ENV:Envelope");
  rootElement.setAttribute("xmlns:SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
  rootElement.setAttribute("xmlns:ns1", "http://services.aonaware.com/webservices/");
  Element firstNode = document.createElement("SOAP-ENV:Body");
  Element secondNode = document.createElement("ns1:Define");
  Element thirdNode = document.createElement("ns1:word");
  thirdNode.setTextContent(word);
  secondNode.appendChild(thirdNode);
  firstNode.appendChild(secondNode);
  rootElement.appendChild(firstNode);
  document.appendChild(rootElement);
  
  return document;
 }
As you can see the method takes a string parameter word which is populated in the right xml tag "ns1:word". When we look at the response message, we can see that the definations are populated in "WordDefination" element. So we will write another method in our utility class, which takes HttpResponse object as a parameter and gets all the values populated in this tag and puts them in an ArrayList of Strings.
@Override
 public ArrayList< string > generateWordDefination(HttpResponse response) throws IllegalStateException, IOException, SAXException, ParserConfigurationException {
  HttpEntity entity = response.getEntity();
  InputStream is = entity.getContent();
  BufferedReader br = new BufferedReader(new InputStreamReader(is));
  StringBuffer sb = new StringBuffer();
  String line = "";
  while ((line=br.readLine())!=null) {
  sb.append(line);
  }
  Document responseXml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(sb.toString())));
  NodeList nl = responseXml.getElementsByTagName("WordDefinition");
  ArrayList< string > definitions = new ArrayList< string >();
  for(int i=0 ; i < nl.getLength(); i++) {
  definitions.add(nl.item(i).getTextContent());
  }
  System.out.println(sb.toString());
  return definitions;
 }

Next We need to create a user interface to access the dictionary. We will have a simple EditText widget where the users will be able to enter the desired word to search, We will have a search button which triggers the web service call and generates the word definations and then we will have a listview which will be populated with the list of definations. Here is how the layout looks like:
Here is the layout code



<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context=".MainActivity" >



    <EditText

        android:id="@+id/editText1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentLeft="true"

        android:layout_alignParentTop="true"

        android:layout_marginTop="15dp"

        android:ems="10"

        android:hint="Type the word" />



    <Button

        android:id="@+id/button1"

        style="?android:attr/buttonStyleSmall"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignBottom="@+id/editText1"

        android:layout_alignParentRight="true"

        android:text="Search" />



    <ListView

        android:id="@+id/listView1"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_alignRight="@+id/button1"

        android:layout_below="@+id/editText1" >



    </ListView>



</RelativeLayout>


The last thing we need is a Activity class which triggers the web service call in the OnClick method of the search button. The web service will be called from an AsyncTask subclass within our Activity class. Once the word definations are obtained they are populated into the listview in the onPostExecute() method of the AsyncTask. Here is our Activity Class.
package com.peshal.dictionarywebservicetest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import com.peshal.utility.impl.DictionaryXmlGeneratorImpl;

public class MainActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  final Button button = (Button) findViewById(R.id.button1);
  final EditText word = (EditText) findViewById(R.id.editText1);
  
  
  button.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    System.out.println(word.getText().toString());
    new WebServiceCall().execute(word.getText().toString());
    
   }
   
  });
  
 }
class WebServiceCall extends AsyncTask< string,Void,Void > {
DictionaryXmlGeneratorImpl xmlGenerator = new DictionaryXmlGeneratorImpl();
ArrayList< string > definations = new ArrayList< string >();
@Override
protected Void doInBackground(String... params) {
 try {
  System.out.println(params[0]);
  Document req = xmlGenerator.generateRequestXml(params[0]);
  DOMSource requestXml = new DOMSource(req);
  HttpClient client = new DefaultHttpClient();
  HttpPost post = new HttpPost("http://services.aonaware.com/DictService/DictService.asmx");
  Transformer tf = TransformerFactory.newInstance().newTransformer();
   StringWriter writer = new StringWriter();
         StreamResult result = new StreamResult(writer);
  tf.transform((Source) requestXml, result);
  StringEntity se = new StringEntity(writer.toString());
  se.setContentType("text/xml");
  System.out.println("Request XML is : " +writer.toString() );
  post.setEntity(se);
  HttpResponse httpResponse = client.execute(post);
  definations = xmlGenerator.generateWordDefination(httpResponse);
  
 } catch (ParserConfigurationException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } catch (ClientProtocolException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } catch (TransformerException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } catch (IllegalStateException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 } catch (SAXException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 return null;
}
@Override
protected void onPostExecute(Void result) {
 final ListView listOfWords = (ListView) findViewById(R.id.listView1);
 ArrayAdapter< string > adapter = new ArrayAdapter< string >(MainActivity.this, android.R.layout.simple_list_item_1, definations);
 listOfWords.setAdapter(adapter);
 super.onPostExecute(result);
} 
}
}

As you can see, we use Android native Apache HttpClient to trigger a HTTP POST request with XML payload, The response xml is read as an InputStream into String Buffer which is then converted to DOM document. This document is then scanned for the element "WordDefinition" to read all the definitions into an ArrayList of String. This ArrayList is then added to ListAdapter to populate the word definitions into the ListView. Here is the screenshot of the resulting application.