Saturday, September 24, 2011

how to read line by line data from txt file in Android(JAVA) ?


URL url = new URL(
"http://dangalula.free.fr/psgtube/lesplusvues.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(
url.openStream()));

String theLine;
while ((theLine = in.readLine()) != null) {
Log.v("log_tag","line is :" +theLine);
}

Saturday, August 27, 2011

JSON Parsing in Android

1. Android and JSON

1.1. Android and JSON

JSON is a very condense data exchange format. Android includes the json.org libraries which allow to work easily with JSON files.

1.2. Twitter

Twitter is a great source for JSON. You can just call a URI and retrieve JSON. Here are some examples:

Table 1. Twitter URI's
URIDescription
http://twitter.com/statuses/user_timeline/vogella.json Get the timeline of user vogella .
http://search.twitter.com/search.json?q=android Search for the term "android" on Twitter.
http://twitter.com/statuses/user_timeline/vogella.json Returns the user data of user vogella .

Please note that some URI's return a JSONObject object while others return a JSONArray. The following coding uses an URI which returns an JSONArray.

2. Reading JSON

Create a new Android project "de.vogella.android.twitter.json" with the package "de.vogella.android.twitter.json" and the activity "ParseJSON".
Create the following coding for the activity. This will download the twitter feed for the user http://twitter.com/ and write the number of entries and the text messages to the Android log file.

