Android Series: Display device CPU and Memory info

Posted by admin | Posted in Code Snippets, Mobile Development | Posted on 07-02-2011

1

Today I will post a short snippet on how to display cpu and memory info of our andorid device. The program uses external utilities to get the device info by calling cat on ‘/proc/meminfo’ and ‘/proc/cpuinfo’.
The activity displaying the data from the ‘cat’ output is displayed in a TextView contained withing ‘ScrollView’.

This is the output of the cat command running in emulator on my machine:

Layout file:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ScrollView01"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content">
<LinearLayout
 android:orientation="vertical"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 >
 <TextView
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:textColor="#FF0000"
 android:text="CPU Info:"
 />
<TextView
 android:id="@+id/cpuinfo"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 />
 <TextView
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:textColor="#0000FF"
 android:text="Memory Info:"
 />
<TextView
 android:id="@+id/memoryinfo"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 />
</LinearLayout>
</ScrollView>

Main activity:

package com.softwarepassion;

import java.io.IOException;
import java.io.InputStream;

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

public class CpuSpeed extends Activity {
private TextView cpuInfo;
private TextView memoryInfo;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
cpuInfo = (TextView) findViewById(R.id.cpuinfo);
cpuInfo.setText(getCPUinfo());
memoryInfo = (TextView)findViewById(R.id.memoryinfo);
memoryInfo.setText(getMemoryInfo());
}

private String getMemoryInfo(){
ProcessBuilder cmd;
String result = new String();

try{
String[] args = {"/system/bin/cat", "/proc/meminfo"};
cmd = new ProcessBuilder(args);

Process process = cmd.start();
InputStream in = process.getInputStream();
byte[] re = new byte[1024];
while(in.read(re) != -1){
System.out.println(new String(re));
result = result + new String(re);
}
in.close();
} catch(IOException ex){
ex.printStackTrace();
}
return result;
}
private String getCPUinfo()
{
ProcessBuilder cmd;
String result="";

try{
String[] args = {"/system/bin/cat", "/proc/cpuinfo"};
cmd = new ProcessBuilder(args);

Process process = cmd.start();
InputStream in = process.getInputStream();
byte[] re = new byte[1024];
while(in.read(re) != -1){
System.out.println(new String(re));
result = result + new String(re);
}
in.close();
} catch(IOException ex){
ex.printStackTrace();
}
return result;
}
}

You don’t need to modify anything inside AndroidManifest.xml file.

Android Series: Download files with Progress Dialog

Posted by admin | Posted in Code Snippets, Mobile Development | Posted on 05-02-2011

25

Today, I will present a short tutorial on how to download files in android displaying at the same time download progress based on the bytes downloaded. For the purpose of this tutorial we will use build in AsyncTask mechanism together with ProgressDialog class.
The whole application consists of one activity displaying a ‘Start Download’ button. Clicking our start button we initialize file download passing to the asynctask the url or the resource we want to download.


AndroAsync.java

package com.softwarepassion;

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class AndroAsync extends Activity {
   
    public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
    private Button startBtn;
    private ProgressDialog mProgressDialog;
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        startBtn = (Button)findViewById(R.id.startBtn);
        startBtn.setOnClickListener(new OnClickListener(){
            public void onClick(View v) {
                startDownload();
            }
        });
    }

    private void startDownload() {
        String url = "http://farm1.static.flickr.com/114/298125983_0e4bf66782_b.jpg";
        new DownloadFileAsync().execute(url);
    }
    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case DIALOG_DOWNLOAD_PROGRESS:
                mProgressDialog = new ProgressDialog(this);
                mProgressDialog.setMessage("Downloading file..");
                mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                mProgressDialog.setCancelable(false);
                mProgressDialog.show();
                return mProgressDialog;
            default:
                return null;
        }
    }
    class DownloadFileAsync extends AsyncTask<String, String, String> {
       
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showDialog(DIALOG_DOWNLOAD_PROGRESS);
        }

        @Override
        protected String doInBackground(String... aurl) {
            int count;

            try {
                URL url = new URL(aurl[0]);
                URLConnection conexion = url.openConnection();
                conexion.connect();

                int lenghtOfFile = conexion.getContentLength();
                Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);

                InputStream input = new BufferedInputStream(url.openStream());
                OutputStream output = new FileOutputStream("/sdcard/some_photo_from_gdansk_poland.jpg");

                byte data[] = new byte[1024];

                long total = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;
                    publishProgress(""+(int)((total*100)/lenghtOfFile));
                    output.write(data, 0, count);
                }

                output.flush();
                output.close();
                input.close();
            } catch (Exception e) {}
            return null;

        }
        protected void onProgressUpdate(String... progress) {
             Log.d("ANDRO_ASYNC",progress[0]);
             mProgressDialog.setProgress(Integer.parseInt(progress[0]));
        }

        @Override
        protected void onPostExecute(String unused) {
            dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
        }
    }
}

