Monday 28 February 2011

Simple guide to speaking foreign languages | zen habits

Want to learn a foreign language here's how: Simple guide to speaking foreign languages | zen habits.



Now the only questions is, how do I get myself sent to Prague for 3 months. :)

Saturday 26 February 2011

Android SDK cannot detect JDK

Normally I develop Android on Linux machine, and just tried to install the new version of Android SDK on my Windows 7 machine today. I download the exe version of Android SDK, installer_r10-windows.exe. And run it, it's complained by Android SDK Tools Setup that Java SE Development Kit not found. No matter how I config my Windows 7 and JDK!!!

Android SDK cannot detect JDK

Finally I found out the solution:
- Press Back button on the error page
- Press Next again.
- OK !!!

Friday 25 February 2011

How to Add VCards to Thunderbird

At work, we have this really nice staff directory. However, it only exports a person's entry in VCard format. But Thunderbird doesn't have a way to import a VCard. Or does it? To add a VCard to a Thunderbird Address Book do the following.

  1. Save the VCard to a file.

  2. Attach the VCard file to an email message and send it to yourself.

  3. When you receive the message, the VCard will be attached along with a small icon that represents a person.

  4. Click on the icon, and Thunderbird will provide a popup that adds the VCard to your address book.

That's it. Saves a bunch of typing.



Thanks to MacWorld hints for the idea.

Get Network Info

We can get all network info by calling getAllNetworkInfo() method of ConnectivityManager object.

Get All Network Info

AndroidNetworkInfo.java
package com.exercise.AndroidNetworkInfo;

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

import android.app.ListActivity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class AndroidNetworkInfo extends ListActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ConnectivityManager connectivityManager
= (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] networkInfo
= connectivityManager.getAllNetworkInfo();

List<String> listNetworkInfo = new ArrayList<String>();
for(int i=0; i<networkInfo.length; i++){
listNetworkInfo.add(networkInfo[i].toString());
}

setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
listNetworkInfo));
getListView().setTextFilterEnabled(true);
}
}


Modify AndroidManifest.xml to grant permission to access network state
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exercise.AndroidNetworkInfo"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="4" />

<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".AndroidNetworkInfo"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>


Download the files.

Necessitas: port of Qt on Android

Necessitas is the codename for the port of Qt on the Android Operating System and of the user-friendly Qt Creator Integration with Android,

This project provides you Qt for the Android Operating System, and a first-class citizen IDE letting you manage, develop, deploy, run & debug your Qt Applications on Android Devices.

To see more, you can click here to get videos of the port, or you can test Qt on your Android Device by installing a demo from the Google Market.

What is Ministro ?

Necessitas is also the Home of Ministro, an Android application which provides a system wide downloader and installer of the LGPL Qt shared libraries. You can find Ministro on the Android Market or as direct download here.



Necessitas Home>>>

Thursday 24 February 2011

Detect phone flipping

By checking Android's build-in accelerometer sensor status, we can detect the phone flipping (face-up/face-down).

Detect phone flipping

package com.exercise.AndroidDetectFlipping;

import java.util.List;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;

public class AndroidDetectFlipping extends Activity {

SensorManager sensorManager;
Sensor accelerometerSensor;
boolean accelerometerPresent;

TextView face;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

face = (TextView)findViewById(R.id.face);

sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
if(sensorList.size() > 0){
accelerometerPresent = true;
accelerometerSensor = sensorList.get(0);
}
else{
accelerometerPresent = false;
face.setText("No accelerometer present!");
}
}

@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if(accelerometerPresent){
sensorManager.registerListener(accelerometerListener, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}

@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
if(accelerometerPresent){
sensorManager.unregisterListener(accelerometerListener);
}
}

private SensorEventListener accelerometerListener = new SensorEventListener(){

@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub

}

@Override
public void onSensorChanged(SensorEvent arg0) {
// TODO Auto-generated method stub
float z_value = arg0.values[2];
if (z_value >= 0){
face.setText("Face UP");
}
else{
face.setText("Face DOWN");
}
}};

}


<?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"
/>
<TextView
android:id="@+id/face"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>


Download the files.

Related articles:
- Get the list of available sensors, SensorManager.getSensorList()
- Detect Android Accelerometer sensor changed
- Detect Shaking

Data visualization of global Android device activations

Global Android Activations, Oct '08 - Jan '11


Wednesday 23 February 2011

HP redesigns and refreshes EliteBook and ProBook laptops -- Engadget

Microsoft Logo

HP gets down to business with redesigned and refreshed EliteBook and ProBook laptops (hands-on) -- Engadget



Engadget has the latest on HP's business line of laptops. If you are looking for a nice solid laptop with a matte finished screen, check these out. They may not be as sleek as a MacBook Pro, but they are just as functional and cost about $1000 less.

Tuesday 22 February 2011

Full SDK for Android 3.0 is now available


The full SDK for Android 3.0 is now available to developers. The APIs are final, and you can now develop apps targeting this new platform and publish them to Android Market. The new API level is 11.

For an overview of the new user and developer features, see the Android 3.0 Platform Highlights.

Together with the new platform, the SDK Tools (r10) and ADT Plugin for Eclipse (10.0.0) have been updated also.

To get started developing or testing applications on Android 3.0, visit the Android Developers site for information about the Android 3.0 platform, the SDK Tools, and the ADT Plugin.