package de.vogella.android.twitter.json;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class ParseJSON extends Activity {
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		String readTwitterFeed = readTwitterFeed();
	try {
		JSONArray jsonArray = new JSONArray(readTwitterFeed);
		Log.i(ParseJSON.class.getName(),
			"Number of entries " + jsonArray.length());
		for (int i = 0; i < jsonArray.length(); i++) {
		JSONObject jsonObject = jsonArray.getJSONObject(i);
		Log.i(ParseJSON.class.getName(), jsonObject.getString("text"));
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

	public String readTwitterFeed() {
	StringBuilder builder = new StringBuilder();
	HttpClient client = new DefaultHttpClient();
	HttpGet httpGet = new HttpGet(
		"http://twitter.com/statuses/user_timeline/vogella.json");
	try {
		HttpResponse response = client.execute(httpGet);
		StatusLine statusLine = response.getStatusLine();
		int statusCode = statusLine.getStatusCode();
		if (statusCode == 200) {
			HttpEntity entity = response.getEntity();
			InputStream content = entity.getContent();
			BufferedReader reader = new BufferedReader(
					new InputStreamReader(content));
			String line;
			while ((line = reader.readLine()) != null) {
				builder.append(line);
			}
		} else {
		Log.e(ParseJSON.class.toString(), "Failed to download file");
	}
	} catch (ClientProtocolException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	return builder.toString();
}
} 
 
 
To run this example assign the uses-permission to your "AndroidManifest.xml" for "android.permission.INTERNET".

3. Write JSON

Writing JSON is very simple. Just create the JSONObject or JSONArray and use the toString() method.
 

public void writeJSON() {
	JSONObject object = new JSONObject();
	try {
		object.put("name", "Jack Hack");
		object.put("score", new Integer(200));
		object.put("current", new Double(152.32));
		object.put("nickname", "Hacker");
	} catch (JSONException e) {
		e.printStackTrace();
	}
	System.out.println(object);
}
	

How to create LIve Wallpaper in Android ?

1.1. Live Wallpapers

Live Wallpapers are animated, interactive backgrounds for the Android homescreen. A live wallpaper is similar to other Android applications and can use most of the same functionality.
To create a live wallpaper, you need to create a XML file which describes your wallpaper. This file should contain a description of the application and can contain a preview and a link to a preference activity which allow to customize the live wallpaper.
You also maintain a service which must extend the abstract class "WallpaperService". "WallpaperService"is the base class for all live wallpapers in the system. You must implement the method onCreateEngine() and return an object of type "Engine". This engine will handle the life cycle events, animations and drawings of the wallpaper. Here you find life cycle hooks, as for example onCreate(), onSurfaceCreated(), onVisibilityChanged(), onOffsetsChanged(), onTouchEvent() and onCommand() .
This service requires the permission "android.permission.BIND_WALLPAPER" and must be registered via an intent-filter to the action "android.service.wallpaper.WallpaperService".
The service returns in its method onCreateEngine() an instance "android.service.wallpaper.WallpaperService.Engine". This class is responsible for handling the Live Wallpaper.
You should also maintain in your "AndroidManifest.xml" that your application uses the feature "android.software.live_wallpaper" in "AndroidManifest.xml". This will prevent that your wallpaper can be installed on devices which do not support live wallpapers.

2. Android Wallpaper Example

Create a new project "de.vogella.android.wallpaper". Do not create an Activity.
Create the folder "/res/xml" and maintain the following file "mywallpaper.xml. This file contains a description of your wallpaper and a preview graphic. You can also maintain a link to an activity which allow to configure your wallpaper. This resource file will be linked to from the "AndroidManifest.xml". You could also include the "android:thumbnail attribute" which would point to a drawable which gives a smaller image of the running wallpaper.


<?xml version="1.0" encoding="UTF-8"?>
<wallpaper 
xmlns:android="http://schemas.android.com/apk/res/android"
android:thumbnail="@drawable/icon"
android:description="@string/wallpaper_description"  
android:settingsActivity="de.vogella.android.wallpaper.MyPreferencesActivity"/>
 
	
Change your "AndroidManifest.xml" to the following to define your service ""MyWallpaperService" and to maintain the uses-feature. 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
	package="de.vogella.android.wallpaper" android:versionCode="1"
	android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">


<service android:name="MyWallpaperService" android:enabled="true"
android:permission="android.permission.BIND_WALLPAPER"
android:label="Wallpaper Example ">
	<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService"></action>
		</intent-filter>
	<meta-data android:name="android.service.wallpaper"
		android:resource="@xml/mywallpaper"></meta-data>
</service>
<activity android:label="@string/app_name" android:name=".MyPreferencesActivity"
	android:theme="@android:style/Theme.Light.WallpaperSettings"
	android:exported="true">
	</activity>
	</application>
	<uses-sdk android:minSdkVersion="10" />
	<uses-feature android:name="android.software.live_wallpaper"
		android:required="true"></uses-feature>

</manifest> 
 
We create the class "MyPoint" to save the elements we have drawn. 
 
				
package de.vogella.android.wallpaper;

public class MyPoint {
	String text;
	private int x;
	private int y;

	public MyPoint(String text, int x, int y) {
		this.text = text;
		this.x = x;
		this.y = y;
	}
}

			
		
Create a preference activity . Create the preference value files "prefs.xml" in the folder "res/xml".

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
	<CheckBoxPreference android:key="touch"
		android:title="Enable Touch"></CheckBoxPreference>
	<EditTextPreference android:key="numberOfCircles"
		android:title="Number of Circles"></EditTextPreference>
</PreferenceScreen>
 
 
Create the following coding for your preference activity. 
 
 
package de.vogella.android.wallpaper;

import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceActivity;
import android.widget.Toast;

public class MyPreferencesActivity extends PreferenceActivity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		addPreferencesFromResource(R.xml.prefs);

	// We want to add a validator to the number of circles so that it only
	// accepts numbers
	Preference circlePreference = getPreferenceScreen().findPreference(
			"numberOfCircles");

		// Add the validator
	circlePreference.setOnPreferenceChangeListener(numberCheckListener);
	}

	/**
	 * Checks that a preference is a valid numerical value
	 */
	Preference.OnPreferenceChangeListener numberCheckListener = 
new OnPreferenceChangeListener() {

	@Override
	public boolean onPreferenceChange(Preference preference,
Object newValue) {
		// Check that the string is an integer
		if (newValue != null && newValue.toString().length() > 0
				&& newValue.toString().matches("\\d*")) {
			return true;
		}
		// If now create a message to the user
		Toast.makeText(MyPreferencesActivity.this, "Invalid Input",
				Toast.LENGTH_SHORT).show();
			return false;
	}
	};

} 
 
Create the following coding for the Wallpaper Service. 
 
package de.vogella.android.wallpaper;

import java.util.ArrayList;
import java.util.List;

import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

public class MyWallpaperService extends WallpaperService {

	@Override
	public Engine onCreateEngine() {
		return new MyWallpaperEngine();
	}

	private class MyWallpaperEngine extends Engine {
		private final Handler handler = new Handler();
		private final Runnable drawRunner = new Runnable() {
			@Override
			public void run() {
				draw();
			}

		};
		private List<MyPoint> circles;
		private Paint paint = new Paint();
		private int width;
		int height;
		private boolean visible = true;
		private int maxNumber;
		private boolean touchEnabled;

		public MyWallpaperEngine() {
	SharedPreferences prefs = PreferenceManager
		.getDefaultSharedPreferences(MyWallpaperService.this);
		maxNumber = Integer
			.valueOf(prefs.getString("numberOfCircles", "4"));
			touchEnabled = prefs.getBoolean("touch", false);
			circles = new ArrayList<MyPoint>();
			paint.setAntiAlias(true);
			paint.setColor(Color.WHITE);
			paint.setStyle(Paint.Style.STROKE);
			paint.setStrokeJoin(Paint.Join.ROUND);
			paint.setStrokeWidth(10f);
			handler.post(drawRunner);
		}

		@Override
		public void onVisibilityChanged(boolean visible) {
			this.visible = visible;
			if (visible) {
				handler.post(drawRunner);
			} else {
				handler.removeCallbacks(drawRunner);
			}
		}

		

}
 
			@Override
		public void onSurfaceDestroyed(SurfaceHolder holder) {
			super.onSurfaceDestroyed(holder);
			this.visible = false;
			handler.removeCallbacks(drawRunner);
		}

		@Override
		public void onSurfaceChanged(SurfaceHolder holder, int format,
				int width, int height) {
			this.width = width;
			this.height = height;
			super.onSurfaceChanged(holder, format, width, height);
		}

		@Override
		public void onTouchEvent(MotionEvent event) {
			if (touchEnabled) {

				float x = event.getX();
				float y = event.getY();
				SurfaceHolder holder = getSurfaceHolder();
				Canvas canvas = null;
				try {
					canvas = holder.lockCanvas();
			if (canvas != null) {
				canvas.drawColor(Color.BLACK);
				circles.clear();
				circles.add(new MyPoint(
				String.valueOf(circles.size() + 1), x, y));
				drawCircles(canvas, circles);
				}
			} finally {
				if (canvas != null)
				holder.unlockCanvasAndPost(canvas);
			}
			super.onTouchEvent(event);
		}
	}
		private void draw() {
	SurfaceHolder holder = getSurfaceHolder();
	Canvas canvas = null;
		try {
			canvas = holder.lockCanvas();
			if (canvas != null) {
				if (circles.size() >= maxNumber) {
					circles.clear();
				}
			int x = (int) (width * Math.random());
			int y = (int) (height * Math.random());
	circles.add(new MyPoint(String.valueOf(circles.size() + 1),
						x, y));
					drawCircles(canvas, circles);
				}
			} finally {
				if (canvas != null)
					holder.unlockCanvasAndPost(canvas);
			}
			handler.removeCallbacks(drawRunner);
			if (visible) {
				handler.postDelayed(drawRunner, 5000);
			}
		}

		// Surface view requires that all elements are drawn completely
		private void drawCircles(Canvas canvas, List<MyPoint> circles) {
			canvas.drawColor(Color.BLACK);
			for (MyPoint point : circles) {
			canvas.drawCircle(point.x, point.y, 20.0f, paint);
			}
		}
	}
 
 
If you start your application and set this wallpaper as
background your emulator should similar to the following. If you have
Touch enabled via the preferences you can click on the screen to
remove the existing circles, also via the settings you can define the
number of circles which should be displayed.