layout file (main.xml) :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   >
<TextView  
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="@string/hello"
   />
<Button
    android:text="Start long running task.."
    android:id="@+id/startBtn"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
</Button>
</LinearLayout>

While downloadin a file from the internet remember to add INTERNET permission in AndroidManifest.xml

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

Check your sd card folder for what was downloaded and enjoy!

Android Series: Creating custom dialogs

Posted by admin | Posted in Code Snippets, Mobile Development | Posted on 03-02-2011

5

Every android developer will face one day a need to create a custom dialog, where the user has to input some data for processing or any other purposes. This post is a short tutorial on how to create a custom dialog in android, dimming the background activity and asking user to input a string for a search query.
Custom dialog is implemented as another activity and treated as dialog by using special option in AndroidManifest.xml (listed at the end of this post).
The whole application consists of two activities (main + custom dialog), two small layout xml files and a modified AndroidManifest.xml.


AndroDialog (main activity)

package com.softwarepassion;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class AndroDialog extends Activity {

private Button startDialogBtn;
private static final int MY_CUSTOM_DIALOG = 0;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startDialogBtn = (Button)findViewById(R.id.startdialog);
startDialogBtn.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
startCustomDialog();
}
});
}

/**
* Starts an Activity which in this case is a custom
* dialog, as specified in AndroidManifest.xml
*/

private void startCustomDialog() {
Intent intent = new Intent(this,SearchDialog.class);
startActivityForResult(intent, MY_CUSTOM_DIALOG);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case (MY_CUSTOM_DIALOG) : {
if (resultCode == Activity.RESULT_OK) {
Log.d("ANDRO_DIALOG","Coming back from the search dialog..");
String searchQuery = data.getStringExtra(SearchDialog.SEARCH_QUERY_RESULT_FROM_DIALOG);
Log.d("ANDRO_DIALOG", "Search query result: " + searchQuery);
}
break;
}
}
}
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    />
<Button android:text="Show Custom Dialog"
    android:id="@+id/startdialog"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
</Button>
</LinearLayout>

SearchDialog.java (custom dialog activity)

package com.softwarepassion;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;

public class SearchDialog extends Activity{

public static final String SEARCH_QUERY_RESULT_FROM_DIALOG = "SEARCH_DIALOG";
private Button searchBtn;
private Button cancelBtn;
private EditText searchEdit;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_dialog);
searchBtn = (Button)findViewById(R.id.search);
searchBtn.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
returnSearchQuery();
}
});
cancelBtn = (Button)findViewById(R.id.cancel);
cancelBtn.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
cancelDialog();
}
});
searchEdit = (EditText)findViewById(R.id.search_query);
searchEdit.setText("query");
getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

}
private void returnSearchQuery(){
Intent resultIntent = new Intent(this, SearchDialog.class);
resultIntent.putExtra(SEARCH_QUERY_RESULT_FROM_DIALOG, searchEdit.getText().toString());
setResult(Activity.RESULT_OK, resultIntent);
finish();
}
private void cancelDialog(){
finish();
}
}

custom dialog xml layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/layout_root"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:padding="10dp">
    <EditText android:id="@+id/search_query"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>
    <LinearLayout android:orientation="horizontal"
    android:background="@android:drawable/bottom_bar" android:paddingLeft="4.0dip"
    android:paddingTop="5.0dip" android:paddingRight="4.0dip"
    android:paddingBottom="1.0dip" android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <Button android:id="@+id/search" android:layout_width="0.0dip"
        android:layout_height="fill_parent" android:text="Search"
        android:layout_weight="1.0" />
    <Button android:id="@+id/cancel" android:layout_width="0.0dip"
        android:layout_height="fill_parent" android:text="Cancel"
        android:layout_weight="1.0" />