Source:
http://android-developers.blogspot.com/2011/02/final-android-30-platform-and-updated.html

Apple Earbud Cheat Sheet

Ever forget the commands for those fancy earbuds from Apple? Well Blue Sky Workshop is here to help. Here is a small table showing all the click commands for the Apple ear buds.



The link below the table is special. If you click it and bookmark it on your mobile device, you will have the commands listed in the table stored locally on your device. This is possible because all the data for the table is stored in the bookmark using an HTML trick. So if you need a ear bud cheat sheet for your mobile device, enjoy!



















































Action Commands
Play/Pause Press center button
Vol Up Press plus or top button
Vol Down Press minus or bottom button
Skip Double click center
Fast Forward Double click and hold second click
Skip Back Triple click
Rewind Triple click and hold last click
Answer Call/Hang Up Click center button
Deny Incoming Call Hold down center for 2 seconds

Click this link and bookmark to view this document offline

TinyUmbrella - Fix Recovery Beta

TinyUmbrella 4.21.12 is out with beta support of the nasty 4.2.1 recovery loop fix. I've finished the OSX version and am currently working on the windows version. As soon as the windows version is fixed, I'll update the links.




*IMPORTANT*

In order for the 'Fix Recovery' button to be enabled you must put your device in DFU. Once the 'Fix Recovery' button is enabled, click the button then click 'Yes' on the confirmation and wait. Your device should reboot out of the recovery loop!




Huge credit and thanks to westbaer and the rest of the team (cdev team) greenpois0n makes this all possible.

Monday 21 February 2011

2010 State of the Computer Book Market - The Languages

Internet IconEvery year O'Reilly media writes a few posts on the state of the computer book market. It gives a lot of insite into what languages and tools developers are interested in. So for 2010 here is the post:

2010 State of the Computer Book Market - The Languages



Java is back in the #1 position. Right where it should be! :)

Detect Shaking

By comparing previous and current reading of build-in accelerometer sensor, shaking of android device can be detected.

Detect Shaking

In this exercise, three SeekBar is used to adjust the sensitive of x, y, z. The changing rate are compare with the sensitive to detect shaking.

<?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"
/>
<SeekBar
android:id="@+id/xsensitive"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="100"
/>
<TextView
android:id="@+id/x"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/xrate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/xstate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<SeekBar
android:id="@+id/ysensitive"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="100"
/>
<TextView
android:id="@+id/y"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/yrate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/ystate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<SeekBar
android:id="@+id/zsensitive"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="100"
/>
<TextView
android:id="@+id/z"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/zrate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/zstate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


package com.exercise.AndroidDetectShaking;

import java.util.List;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;

public class AndroidDetectShaking extends Activity {

TextView text_x, text_xrate, text_xstate;
TextView text_y, text_yrate, text_ystate;
TextView text_z, text_zrate, text_zstate;
SeekBar seekbar_x, seekbar_y, seekbar_z;

SensorManager sensorManager;
Sensor accelerometerSensor;
boolean accelerometerPresent;

float SensitiveX, SensitiveY, SensitiveZ;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

seekbar_x = (SeekBar)findViewById(R.id.xsensitive);
text_x = (TextView)findViewById(R.id.x);
text_xrate = (TextView)findViewById(R.id.xrate);
text_xstate = (TextView)findViewById(R.id.xstate);
seekbar_y = (SeekBar)findViewById(R.id.ysensitive);
text_y = (TextView)findViewById(R.id.y);
text_yrate = (TextView)findViewById(R.id.yrate);
text_ystate = (TextView)findViewById(R.id.ystate);
seekbar_z = (SeekBar)findViewById(R.id.zsensitive);
text_z = (TextView)findViewById(R.id.z);
text_zrate = (TextView)findViewById(R.id.zrate);
text_zstate = (TextView)findViewById(R.id.zstate);

seekbar_x.setOnSeekBarChangeListener(seekbar_sensitiveOnSeekBarChangeListener);
seekbar_y.setOnSeekBarChangeListener(seekbar_sensitiveOnSeekBarChangeListener);
seekbar_z.setOnSeekBarChangeListener(seekbar_sensitiveOnSeekBarChangeListener);

sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
if(sensorList.size() > 0){
accelerometerPresent = true;
accelerometerSensor = sensorList.get(0);
}
else{
accelerometerPresent = false;
}
}

SeekBar.OnSeekBarChangeListener seekbar_sensitiveOnSeekBarChangeListener
= new SeekBar.OnSeekBarChangeListener(){

@Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
// TODO Auto-generated method stub
if (arg0 == seekbar_x){
SensitiveX = (float)arg1;
}else if (arg0 == seekbar_y){
SensitiveY = (float)arg1;
}else if (arg0 == seekbar_z){
SensitiveZ = (float)arg1;
}
}

@Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}

@Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}};

@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if(accelerometerPresent){
sensorManager.registerListener(accelerometerListener, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}

@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
if(accelerometerPresent){
sensorManager.unregisterListener(accelerometerListener);
}
}

private SensorEventListener accelerometerListener = new SensorEventListener(){

float lastx, lasty, lastz;
long lasttime;
boolean firsttime = true;

@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}