</LinearLayout>
</LinearLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.softwarepassion"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".AndroDialog"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="SearchDialog"
          android:label="Search Dialog"
          android:theme="@android:style/Theme.Dialog"/>
    </application>
</manifest>

Hope this helps anyone needing to write a custom dialog for the android platform.

Android Series: Utilizing Camera ‘Share via..” option

Posted by admin | Posted in Mobile Development | Posted on 30-01-2011

1

If you have ever build an android app which required you to use a camera, you should consider a different flow in your application, starting not from your app itself but from the built in android Camera application.
Let’s say you want to post a photo on twitter or facebook. In you standard flow you would open the application XXX, choose the options to take the photo and finally go to the activity responsible for sending that photo.
There is another way to do it, user chooses to open internal andorid Camera application, takes the photo and then chooses ‘Share via..’ option menu.
This is how to include your activity for handling image taken by the external Camera app in the ‘Share via ‘ option list.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.softwarepassion.androcamera"
     android:versionCode="1"
     android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".AndroCamera"
                 android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".CamSender"
                 android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="image/*" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Assuming AndroCamera is the main activity, where a standard application flow starts, and CamSender activity is responsible for manipulating/sending the photo only.
To get the data in the activity responsible for handling received image you should call getExtras(..) and retrieve the data stream

package com.softwarepassion.androcamera;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class CamSender extends Activity {

    private Uri imageUri;
    private ImageView imageView;
   
    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        setContentView(R.layout.camsender);
        imageView = (ImageView)findViewById(R.id.img);
       
        imageUri = (Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM);
        imageView.setImageURI(imageUri);
    }
   
}

Android Series: Taking photos with Andorid built in camera

Posted by admin | Posted in Mobile Development | Posted on 29-01-2011

4

Today I will describe how to take a photo in android application using the built in camera. The way to do it is to simply start ‘activity for result’ instead of simple ‘activity’ and specify android camera application as our activity.
Then, once a picture is taken with a nice built in camera application, we can get it back in our app for further processing:

Main activity class:

package com.softwarepassion.androcamera;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class AndroCamera extends Activity {
    private static final int IMAGE_CAPTURE = 0;
    private Button startBtn;
    private Uri imageUri;
    private ImageView imageView;

    /** Called when the activity is first created.
     *  sets the content and gets the references to
     *  the basic widgets on the screen like
     *  {@code Button} or {@link ImageView}
     */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        imageView = (ImageView)findViewById(R.id.img);
        startBtn = (Button) findViewById(R.id.startBtn);
        startBtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                startCamera();
            }
        });
    }

    public void startCamera() {
        Log.d("ANDRO_CAMERA", "Starting camera on the phone...");
        String fileName = "testphoto.jpg";
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE, fileName);
        values.put(MediaStore.Images.Media.DESCRIPTION,
                "Image capture by camera");
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        imageUri = getContentResolver().insert(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
        startActivityForResult(intent, IMAGE_CAPTURE);
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == IMAGE_CAPTURE) {
            if (resultCode == RESULT_OK){
                Log.d("ANDRO_CAMERA","Picture taken!!!");
                imageView.setImageURI(imageUri);
            }
        }
    }
}

and layout xml (main.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   >
<Button android:text="Start Camera"
    android:id="@+id/startBtn"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
</Button>
<ImageView android:id="@+id/img"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
</ImageView>
</LinearLayout>

Android Series: GET, POST and Multipart POST requests

Posted by admin | Posted in Code Snippets, Mobile Development | Posted on 18-03-2010

56

Today I will describe shortly how to execute http GET and POST request on Android platform.
The code is very simple and straightforward, for post request with attachement, you would have to add apache-mime4j-0.6.jar and httpmime-4.0.1.jar to your build path.

HTTP GET

try {
        HttpClient client = new DefaultHttpClient();  
        String getURL = "http://www.google.com";
        HttpGet get = new HttpGet(getURL);
        HttpResponse responseGet = client.execute(get);  
        HttpEntity resEntityGet = responseGet.getEntity();  
        if (resEntityGet != null) {  
                    //do something with the response
                    Log.i("GET RESPONSE",EntityUtils.toString(resEntityGet));
                }
} catch (Exception e) {
    e.printStackTrace();
}

HTTP POST

     try {
        HttpClient client = new DefaultHttpClient();  
        String postURL = "http://somepostaddress.com";
        HttpPost post = new HttpPost(postURL);
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("user", "kris"));
            params.add(new BasicNameValuePair("pass", "xyz"));
            UrlEncodedFormEntity ent = new UrlEncodedFormEntity(params,HTTP.UTF_8);
            post.setEntity(ent);
            HttpResponse responsePOST = client.execute(post);  
            HttpEntity resEntity = responsePOST.getEntity();  
            if (resEntity != null) {    
                Log.i("RESPONSE",EntityUtils.toString(resEntity));
            }
    } catch (Exception e) {
        e.printStackTrace();
    }