@Override
public void onSensorChanged(SensorEvent arg0) {
// TODO Auto-generated method stub
float x_value = arg0.values[0];
float y_value = arg0.values[1];
float z_value = arg0.values[2];
text_x.setText(String.valueOf(x_value));
text_y.setText(String.valueOf(y_value));
text_z.setText(String.valueOf(z_value));

long currenttime = System.currentTimeMillis();
if(!firsttime){
long deltatime = currenttime - lasttime;
float xrate = Math.abs(x_value - lastx) * 10000/deltatime;
float yrate = Math.abs(y_value - lasty) * 10000/deltatime;
float zrate = Math.abs(z_value - lastz) * 10000/deltatime;
text_xrate.setText(String.valueOf(xrate));
text_yrate.setText(String.valueOf(yrate));
text_zrate.setText(String.valueOf(zrate));

if (xrate>SensitiveX){
text_xstate.setText("Shaking:)");
}else{
text_xstate.setText("");
}

if (yrate>SensitiveY){
text_ystate.setText("Shaking:)");
}else{
text_ystate.setText("");
}

if (zrate>SensitiveZ){
text_zstate.setText("Shaking:)");
}else{
text_zstate.setText("");
}
}
lasttime = currenttime;
lastx = x_value;
lasty = y_value;
lastz = z_value;
firsttime = false;
}
};
}


Download the files.

Sunday 20 February 2011

Detect Android Accelerometer sensor changed

Detect Android Accelerometer sensor changed

package com.exercise.AndroidAccelerometer;

import java.util.List;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;

public class AndroidAccelerometer extends Activity {

SensorManager sensorManager;
boolean accelerometerPresent;
Sensor accelerometerSensor;

TextView x, y, z;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
x = (TextView)findViewById(R.id.x);
y = (TextView)findViewById(R.id.y);
z = (TextView)findViewById(R.id.z);

sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
if(sensorList.size() > 0){
accelerometerPresent = true;
accelerometerSensor = sensorList.get(0);
}
else{
accelerometerPresent = false;
}
}

@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if(accelerometerPresent){
sensorManager.registerListener(accelerometerListener, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}

@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
if(accelerometerPresent){
sensorManager.unregisterListener(accelerometerListener);
}
}

private SensorEventListener accelerometerListener = new SensorEventListener(){

@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub

}

@Override
public void onSensorChanged(SensorEvent arg0) {
// TODO Auto-generated method stub
float x_value = arg0.values[0];
float y_value = arg0.values[1];
float z_value = arg0.values[2];
x.setText(String.valueOf(x_value));
y.setText(String.valueOf(y_value));
z.setText(String.valueOf(z_value));
}};
}


<?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"
/>
<TextView
android:id="@+id/x"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/y"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/z"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


Download the files.

next:
- Detect Shaking
- Detect phone flipping

Friday 18 February 2011

Small Update - Download size decreased

I just pushed a smaller, trimmed-down version of TinyUmbrella. This change had to take precedence over the other things I was working on for TinyUmbrella because the bandwidth usage was insane. Now that this is out of the way, I can go back to the 4.2.1 recovery kick out issue. Have a great weekend folks!

The Daily has made me a USA Today Reader

Yes its true. Newscorp's The Daily application for the iPad has turned me into a USA Today reader on the iPad. Here is my take.



When The Daily came out about two weeks ago, I was really intrigued. A news application with a staff like a newspaper. New content will be created on a daily basis with a focus on media designed for the iPad. All for about $50 a year subscription. A great price compared to my local newspaper. So I read The Daily for about a week and here are the conclusions I came to.



Good Things about The Daily

  • All the articles are beautiful and well written. I really liked how the articles looked. Someone on the staff has a good eye for design.

  • The 360 degree photos are really cool. Basically it is like standing on the spot where the news is happening and looking around.

  • Great photos. Lots of slide shows with high res photos. Very nice.

  • I liked the shorter form articles myself. I am really not that interested in 10 page articles. (A criticism I have heard on a number of podcasts.)

  • The news, life, and sports sections are very good.



The Bad Things about The Daily
  • It takes too long to load. This has been a universal criticism. Instead of loading the front page and loading the rest in the background, you have to wait like a minute for the whole thing to load. Way to slow.

  • Content is a little thin. I thought there could be a few more stories in each section to give the paper a little more weight. The tech section suffered the most from this.

  • Local sports coverage not good enough. Even though I'm sure they can't cover local sports, they could at least provide AP feeds and do the stats really well. Compared to just about any sports website on the net, their stats are kinda lame.

  • No business section. Really?  You guys own the Wall Street Journal for goodness sake.

  • Not much in the way of personalization.

So on the whole, I think the negatives outweigh the positives. To make The Daily work this is what I think they need to do.
  • Partner with others to provide more content. This could be existing NewCorp properties or external. But they need more content than is provided right now. For example, I would love business news from the Journal, soccer news from Sky Sports, and tech news from All Things D. All NewsCorp properties.

  • Focus on curation and creation. Creating your own content is great. But I want someone to help me find the great stories and blog posts out there on the Internet.  If you can find 5 great stories per day in a category, I would pay for that.

  • Be part of the net. Don't be afraid to link to content. In addition, integrate with twitter and Facebook. Let folks look at their feed while in your app. 



USA Today