HTTP POST with File attachment

File file = new File("path/to/your/file.txt");
try {
         HttpClient client = new DefaultHttpClient();  
         String postURL = "http://someposturl.com";
         HttpPost post = new HttpPost(postURL);
     FileBody bin = new FileBody(file);
     MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);  
     reqEntity.addPart("myFile", bin);
     post.setEntity(reqEntity);  
     HttpResponse response = client.execute(post);  
     HttpEntity resEntity = response.getEntity();  
     if (resEntity != null) {    
               Log.i("RESPONSE",EntityUtils.toString(resEntity));
         }
} catch (Exception e) {
    e.printStackTrace();
}

Hope this helps!

Android Series: Using GPS data

Posted by admin | Posted in Code Snippets, Mobile Development | Posted on 15-03-2010

2

In this tutorial i will show you how to quickly get the gps data using your android device version 1.6+.

All you have to do is to implement one interface and acquire LocationMangager from the adnroid system service.

public class LocationExampleAct extends Activity implements LocationListener{


    private double latitude;
    private double longitude;
    private LocationManager locMgr = null;
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
   
        locationTxt = (TextView)findViewById(R.id.location_id);
       
        locMgr = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
        locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
       
    }
   
    @Override
    public void onLocationChanged(Location location) {
        this.latitude = location.getLatitude();
        this.longitude = location.getLongitude();
        this.locationTxt.setText("Location: "+this.latitude +" : " + this.longitude);
        Log.i("Location change",""+latitude+ " : "+longitude) ;
    }
    @Override
    public void onProviderDisabled(String provider) {
       
    }
    @Override
    public void onProviderEnabled(String provider) {
       
    }
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
       
    }
}

Android Series: Parsing JSON data with GSON

Posted by admin | Posted in Code Snippets, Mobile Development | Posted on 25-02-2010

18

Today I will describe how to parse json data using Gson open source library and how to convert it at the same time to java objects.
This is a typical cookbook example and should be very easy to follow.


1. Create an Android application with one activity, name it as you wish, if you are doing it in eclipse all the basic stuff will be generated for you which is exactly what we need.
2. Find an example url which responds in JSON, I have used Twitter Trends found here: http://search.twitter.com/trends.json
The example response looks like this:

{"as_of":"Thu, 25 Feb 2010 11:30:17 +0000","trends":[{"name":"#nowplaying","url":"http://search.twitter.com/search?q=%23nowplaying"},{"name":"#nothingworsethan","url":"http://search.twitter.com/search?q=%23nothingworsethan"},{"name":"Dubai Mall","url":"http://search.twitter.com/search?q=%22Dubai+Mall%22"},{"name":"iPad Gets","url":"http://search.twitter.com/search?q=%22iPad+Gets%22"},{"name":"#SuperJuniorTrot","url":"http://search.twitter.com/search?q=%23SuperJuniorTrot"},{"name":"Justin Bieber","url":"http://search.twitter.com/search?q=%22Justin+Bieber%22"},{"name":"Click","url":"http://search.twitter.com/search?q=Click"},{"name":"Jaebum","url":"http://search.twitter.com/search?q=Jaebum"},{"name":"#tosavemoney","url":"http://search.twitter.com/search?q=%23tosavemoney"},{"name":"Protection","url":"http://search.twitter.com/search?q=Protection"}]}



As you can see this json data contains date attribute called ‘as_of’ as well as array of items, each consisting of name and url attributes.
We will create two simple java classes wich will hold that information.
First one is TwitterTrends.java

package com.softwarepassion.jsonexample;

import java.util.Date;
import java.util.List;

public class TwitterTrends {

    private String as_of;
    private List<TwitterTrend> trends;
   
    public String getAs_of() {
        return as_of;
    }
    public void setAs_of(String asOf) {
        as_of = asOf;
    }
    public List<TwitterTrend> getTrends() {
        return trends;
    }
    public void setTrends(List<TwitterTrend> trends) {
        this.trends = trends;
    }
   
   
   
}

And the second one is a simple TwitterTrend.java

package com.softwarepassion.jsonexample;

public class TwitterTrend {
    private String name;
    private String url;
   
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
}

TwitterTrends contains a list of TwitterTrend objects, both of them are simple beans and are very similar to the json response if you look closely :) .

Now the fun part begins.

Download the Gson library from http://code.google.com/p/google-gson/ and add it to your java build path in eclipse.
Once you do that, you can now transform your json response to Java object on Android Platform:
Get the response as InputStream:

public InputStream getJSONData(String url){
        DefaultHttpClient httpClient = new DefaultHttpClient();
        URI uri;
        InputStream data = null;
        try {
            uri = new URI(url);
            HttpGet method = new HttpGet(uri);
            HttpResponse response = httpClient.execute(method);
            data = response.getEntity().getContent();
        } catch (Exception e) {
            e.printStackTrace();
        }
       
        return data;
    }

Then use that input stream to create your java objects:

public void runJSONParser(){
        try{
        Log.i("MY INFO", "Json Parser started..");
        Gson gson = new Gson();
        Reader r = new InputStreamReader(getJSONData("http://search.twitter.com/trends.json"));
        Log.i("MY INFO", r.toString());
        TwitterTrends objs = gson.fromJson(r, TwitterTrends.class);
        Log.i("MY INFO", ""+objs.getTrends().size());
        for(TwitterTrend tr : objs.getTrends()){
            Log.i("TRENDS", tr.getName() + " - " + tr.getUrl());
        }
        }catch(Exception ex){
            ex.printStackTrace();
        }
    }

Easy ha!

Android Series: Custom ListView items and adapters

Posted by admin | Posted in Mobile Development | Posted on 20-05-2009

249

This is a short tutorial on how to populate your android list view, with data downloaded from the internet or other sources, using ArrayAdapter. ListView items view is declared in a separate XML file and displayed using custom adapter class.
First things first, so go ahead and create a new project using Eclipse equipped with ADT plugin.
The project described below assumes you have a list of objects created, this can be either downloaded from the internet as XML and parsed to create ArrayList of your custom objects or anything you imagine. I will not go into details on this tutorial how to create such an ArrayList but your imagination is the limit. Parsing XML downloaded from the net will be covered in the next tutorial coming up soon.


Click File -> New -> Project and select the ‘Android Project’ wizard:

android11

Click next and fill out the next screen with the following values:

android21

Once you have filled out all the necessary data you can click finish.
Your new project has just been created. Now lets modify it a bit to display our custom made list.
Open up SoftwarePassionView.java in the eclipse editor and change the class file to the following:

1. Define necessary member variables we will use later in our class

    private ProgressDialog m_ProgressDialog = null;
    private ArrayList<Order> m_orders = null;
    private OrderAdapter m_adapter;
    private Runnable viewOrders;

m_ProgressDialog is a small pop up displaying information that your data is being downloaded or retrieved other way.
m_orders is an ArrayList which will hold our data downloaded from the internet or acquired other way
m_adapter is our custom class extending ArrayAdapter
viewOrders is a runnable for downloading data from the internet in a separate thread

To import whatever you can at this point click Ctrl+Shift+O, some classes like Order or OrderAdapter are not created yet but don’t worry we will come to that point soon.
Another important note at this point is that your SoftwarePassoinView should extend ListActivity instead of simple Activity.
Your class should look more or less something like this now:

package com.softberries.lve;

import java.util.ArrayList;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.os.Bundle;

public class SoftwarePassionView extends ListActivity{
   