So to compare The Daily to something, I started reading the USA Today iPad app on a daily basis. By the end of about a week I was really enjoying reading it. And so, since I like it better and the price is better (free), I plan to use this as my national paper app of choice for the time being. Here is why.



  • It loads fast. Open the app and whatever page or section you are on, loads in a second or two. Very fast.

  • More content, but not too much. Each section has more content, but not so much that I am drowning in it.

  • Good Tech and Business sections. All the sections are good and there are more of them.

  • Simple user interface. Although not as fancy as The Daily, it is a lot easier to use. Anybody can figure it out in about 5 minutes.

So right now, I plan on using USA Today for the near term. But I will keep my eye on The Daily. Given the number of properties NewsCorp has and the potential that is there, they could still come up with a killer app in a few months. 


Get the list of available sensors, SensorManager.getSensorList()

The class android.hardware.SensorManager provide a method getSensorList(). Use this method to get the list of available sensors of a certain type, or use Sensor.TYPE_ALL to get all the sensors.

Get the list of available sensors, SensorManager.getSensorList()

package com.exercise.AndroidSensorList;

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

import android.app.ListActivity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class AndroidSensorList extends ListActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SensorManager sensorManager
= (SensorManager)getSystemService(Context.SENSOR_SERVICE);
List<Sensor> listSensor
= sensorManager.getSensorList(Sensor.TYPE_ALL);

List<String> listSensorType = new ArrayList<String>();
for(int i=0; i<listSensor.size(); i++){
listSensorType.add(listSensor.get(i).getName());
}

setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
listSensorType));
getListView().setTextFilterEnabled(true);
}
}


Download the files.

Related Article:
- Detect rotation around X, Y & Z axis, using SensorManager and SensorEventListener
- Detect Android Accelerometer sensor changed

Thursday 17 February 2011

What Does Google Know About You?

Google LogoEver wonder what Google knows about you?  Well here is a small peek:



http://www.google.com/ads/preferences/view



It is the interest categories Google uses to serve you ads. The page allows you to opt out if you so desire.

Display Gallery selected image using BitmapFactory

In last exercise "Select Image using Android build-in Gallery", we ask Android build-in Gallery app help to select image, with uri returned. In this exercise, BitmapFactory is used to load the image.

Display Gallery selected image using BitmapFactory

Modify main.xml to add a ImageView to display the returned image
<?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:id="@+id/loadimage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Load Image"
/>
<TextView
android:id="@+id/targeturi"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/targetimage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>


Modify the code to load image using BitmapFactory.
package com.exercise.AndroidSelectImage;

import java.io.FileNotFoundException;

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

public class AndroidSelectImage extends Activity {

TextView textTargetUri;
ImageView targetImage;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonLoadImage = (Button)findViewById(R.id.loadimage);
textTargetUri = (TextView)findViewById(R.id.targeturi);
targetImage = (ImageView)findViewById(R.id.targetimage);

buttonLoadImage.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 0);
}});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);

if (resultCode == RESULT_OK){
Uri targetUri = data.getData();
textTargetUri.setText(targetUri.toString());
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri));
targetImage.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}


Remark@2012-07-14: Recently found that it cannot display large image, such as original photos from camera ~ but I don't know why no error reported!!! Refer to the update post: Scale bitmap Efficiently.

Related:
- Convert URI to real path format
- Read EXIF of JPG file

New Google Chrome Extension will Block Content Farms

Webkit icon
Ever do a Google search for something a little obscure, and instead of getting the information you need, you get a page full of more ads than text? Sites like this are called content farms. The farms hire people to write little snippets of text which they surround with ads.



To fight back, Google is adding an extension to its Chrome browser that allows you to block these sites. The details are in the blog post from Google. Check it out.

Wednesday 16 February 2011

Select Image using Android build-in Gallery

If you have to select image from SD in your app, and don't want to implement a file browser by yourself; you can call the Android build-in Gallery to do so, using Intent.

Select Image using Android build-in Gallery

Here is a example:
package com.exercise.AndroidSelectImage;

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.TextView;

public class AndroidSelectImage extends Activity {

TextView textTargetUri;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button buttonLoadImage = (Button)findViewById(R.id.loadimage);
textTargetUri = (TextView)findViewById(R.id.targeturi);

buttonLoadImage.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 0);
}});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);

if (resultCode == RESULT_OK){
Uri targetUri = data.getData();
textTargetUri.setText(targetUri.toString());
}
}
}


<?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:id="@+id/loadimage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Load Image"
/>
<TextView
android:id="@+id/targeturi"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


Download the files.

next:
- Display Gallery selected image using BitmapFactory

related:
- Send email with Image by starting activity using Intent of ACTION_SEND

New MacWorld App for the iPad

iPhone iPad pictureMacWorld has released a new App for the iPad, MacWorld Daily Reader. It provides an interface to the content MacWorld creates every day.



The App has a clean interface divided into sections. Each category or section has its own page which does not scroll up or down. That seems a little odd to me, as I keep trying to make it scroll up and down to find the bottom of the page. lol. Scrolling right or left moves you from section to section. Sections include Mac, iOS, Photography, etc... Each page contains a number of articles from the MacWorld web site.



Definitely worth a look if you are into all things Apple.

Get a Web Link to an iPhone or iPad App on App Store

iPhone iPad pictureOne thing I really wish Apple would do is provide a Web based interface to its App Store. Let's be honest kids, the iTunes store interface just sucks. Its hard to find stuff, it can be really slow, and its down a lot (although the last two of those issues seem to be much better of late.). I know there is a web page for each app, but how in the world do I find it?



Well I just found it. So I'm sharing.



To get a Web page link to an app, do the following.

  1. Start iTunes.

  2. Navigate to the App you are interested in.

  3. In the upper left hand corner of the screen, you will see the app icon and a little button below it. The button will say "Free App" or the prices "$1.99 Buy". Just to the right of that is a little arrow.

  4. If you click that you will see this popup list.

  5. Pick your favorite way to share the link and the link is created and posted to the communications system of your choice. The "Tell a Friend" option, simply sends an e-mail with the link.

For example, here is a link to the new MacWorld iPad App: http://itunes.apple.com/us/app/macworld-daily-reader/id393179523?mt=8#ls=1

A bit verbose, but somewhat understandable.



That's it. Link away kids!

How well does IE9 Support HTML5? Not very well apparently

Firefox LogoHow does IE9 compare with Firefox 4 when it comes to HTML5 features?   Really well according to Microsoft. Not so good according Paul Rouget and caniuse.com. Check out this post on the subject.

Tuesday 15 February 2011

Coyote's are Howling Tonight

I have my window open because it was about 65 degrees here in Denver today. I can hear the Coyotes howl from the nearby open space. They have been howling for about half an hour. Very unusual, but very cool.



So if you live in Broomfield, Colorado, open your window.

Felicia Day Starring in a new Web Series: Dragon Age Redemption

USA Today provided us with this story on Felicia Day, star of The Guild. She will be starring in a new Web series, Dragon Age: Redemption. The series will tie into the Dragon Age universe defined in the current game Dragon Age: Origins and the forthcoming Dragon Age II. See the article for details.



It just goes to show that hard work pays off. I've seen Felicia in a few SyFy channel movies and a few TV shows. Pretty cool for someone who plays WOW. :)

AT&T Data Pro Tethering Plan Doubles to 4GB

iPhone iPad pictureAT&T texted me last night to let me know they had doubled my iPhone Data Pro tethering plan. Now instead of getting 2GB for a month, I get 4GB for the same price. Woot! That is an awful lot of data, unless you are planning to watch a bunch of movies. Here is the text message:



AT&T Free Msg: Great news! Effective immediately, AT&T is increasing the amount of data included in your DataPro Tethering plan from 2GB to 4GB. The monthly charge for your plan will not change and no action is required by you. Thank you for being a great customer. Please call 611 with questions.


Maybe this move comes to sway potential Verizon switchers? Hmmm... Anyway, good news for those of us planning to stick with AT&T.

Monday 14 February 2011

Search Optimization and Its Dirty Little Secrets

Internet IconWant to learn about he darker side of Search Engine Optimization (SEO)? Check out this article from the NY Times:

Search Optimization and Its Dirty Little Secrets - NYTimes.com



It is a fascinating read. The hackers must be making money doing this or they wouldn't do it. It just goes to show you what an integral part of the Internet Google is.

Sunday 13 February 2011

The First Immutable Law of the Internet

Internet IconThis subject has been on my mind for a while now. I suppose it is a bit presumptuous of me to try to define the laws of the Internet. On the other hand, why not me? :) Anyway, there seems to be one truth about the Net in my 20 years of participation.





The First Immutable Law of the Internet: If a system can be gamed, it will be gamed.



Whether it is a "like" system on a social network, a link ranking system, or a simple voting application, if the results can be manipulated, they will be.



Too often systems are designed with the naive assumption that users will act on the honor system. In my opinion, the vast majority of users do. However, there will always be enough smart people that don't follow "the rules" of a system. Eventually, someone or some group, will end up owning the top rating, the highest page rank, or most liked story by not following the rules. World of Warcraft saw this happen with their PVP rating system. Google constantly battles it with its page rank system.



So when you are out there, developing the next great thing, remember the first law. Assume someone will attempt to game your app. Because if you don't, inevitably someone will do just that. :)

Android Wireless Application Development (2nd Edition)

The start-to-finish guide to Android application development: massively updated for the newest SDKs and developer techniques!



This book delivers all the up-to-date information, tested code, and best practices you need to create and market successful mobile apps with the latest versions of Android. Drawing on their extensive experience with mobile and wireless development, Lauren Darcey and Shane Conder cover every step: concept, design, coding, testing, packaging, and delivery. The authors introduce the Android platform, explain the principles of effective Android application design, and present today�s best practices for crafting effective user interfaces. Next, they offer detailed coverage of each key Android API, including data storage, networking, telephony, location-based services, multimedia, 3D graphics, and hardware.

Every chapter of this edition has been updated for the newest Android SDKs, tools, utilities, and hardware. All sample code has been overhauled and tested on leading devices from multiple companies, including HTC, Motorola, and ARCHOS. Many new examples have been added, including complete new applications. This new edition also adds

  • Nine new chapters covering web APIs, the Android NDK, extending application reach, managing users, data synchronization, backups, advanced user input, and more
  • Greatly expanded coverage of Android manifest files, content providers, app design, and testing
  • New coverage of hot topics like Bluetooth, gestures, voice recognition, App Widgets, live folders, live wallpapers, and global search
  • Updated 3D graphics programming coverage reflecting OpenGL ES 2.0
  • An all-new chapter on tackling cross-device compatibility issues, from designing for the smallest phones to the big new tablets hitting the market
  • Even more tips and tricks to help you design, develop, and test applications for different devices
  • A new appendix full of Eclipse tips and tricks