    private ProgressDialog m_ProgressDialog = null;
    private ArrayList<Order> m_orders = null;
    private OrderAdapter m_adapter;
    private Runnable viewOrders;
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

Now lets create our simple Order class holding single order.
Right click on the project and and select ‘New’ -> ‘Class’, name it order and open it up in the editor.
The source code for our orders looks like this:

package com.softberries.lve;

public class Order {
   
    private String orderName;
    private String orderStatus;
   
    public String getOrderName() {
        return orderName;
    }
    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }
    public String getOrderStatus() {
        return orderStatus;
    }
    public void setOrderStatus(String orderStatus) {
        this.orderStatus = orderStatus;
    }
}

The Order class is very simple and contains only 2 strings with getters and setter generated for them
Now lets change our main.xml file to hold our custom list items:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   >
<ListView
    android:id="@+id/android:list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    />
<TextView
    android:id="@+id/android:empty"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:text="@string/main_no_items"/>
</LinearLayout>

This layout will display our list items if any and if the list is empty it will display ‘No orders to display’ string defined in string.xml resource file.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, SoftwarePassionView!</string>
    <string name="app_name">Software Passion</string>
    <string name="main_no_items">No orders to display</string>
</resources>



Our list item (single row on the list) have a custom layout as well, defined in row.xml file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="6dip">
    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_marginRight="6dip"
        android:src="@drawable/icon" />
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:layout_height="fill_parent">
        <TextView
            android:id="@+id/toptext"
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:gravity="center_vertical"
        />
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:id="@+id/bottomtext"
            android:singleLine="true"
            android:ellipsize="marquee"
        />
    </LinearLayout>
</LinearLayout>

Single row example has been borrowed from the romain Guy website here

Ok, so we have all our layouts defined in the res folder under layout. Now its time to go back to our code and create our custom OrderAdapter class which will manage our list of orders:

private class OrderAdapter extends ArrayAdapter<Order> {

        private ArrayList<Order> items;

        public OrderAdapter(Context context, int textViewResourceId, ArrayList<Order> items) {
                super(context, textViewResourceId, items);
                this.items = items;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
                View v = convertView;
                if (v == null) {
                    LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    v = vi.inflate(R.layout.row, null);
                }
                Order o = items.get(position);
                if (o != null) {
                        TextView tt = (TextView) v.findViewById(R.id.toptext);
                        TextView bt = (TextView) v.findViewById(R.id.bottomtext);
                        if (tt != null) {
                              tt.setText("Name: "+o.getOrderName());                            }
                        if(bt != null){
                              bt.setText("Status: "+ o.getOrderStatus());
                        }
                }
                return v;
        }
}

This is a private class and should be added to our SoftwarePassionView. This is extended ListAdapter which inside overriden getView method returns our row with assigned string values to the textfields defined in row.xml.

A huge part of our application is already done. Now we have to add some modifications to the onCreate method to initialize everything properly and add a method retrieving our orders from somewhere, lets start with the latter:

private void getOrders(){
          try{
              m_orders = new ArrayList<Order>();
              Order o1 = new Order();
              o1.setOrderName("SF services");
              o1.setOrderStatus("Pending");
              Order o2 = new Order();
              o2.setOrderName("SF Advertisement");
              o2.setOrderStatus("Completed");
              m_orders.add(o1);
              m_orders.add(o2);
                 Thread.sleep(2000);
              Log.i("ARRAY", ""+ m_orders.size());
            } catch (Exception e) {
              Log.e("BACKGROUND_PROC", e.getMessage());
            }
            runOnUiThread(returnRes);
        }



Instead of creating our simple orders in the method above you could of course download them from somewhere and assign the result to the m_orders array list. The method runOnUIThread is a utility method for running tasks back on the main UI thread after the job is done on the separate thread created for long running tasks. We will call our getOrders method from a separate thread.

The returnRes runnable adds newly retrieved Order object to our custom Adapter and notifies it of the data change:

private Runnable returnRes = new Runnable() {

            @Override
            public void run() {
                if(m_orders != null && m_orders.size() > 0){
                    m_adapter.notifyDataSetChanged();
                    for(int i=0;i<m_orders.size();i++)
                    m_adapter.add(m_orders.get(i));
                }
                m_ProgressDialog.dismiss();
                m_adapter.notifyDataSetChanged();
            }
          };