This book is an indispensable resource for every member of the Android development team: software developers with all levels of mobile experience, team leaders and project managers, testers and QA specialists, software architects, and even marketers.

Saturday 12 February 2011

Android for Tablets - Honeycomb 3.0

iPhone iPad pictureA preview release of Google's new operating system for tablets was released a few weeks back. I'm just hearing about it on some of the podcasts I listen to. lol. So I searched around a bit and this article seems to be the best article on the subject.



Android Central: What's new in Android 3.0 Honeycomb



Pictures are included so you can get an idea of what the new OS will look like. The first tablet running the OS will be the Motorola Xoom, which is rumored to be released February 24. Which is interesting, given that the "preview" release came out 2 weeks ago. Apparently Motorola was the only company to have access to the new OS up until the "preview". Odd for an open source operating system. The price is supposed to be $800. Which seems a bit high for a Wifi only device.



Expect a lot of tablet releases this year. But at the pricing I'm seeing ($700 or $800), expect the iPad to keep its lead for the foreseeable future.

Friday 11 February 2011

Get location(Latitude and Longitude) from described address using Geocoder

The method getFromLocationName(String locationName, int maxResults) returns an array of Addresses that are known to describe the named location.

The query will block and returned values will be obtained by means of a network lookup. The results are a best guess and are not guaranteed to be meaningful or correct. It may be useful to call this method from a thread separate from your primary UI thread.

Modify the last exercise "Get list of address from location using Geocoder", the returned address of the clicked item is passed to getFromLocationName(), to get the location(Latitude and Longitude).

Suggest to test on true device. In my tests, it doesn't always work on emulator!


Get location(Latitude and Longitude) from described address using Geocoder

<?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"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Location"
android:background="#505050"
/>
<TextView
android:id="@+id/mylatitude"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/mylongitude"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Address"
android:background="#505050"
/>
<TextView
android:id="@+id/myaddress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Spinner
android:id="@+id/addresslist"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Returned Address"
android:background="#505050"
/>
<TextView
android:id="@+id/returnedaddress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/returnedlatitude"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/returnedlongitude"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


package com.exercise.AndroidFromLocation;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class AndroidFromLocation extends Activity {

double LATITUDE = 37.42233;
double LONGITUDE = -122.083;

final int maxResult =5;
String addressList[] = new String[maxResult];
private ArrayAdapter<String> adapter;

TextView myReturnedAddress, myReturnedLatitude, myReturnedLongitude;

Geocoder geocoder;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView myLatitude = (TextView)findViewById(R.id.mylatitude);
TextView myLongitude = (TextView)findViewById(R.id.mylongitude);
TextView myAddress = (TextView)findViewById(R.id.myaddress);
Spinner myAddressList = (Spinner)findViewById(R.id.addresslist);
myReturnedAddress = (TextView)findViewById(R.id.returnedaddress);
myReturnedLatitude = (TextView)findViewById(R.id.returnedlatitude);
myReturnedLongitude = (TextView)findViewById(R.id.returnedlongitude);

myLatitude.setText("Latitude: " + String.valueOf(LATITUDE));
myLongitude.setText("Longitude: " + String.valueOf(LONGITUDE));

geocoder = new Geocoder(this, Locale.ENGLISH);

try {
List<Address> addresses = geocoder.getFromLocation(LATITUDE, LONGITUDE, maxResult);

if(addresses != null) {

for (int j=0; j<maxResult; j++){
Address returnedAddress = addresses.get(j);
StringBuilder strReturnedAddress = new StringBuilder();
for(int i=0; i<returnedAddress.getMaxAddressLineIndex(); i++) {
strReturnedAddress.append(returnedAddress.getAddressLine(i)).append("\n");
}
addressList[j] = strReturnedAddress.toString();
}

adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, addressList);
adapter.setDropDownViewResource(android.R.layout.
simple_spinner_dropdown_item);
myAddressList.setAdapter(adapter);

myAddressList.setOnItemSelectedListener(myAddressListOnItemSelectedListener);
}
else{
myAddress.setText("No Address returned!");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
myAddress.setText("Canont get Address!");
}
}

Spinner.OnItemSelectedListener myAddressListOnItemSelectedListener
= new Spinner.OnItemSelectedListener(){

@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub

myReturnedAddress.setText(addressList[arg2]);

try {
List<Address> returnedaddresses = geocoder.getFromLocationName(addressList[arg2], 1);

if(returnedaddresses != null){
myReturnedLatitude.setText(String.valueOf(returnedaddresses.get(0).getLatitude()));
myReturnedLongitude.setText(String.valueOf(returnedaddresses.get(0).getLongitude()));
}

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub

}};
}


Download the files.

Thursday 10 February 2011

Get list of address from location using Geocoder

Last exercise "Get address from location using Geocoder" retrieve only one address from a specifiied location. In this exercise, a list of 5 addresses are retrieved; by submitting "5"(maxResult) in the third parameter of getFromLocation() method.

Get list of address from location using Geocoder