Now lets move to our overriden onCreate method. We will initialize here all the member variables as well as start a new thread retrieving our orders:

       @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        m_orders = new ArrayList<Order>();
        this.m_adapter = new OrderAdapter(this, R.layout.row, m_orders);
                setListAdapter(this.m_adapter);
       
        viewOrders = new Runnable(){
            @Override
            public void run() {
                getOrders();
            }
        };
    Thread thread =  new Thread(null, viewOrders, "MagentoBackground");
        thread.start();
        m_ProgressDialog = ProgressDialog.show(SoftwarePassionView.this,    
              "Please wait...", "Retrieving data ...", true);
    }

After initialization, we start new thread using the viewOrders runnable and show the progress dialog which we close once the orders are retrieved.
Now you should be able to run your application. After the application starts it spawns new thread and displays the loader:

screen_load screen1

And thats it. You can add an Item Click Listener to your list to start new activities etc.
Full source code for the SoftwarePassionView below:

package com.softberries.lve;

import java.util.ArrayList;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class SoftwarePassionView extends ListActivity{
   
    private ProgressDialog m_ProgressDialog = null;
    private ArrayList<Order> m_orders = null;
    private OrderAdapter m_adapter;
    private Runnable viewOrders;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        m_orders = new ArrayList<Order>();
        this.m_adapter = new OrderAdapter(this, R.layout.row, m_orders);
        setListAdapter(this.m_adapter);
       
        viewOrders = new Runnable(){
            @Override
            public void run() {
                getOrders();
            }
        };
        Thread thread =  new Thread(null, viewOrders, "MagentoBackground");
        thread.start();
        m_ProgressDialog = ProgressDialog.show(SoftwarePassionView.this,    
              "Please wait...", "Retrieving data ...", true);
    }
    private Runnable returnRes = new Runnable() {

        @Override
        public void run() {
            if(m_orders != null && m_orders.size() > 0){
                m_adapter.notifyDataSetChanged();
                for(int i=0;i<m_orders.size();i++)
                m_adapter.add(m_orders.get(i));
            }
            m_ProgressDialog.dismiss();
            m_adapter.notifyDataSetChanged();
        }
    };
    private void getOrders(){
          try{
              m_orders = new ArrayList<Order>();
              Order o1 = new Order();
              o1.setOrderName("SF services");
              o1.setOrderStatus("Pending");
              Order o2 = new Order();
              o2.setOrderName("SF Advertisement");
              o2.setOrderStatus("Completed");
              m_orders.add(o1);
              m_orders.add(o2);
              Thread.sleep(5000);
              Log.i("ARRAY", ""+ m_orders.size());
            } catch (Exception e) {
              Log.e("BACKGROUND_PROC", e.getMessage());
            }
            runOnUiThread(returnRes);
        }
    private class OrderAdapter extends ArrayAdapter<Order> {

        private ArrayList<Order> items;

        public OrderAdapter(Context context, int textViewResourceId, ArrayList<Order> items) {
                super(context, textViewResourceId, items);
                this.items = items;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
                View v = convertView;
                if (v == null) {
                    LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    v = vi.inflate(R.layout.row, null);
                }
                Order o = items.get(position);
                if (o != null) {
                        TextView tt = (TextView) v.findViewById(R.id.toptext);
                        TextView bt = (TextView) v.findViewById(R.id.bottomtext);
                        if (tt != null) {
                              tt.setText("Name: "+o.getOrderName());                            }
                        if(bt != null){
                              bt.setText("Status: "+ o.getOrderStatus());
                        }
                }
                return v;
        }
}
}



Enjoy!

New discovery for MIDP development

Posted by admin | Posted in Mobile Development | Posted on 17-01-2009

1


Just wanted to spread the word about my new discovery. About a year ago I was adding finishing touches to my final year project on University of Greenwich and I remember that one of the biggest problems was to come up with a nicely looking UI for my mobile application. I’ve used SVG and I have to say that the effect was ‘ok’, could be much better but building up applications with svg was in my opinion difficult. I had to concentrate my efforts on the web services but spent most of my time building up GUI. Well, after a year I’ve incidently found a nice and promising open source project which would solve this using CSS techniques and two small libraries, the project is named KUIX and you can find out more about it on the kalmeo.org website. I have to add that I tried Java ME Polish and for me KUIX way of doing things is much simpler.
You can check out the demo here
Enjoy!