Modify main.xml to add a Spinner to show the returned address.
<?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"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Location"
android:background="#505050"
/>
<TextView
android:id="@+id/mylatitude"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/mylongitude"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Address"
android:background="#505050"
/>
<TextView
android:id="@+id/myaddress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Spinner
android:id="@+id/addresslist"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


AndroidFromLocation.java
package com.exercise.AndroidFromLocation;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

public class AndroidFromLocation extends Activity {

double LATITUDE = 37.42233;
double LONGITUDE = -122.083;

final int maxResult =5;
String addressList[] = new String[maxResult];
private ArrayAdapter<String> adapter;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView myLatitude = (TextView)findViewById(R.id.mylatitude);
TextView myLongitude = (TextView)findViewById(R.id.mylongitude);
TextView myAddress = (TextView)findViewById(R.id.myaddress);
Spinner myAddressList = (Spinner)findViewById(R.id.addresslist);

myLatitude.setText("Latitude: " + String.valueOf(LATITUDE));
myLongitude.setText("Longitude: " + String.valueOf(LONGITUDE));

Geocoder geocoder = new Geocoder(this, Locale.ENGLISH);

try {
List<Address> addresses = geocoder.getFromLocation(LATITUDE, LONGITUDE, maxResult);

if(addresses != null) {

for (int j=0; j<maxResult; j++){
Address returnedAddress = addresses.get(j);
StringBuilder strReturnedAddress = new StringBuilder();
for(int i=0; i<returnedAddress.getMaxAddressLineIndex(); i++) {
strReturnedAddress.append(returnedAddress.getAddressLine(i)).append("\n");
}
addressList[j] = strReturnedAddress.toString();
}

adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, addressList);
adapter.setDropDownViewResource(android.R.layout.
simple_spinner_dropdown_item);
myAddressList.setAdapter(adapter);
}
else{
myAddress.setText("No Address returned!");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
myAddress.setText("Canont get Address!");
}
}
}


Download the files.

Related Article:
- Get location(Latitude and Longitude) from described address using Geocoder

Wednesday 9 February 2011

Get address from location using Geocoder

Geocoder is a class for handling geocoding and reverse geocoding. Geocoding is the process of transforming a street address or other description of a location into a (latitude, longitude) coordinate. Reverse geocoding is the process of transforming a (latitude, longitude) coordinate into a (partial) address. The amount of detail in a reverse geocoded location description may vary, for example one might contain the full street address of the closest building, while another might contain only a city name and postal code. The Geocoder class requires a backend service that is not included in the core android framework. The Geocoder query methods will return an empty list if there no backend service in the platform. Use the isPresent() method to determine whether a Geocoder implementation exists.

The getFromLocation(double latitude, double longitude, int maxResults) method returns an array of Addresses that are known to describe the area immediately surrounding the given latitude and longitude. The returned addresses will be localized for the locale provided to this class's constructor.

The returned values may be obtained by means of a network lookup. The results are a best guess and are not guaranteed to be meaningful or correct. It may be useful to call this method from a thread separate from your primary UI thread.

It's a exercise getting reversed address from a given location (LATITUDE and LONGITUDE), maxResults is set to one.

Get address from location using Geocoder

package com.exercise.AndroidFromLocation;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.widget.TextView;

public class AndroidFromLocation extends Activity {

double LATITUDE = 37.42233;
double LONGITUDE = -122.083;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView myLatitude = (TextView)findViewById(R.id.mylatitude);
TextView myLongitude = (TextView)findViewById(R.id.mylongitude);
TextView myAddress = (TextView)findViewById(R.id.myaddress);

myLatitude.setText("Latitude: " + String.valueOf(LATITUDE));
myLongitude.setText("Longitude: " + String.valueOf(LONGITUDE));

Geocoder geocoder = new Geocoder(this, Locale.ENGLISH);

try {
List<Address> addresses = geocoder.getFromLocation(LATITUDE, LONGITUDE, 1);

if(addresses != null) {
Address returnedAddress = addresses.get(0);
StringBuilder strReturnedAddress = new StringBuilder("Address:\n");
for(int i=0; i<returnedAddress.getMaxAddressLineIndex(); i++) {
strReturnedAddress.append(returnedAddress.getAddressLine(i)).append("\n");
}
myAddress.setText(strReturnedAddress.toString());
}
else{
myAddress.setText("No Address returned!");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
myAddress.setText("Canont get Address!");
}

}
}


<?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"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Location"
android:background="#505050"
/>
<TextView
android:id="@+id/mylatitude"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/mylongitude"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Address"
android:background="#505050"
/>
<TextView
android:id="@+id/myaddress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


Download the files.

Related Article:
- Get list of address from location using Geocoder

Android 2.3.3 is now available for the Android SDK

Android 2.3.3 is now available for the Android SDK. This update adds new NFC capabilities for developers, such as the ability to write to tags and create peer-to-peer connections.

The new APIs enable exciting new applications, such as for ticketing, ratings, check-ins, advertising, and data exchange with other devices. For more information about Android 2.3.3, read the version notes.



more details:
- http://android-developers.blogspot.com/2011/02/android-233-platform-new-nfc.html



iPad 2 in Production

iPhone iPad pictureIf the Wall Street Journal is reporting it, then it must be true. :) The iPad 2 is in production in China.



More memory, faster graphics, and built in video conferencing seem to be the highlights. However, there is not a higher resolution screen as many predicted. I imagine it would be very difficult to line up enough manufacturing capacity to produce high resolution screens, given the current demand for the iPad.



Expect iPad 2 in a couple of months.

How to retrieve the String from EditText

The getText() method of EditText return a object of Editable, not String. In order to retrieve the text of EditText, toString() of Editable can be used.

 EditText myEditText = (EditText)findViewById(R.id.myedittext);
...
String stringEditText = myEditText.getText().toString();


Tuesday 8 February 2011

Welcome to the family - iPhone 4 Verizon

TinyUmbrella has been updated to support iPhone 4 CDMA aka Verizon. Note that since I do not have a Verizon iPhone 4, support is BETA. Please don't be surprised if I need to post another update with findings that are sure to come... Enjoy!

Monday 7 February 2011

Bing Copying Google Results?

Google LogoThe official Google Blog has this post on how Microsoft is copying Google results for failed Bing searches. Its is very interesting reading. The evidence seems to be quite damning.



However, I am not sure what Google can really do about it. Bringing attention to the issue seems to be about it.

Sunday 6 February 2011

Control Flash Light, function as a torch.

The method Camera.setParameters() was introduced since Android API level 5. Using this method with parameters.setFlashMode(Parameters.FLASH_MODE_TORCH), we can control the build-in flash light of Android device as a torch.

Control Flash Light

Modify main.xml to have a button to toggle torch on/off.
<?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:id="@+id/flashcontrol"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>


main code
package com.exercise.AndroidFlashLight;

import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class AndroidFlashLight extends Activity {

Camera camera = null;
Parameters parameters;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

final Button FlashLightControl = (Button)findViewById(R.id.flashcontrol);
FlashLightControl.setText("Set FLASH_MODE_TORCH");

FlashLightControl.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
if(camera == null){
camera = Camera.open();
parameters = camera.getParameters();
parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(parameters);
FlashLightControl.setText("Set FLASH_MODE_OFF");
}else{
parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(parameters);
camera.release();
camera = null;
FlashLightControl.setText("Set FLASH_MODE_TORCH");
}

}});
}
}


Modify AndroidManifest.xml to grant permission of "android.permission.CAMERA".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exercise.AndroidFlashLight"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".AndroidFlashLight"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.CAMERA"/>
</manifest>


Download the files.

Friday 4 February 2011

The Force

The Force. http://www.youtube.com/watch?v=R55e-uHQna0&NR=1

Get system screen brightness

Last exercise describe how to "Change system screen brightness". If you want to get the current setting of system screen brightness, you can use the code:

        try {
curBrightnessValue=android.provider.Settings.System.getInt(
getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS);
} catch (SettingNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Prevent iPhone 4 Baseband Update - iOS 4.2.1 iPhone 4 *ONLY*

I've added a page to the blog specifically for helping folks update to iOS 4.2.1 on their iPhone 4 while protecting their baseband. Note, this will not downgrade your baseband. All it will do is PREVENT your baseband from being updated. Enjoy!

Also - I've updated TinyUmbrella for 4.3b3 support as well as a nifty bugfix. (Thanks RobRedbeard)

Thursday 3 February 2011

Change system screen brightness, using android.provider.Settings.System.SCREEN_BRIGHTNESS

Last exercise "Change Android Screen Brightness, LayoutParams.screenBrightness" for my app only. On order to change system screen brightness, we can use the code:

android.provider.Settings.System.putInt(getContentResolver(),
android.provider.Settings.System.SCREEN_BRIGHTNESS,
SysBackLightValue);

Change system screen brightness

To access Settings.System.SCREEN_BRIGHTNESS, we have to modify AndroidManifest.xml to grant premission of "android.permission.WRITE_SETTINGS".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exercise.AndroidScreenBrightness"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".AndroidScreenBrightness"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>
<uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
</manifest>


main code
package com.exercise.AndroidScreenBrightness;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;

public class AndroidScreenBrightness extends Activity {
/** Called when the activity is first created. */

float BackLightValue = 0.5f; //dummy default value

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

SeekBar BackLightControl = (SeekBar)findViewById(R.id.backlightcontrol);
final TextView BackLightSetting = (TextView)findViewById(R.id.backlightsetting);
Button UpdateSystemSetting = (Button)findViewById(R.id.updatesystemsetting);

UpdateSystemSetting.setOnClickListener(new Button.OnClickListener(){

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub

int SysBackLightValue = (int)(BackLightValue * 255);

android.provider.Settings.System.putInt(getContentResolver(),
android.provider.Settings.System.SCREEN_BRIGHTNESS,
SysBackLightValue);

}});

BackLightControl.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

@Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
// TODO Auto-generated method stub
BackLightValue = (float)arg1/100;
BackLightSetting.setText(String.valueOf(BackLightValue));

WindowManager.LayoutParams layoutParams = getWindow().getAttributes();
layoutParams.screenBrightness = BackLightValue;
getWindow().setAttributes(layoutParams);


}

@Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub

}

@Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub

}});
}
}


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"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Set BackLight of the App"
/>
<SeekBar
android:id="@+id/backlightcontrol"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10px"
android:max="100"
android:progress="50"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/backlightsetting"
android:text="0.50"
/>
<Button
android:id="@+id/updatesystemsetting"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Update Settings.System.SCREEN_BRIGHTNESS"
/>
</LinearLayout>


Download the files.

Related article:
- Get system screen brightness