Thursday, December 29, 2011

How to add icons to Preference example in Android

If you are having a pain in the ass getting this to work. Download the example from here

http://www.ziddu.com/download/17996784/preference_icon_example.zip.html

Wednesday, December 7, 2011

StackOverflow error in Eclipse ?

Today, friend of mine Kitaro Nu shared this information with me.

This error is likely to happen if you have two library projects and they both refer each other.

· Project A import project B and Project B import Project A .

Thursday, December 1, 2011

Unable to create editor ID org.eclipse.jdt.ui.PropertiesFileEditor: Editor could not be initialized. Java heap space

Today, after I took the latest version of a component and try to rebuild the work space i started to getting this error.

To solve this,
1. Had to close eclipse and restart
2. Run eclipse with clean command
\eclipse\eclipse.exe -clean
3. delete

workspace\.metadata\.plugins\org.eclipse.jdt.core
workspace\metadata\.plugins\org.eclipse.core.resources\.history

worked for me!



Monday, November 28, 2011

How to encrypt a serializable class in Android

public boolean save(YourClass pref){
boolean isSuccess = false;
try {
final File persistedFile = new File("/sdcard/sr.dat");
if(persistedFile.exists())
persistedFile.delete();
OutputStream file = new FileOutputStream(persistedFile);
BufferedOutputStream buffer = new BufferedOutputStream(file);
Cipher desCipher = getCipher(Cipher.ENCRYPT_MODE);
CipherOutputStream cos = new CipherOutputStream(buffer, desCipher);
ObjectOutputStream oos = new ObjectOutputStream(cos);
oos.writeObject(pref);
oos.flush();
oos.close();
} catch (IOException ex) {
Log.d(TAG, ex.getMessage());
isSuccess = false;
} catch (InvalidKeyException e) {
Log.d(TAG, e.getMessage());
isSuccess = false;
} catch (InvalidKeySpecException e) {
Log.d(TAG, e.getMessage());
isSuccess = false;
} catch (NoSuchAlgorithmException e) {
Log.d(TAG, e.getMessage());
isSuccess = false;
} catch (NoSuchPaddingException e) {
Log.d(TAG, e.getMessage());
isSuccess = false;
}
return isSuccess;
}
private Cipher getCipher(int opmode) throws InvalidKeyException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException {
byte key[] = "Aruna Tennakoon".getBytes();
DESKeySpec desKeySpec = new DESKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);

// Create Cipher
Cipher desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
desCipher.init(opmode, secretKey);
return desCipher;
}
public Preference load(){
Preference repo = null;
try {

final File persistedFile = File("/sdcard/sr.dat");
if(!persistedFile.exists()) {
// sr is not created yet. Create one and return
return;
}
Cipher desCipher = getCipher(Cipher.DECRYPT_MODE);
FileInputStream fis = new FileInputStream(persistedFile.getAbsolutePath());
BufferedInputStream bis = new BufferedInputStream(fis);
CipherInputStream cis = new CipherInputStream(bis, desCipher);
ObjectInputStream ois = new ObjectInputStream(cis);
repo = (YourClass) ois.readObject();
ois.close();
} catch (FileNotFoundException e) {
Log.d(TAG, e.getMessage());
} catch (StreamCorruptedException e) {
Log.d(TAG, e.getMessage());
} catch (IOException e) {
Log.d(TAG, e.getMessage());
} catch (InvalidKeyException e) {
Log.d(TAG, e.getMessage());
} catch (InvalidKeySpecException e) {
Log.d(TAG, e.getMessage());
} catch (NoSuchAlgorithmException e) {
Log.d(TAG, e.getMessage());
} catch (NoSuchPaddingException e) {
Log.d(TAG, e.getMessage());
} catch (ClassNotFoundException e) {
Log.d(TAG, e.printStackTrace());
}

return repo;
}

Wednesday, November 23, 2011

how to get the ip address of android phone?

private String getLocalIpAddress() {
try {
for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); }
}
}
} catch (SocketException ex) {
Log.e("ServerActivity", ex.toString());
}
return null;
}

Wednesday, November 16, 2011

'Conversion to Dalvik format failed with error 1' and 'java.lang.IllegalArgumentException: already added: '

Recently we moved to Android SDK tools Rev 15 , In my opinion it has may problems comparing to previous versions of the SDK and should stick with the previous version if you are developing a huge applications and have library projects referenced.

Today, I got this error and few hours of Googling found the solution,

Remove the source folder link in Project properties->Java Build Path->Source

Clean and add the projects back, You will see that it will add the projects as jar files under "Library Projects" not as project_src anymore.

Monday, November 7, 2011

How to do a simple visible animation in Android

public void showConfigurationBar() {
AnimationSet set = new AnimationSet(true);
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(500);
set.addAnimation(animation);
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
animation.setDuration(500);
set.addAnimation(animation);
RelativeLayout configBar = findViewById(R.id.baridhere);
configBar.setVisibility(View.VISIBLE);
configBar.startAnimation(set);
}

How to generate a MD5 Hash in Android

public static String getMd5Hash(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageDigest = md.digest(input.getBytes());
BigInteger number = new BigInteger(1, messageDigest);
String md5 = number.toString(16);
while (md5.length() < 32)
md5 = "0" + md5;
return md5;
} catch (NoSuchAlgorithmException e) {
Log.e("MD5", e.getLocalizedMessage());
return null;
}
}

Tuesday, November 1, 2011

Eclipse Layout Editor Graphical Layout is not Showing or missing ?


Specify the Android Layout Editor as the default for Android XML files under Preferences -> General- >Editors->File Associations.


1. If Android layout editor is missing Add Android Layout Editor and make it default.
2. Close eclipse and restart. Otherwise this will not work.

Monday, October 31, 2011

CountDownTimer Error: Can't create handler inside thread that has not called Looper.prepare()

Today I was getting this error "Can't create handler inside thread that has not called Looper.prepare()" in a CountDownTimer. All this time this code used to work perfectly but suddenly it stopped.

Problem is, in CountDownTimer.java (Android source code) it creates a mHandler inside the code which makes the caller should call the CountDownTimer class on UI thread which is not possible in my case. So I created a separate Timer class,

Timer cTimer = new Timer();
private final static int START_FROM = 60;

cTimer.scheduleAtFixedRate(new TimerTask() {
int i = START_FROM ;
public void run() {
Log.d(TAG, "Comparison will start in:" + i--);
if (i< 0) {
cTimer.cancel();
// Do something
}
}
}, 0, 1000);

Tuesday, October 25, 2011

How to enable/disable Mobile Data on Android 2.3

Today, colleague asked me whether i know how to enable and disable mobile internet on Android ? Actually, I was curious about this for sometime and never had the time to look into how to do this. So this is how to do it.

I tired it on Android 2.3 i tried this code and it worked! When I looked into Android source code I saw this method is available 2.2 R1 up.


  private boolean getMobileDataEnabled() {
        try {
            Method method = connectivityManager.getClass().getMethod("getMobileDataEnabled");
            return (Boolean)method.invoke(connectivityManager);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    private void setMobileDataEnabled(boolean on) {
        try {
            Method method = connectivityManager.getClass().getMethod("setMobileDataEnabled",
                    boolean.class);
            method.invoke(connectivityManager, on);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
If you are using 2.2 R1 or later try this code.


Wednesday, October 19, 2011

android.content.OperationApplicationException: wrong number of rows: 0

Today I got this error tying to update a contact in Android 2.3 Nexus S device which was working fine on Motorola Milestone (Android 2.1 - update 1). Reason was I was getting the "withExpectedCount" parameter as 1

ops.add(ContentProviderOperation. newInsert(addCallerIsSyncAdapterParameter(ContactsContract.Data.CONTENT_URI))
.withValue(ContactsContract.Data.RAW_CONTACT_ID, contact.getId())
.withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(CommonDataKinds.Phone.NUMBER, phone)
.withValue(CommonDataKinds.Phone.TYPE, cm.getType()).withExpectedCount(1).build());

When i removed it it worked fine .. Looks like if the original and updating content values are same it does not update the row :|

Tuesday, September 27, 2011

How to brick your android device?

Today, While I was digging into android source code, I found this. Never tried it. Drop me a message here if you do.

package com.android.server;

import android.content.Context;
import android.content.Intent;
import android.content.BroadcastReceiver;
import android.os.SystemService;
import android.util.Log;

public class BrickReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.w("BrickReceiver", "!!! BRICKING DEVICE !!!");
SystemService.start("brick");
}
}



Friday, September 23, 2011

How to debug Android source code in Eclipse?

Today, I wanted to know what's going on inside Android because it was keep throwing an exception . So i wanted to check how to debug an Android application right from Eclipse IDE. When I googled I found this link,

http://android.opensourceror.org/2010/01/18/android-source/

but it says how to debug a single version of android eg. Cupcake. Now problem is how to debug multiple versions of Android ?

it's easy.

all you have to do is open the .project in notepad
\workspace\.metadata\.plugins\org.eclipse.jdt.core\.org.eclipse.jdt.core.external.folders

and another element to the section.



         .link0
         2
         C:/Aruna/Android/android-sdk_r08-windows/android-sdk-windows/Cupcake
  
     
         .link1
         2
         C:/Aruna/Android/android-sdk_r08-windows/android-sdk-windows/Donut
  


IllegalStateException: Couldn't init cursor window

Today one of our application started getting this exception.
java.lang.IllegalStateException: Couldn't init cursor window at android.database.CursorWindow.native_init(Native Method) at android.database.CursorWindow.(CursorWindow.java:41) at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:277) at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:269)
After few hours of googling, I found the solution to this problem. Solution is to close the Cursor after after you are done!This exception is thrown here
if (!window->initBuffer(localOnly)) { jniThrowException(env, "java/lang/IllegalStateException", "Couldn't init cursor window"); delete window; return; }
localOnly is defined in
CursorWindow.h
as
#define MAX_WINDOW_SIZE (1024 * 1024)
So, There are two possible causes to throw this exception. 1. Your mobile phone is out of memory.2. You are fetching something out of the database more than 1M. If there is a logical way to divide your queries into discrete chunks, you could do incremental queries and use CursorJoiner to stitch them together that might help you if you are dealing with big chuck of data.

So lesson learned, Close the cursor in a try finally block

Cursor cursor;
try {
cursor.open();
}
finally{
if(cursor.isOpen()) {
cursor.close();
}

Wednesday, September 7, 2011

Error retrieving parent for item: No resource found that matches the given name 'android:WindowTitleBackground'.

Today while trying to compile a project I got for github I got this error.

Error retrieving parent for item: No resource found that matches the given name 'android:WindowTitleBackground'.

It's so annoying because it worked perfectly in one machine and on my laptop it did not. When I was almost given up I thought of replacing the platform tools with old platform tools and it worked!!

Download the revision 11 tools from here

http://dl.google.com/android/repository/tools_r11-windows.zip

and rename your platform-tools folder in android-sdk-windows and paste this there. That should work!

Monday, August 22, 2011

How call a method/function inside a APK file in Android?

Today I came across this piece of code and thought of sharing it with others.

PathClassLoader c = new PathClassLoader("/system/app/Mms.apk", getClassLoader());
Class.forName("com.android.mms.util.ContactInfoCache", true, c)
.getMethod("init", Context.class).invoke(null, context);
Class.forName("com.android.mms.transaction.MessagingNotification", true, c)
.getMethod("updateAllNotifications", Context.class).invoke(null, context);

This piece of code will trigger Android new message arrival notification. Interesting ...

Thursday, August 4, 2011

Type The method compareTo(Request) of type Request must override a superclass method ? haa?

We were working on Eclipse Galileo and moved to the new version Indigo but some of the projects that were working fine in Galileo started trowing this exception. Problem is in Galileo Java compiler compliance is set to JRE 1.6 but in Indigo it's set to 1.5 for some reason.

So to fix this error you need to change the compliance to 1.6 back, To do this, Go to your Window -> Preferences -> Java -> Compiler -> Set to 1.6 and set the java compiler level to 1.6 and also make sure you select JRE 1.6 to execute your program from eclipse.

Monday, August 1, 2011

Android ContentObserver not getting notify ?

Today, I ran into a problem where my content observer is not getting notify when I delete something. After hours of searching I realized, sometime you need to set the
notifyForDescendents parameter as true. Weird but it worked!

Eg.

registerContentObserver(uri, true, observer);

How to use ACTION_TIME_TICK broadcast ?

Today, I was looking into how to track change notification to the camera folder in Android. While Googling for this, I came across ACTION_TIME_TICK broadcast event.

Android Doc says
public static final String ACTION_TIME_TICK
The current time has changed. Sent every minute. You can not receive this through components declared in manifests, only by exlicitly registering for it with Context.registerReceiver().

Sometimes we use a backgroud timer in our application to check for something in a continues loop but I think listening to this event is much better approach, but you have to make sure it's thread safe.

How to use.

@Override
public void onCreate(){
super.onCreate();

registerReceiver(
new ThikReceiver(),
new IntentFilter(Intent.ACTION_TIME_TICK));
}
}


public class ThikReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().compareTo(Intent.ACTION_TIME_TICK) == 0)
// Do something
else
// Do something else
}
}

Friday, July 29, 2011

How to create a thread in android without hurting the UI

Sometimes when we want to do something out of the ordinary like pushing something to the server while user is playing a game or checking emails we create Threads. If you do not set the thread priority to low this might hurt the UI performance.

Correct way to do is to call setPriority in the thread class.

SomeTaskThread someTaskThread = new SomeTaskThread();
someTaskThread.setPriority(Thread.NORM_PRIORITY-1); //Make the background thread low priority. This way it will not affect the UI performance
someTaskThread.start();

or you can use AsyncTask class.

Monday, July 18, 2011

Unable to find instrumentation target package ? duh!

Today I was trying to write some test cases after i got inspired by this link

Problem was I was keep getting "Unable to find instrumentation target package" Error and not sure how to fix it. Well there are few ways to fix this problem. Easy way out is:

1.Double click on the AndroidManifest.xml

Delete any "instrumentation" tags

2.Goto Instrumentation Tab
3.Click Add
4.Select Instrumentation
5. Select the name and target package.

This should work. Trying to add the Instrumentation manually is a nightmare.

Hope this will help to someone else

Sunday, July 3, 2011

How do I investigate an Application Not Responding (ANR) in Android?

Today I got an ANR error and it's really annoying because you know you have done something wrong and not sure where to look for to find out the problem.

When I googled, I found this on StackOverFlow.

"An ANR happens when some long operation takes place in the "main" thread. This is the event loop thread, and if it is busy, Android cannot process any further GUI events in the application, and thus throws up an ANR dialog." - From Stackoverflow

so, how to diagnose the problem, it's easy,

adb shell cat /data/anr/traces.txt

will drump all the appplication not responding traces to the command prompt. (Make sure to change the command prompt buffer size otherwise you can not see the full log out)

Monday, June 20, 2011

How get PDUs from SMS in Android

Today, I wanted to convert the "pdus" bytes back to hex, this is how to do it.

@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Object[] aPDUArray = (Object[]) bundle.get("pdus");
String pduString = toHexString((byte[]) aPDUArray[0]);
}


private final static char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F' };

public static String toHexString(byte[] array) {
int length = array.length;
char[] buf = new char[length * 2];

int bufIndex = 0;
for (int i = 0 ; i < length; i++)
{
byte b = array[i];
buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F];
buf[bufIndex++] = HEX_DIGITS[b & 0x0F];
}

return new String(buf);
}

Friday, June 10, 2011

isProcessRunning in Android - The hardway

public static boolean isProcessRunning(String paramString)
throws Exception
{
int i = 0;
Process localProcess = Runtime.getRuntime().exec("ps");
InputStream localInputStream = localProcess.getInputStream();
InputStreamReader localInputStreamReader = new InputStreamReader(localInputStream);
BufferedReader localBufferedReader = new BufferedReader(localInputStreamReader);
String str = localBufferedReader.readLine();
localBufferedReader.close();
localProcess.waitFor();

if (!str.contains(paramString))
break;

}
}

Tuesday, May 17, 2011

how to answer an incoming call in android 2.3

Today, I was researching on a how to answer incoming call in android 2.3 automatically. My first thought was using "ITelephony.aidl" and call the answerRingingCall(). When i looked into more details answerRingingCall() function all requires MODIFY_PHONE_STATE permission which is marked as a as "signatureOrSystem" which is mentioned here
http://android.git.kernel.org/?p=platform/frameworks/base.git;a=commit;h=f4ece2086f3b7060edc4b93a12f04c9af648867a

and here
http://code.google.com/p/android/issues/detail?id=15031

bummer. Then thought of a another work-around and bluetooth headset popuped to my mind. In this all I had to do was to call start new intent with ACTION_UP. It worked!

here is the soulution

BroadcastReceiver PhoneState = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {
if (!intent.getAction().equals("android.intent.action.PHONE_STATE")) return;
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);

if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
String number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

Intent answer = new Intent(Intent.ACTION_MEDIA_BUTTON);
answer.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
sendOrderedBroadcast(answer, null);

}

return;
}};

// Update on 2011-09-27

In Android 2.3.3 HTC Sensation this piece of code does not work. Reason is in 2.3.3 I found a HeadsetObserver  listening for actual bluetooth plug-in event. So you need to send a Intent pretending there is a headset connected already. To fix this problem you need to send the ACTION_HEADSET_PLUG Intent before calling the above code.


 Intent buttonDown = new Intent(Intent.ACTION_MEDIA_BUTTON);          
 buttonDown.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));
 context.sendOrderedBroadcast(buttonDown, "android.permission.CALL_PRIVILEGED");

 // froyo and beyond trigger on buttonUp instead of buttonDown
 Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);            
 buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));
 context.sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED");

 Intent headSetUnPluggedintent = new Intent(Intent.ACTION_HEADSET_PLUG);
 headSetUnPluggedintent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
 headSetUnPluggedintent.putExtra("state", 1); // 0 = unplugged  1 = Headset with microphone 2 = Headset without microphone
 headSetUnPluggedintent.putExtra("name", "Headset");
 // TODO: Should we require a permission?
 sendOrderedBroadcast(headSetUnPluggedintent, null);

// Update on 2012-04-27

Lot of people are asking me how to end call, here is the code


Intent buttonUp = new Intent(Intent.ACTION_MEDIA_BUTTON);            
buttonUp.putExtra(Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));
getContext().sendOrderedBroadcast(buttonUp, "android.permission.CALL_PRIVILEGED");

// Update on 2012 - 08 - 21
This method no longer works on Android Jelly Bean (4.1.1) and possibly later versions. Google has blocked  3rd party apps from broadcasting Intent.ACTION_MEDIA_BUTTON.

java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.HEADSET_PLUG from pid=30943, uid=10064


Android 1 : Me 0

How to turn on noise suppression in Android

While researching on another topic i found the answer to this question. it's easy all you have to do is set the parameter.

AudioManager localAudioManager = (AudioManager)paramContext.getSystemService("audio");
localAudioManager.setParameters("noise_suppression=auto");

or if you do not want
localAudioManager.setParameters("noise_suppression=off");

Monday, May 9, 2011

How to create a Thumbnail image in Android

Today, I wanted to create an image thumbnail in Android. There is no easyway out. So I wrote the code by my self.

byte[] imageData = null;

try
{

final int THUMBNAIL_SIZE = 64;

FileInputStream fis = new FileInputStream(fileName);
Bitmap imageBitmap = BitmapFactory.decodeStream(fis);

Float width = new Float(imageBitmap.getWidth());
Float height = new Float(imageBitmap.getHeight());
Float ratio = width/height;
imageBitmap = Bitmap.createScaledBitmap(imageBitmap, (int)(THUMBNAIL_SIZE * ratio), THUMBNAIL_SIZE, false);

ByteArrayOutputStream baos = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
imageData = baos.toByteArray();

}
catch(Exception ex) {

}

Tuesday, March 29, 2011

"Cannot find 'make' program. Please install Cygwin make package" ?

Today I was trying to install Cygwin from in my Machine. I was lazy to download the whole thing and install, so i copied it from a another machine. Then when i ran Ant Release i got this error. After few mins it clicked me to set the environment variables.

1. Set the environment variable CYGWIN=nodosfilewarning
2. Set c:\cygwin\bin to PATH variable
3. Set NDK_ROOT environment variable to point there.

Thursday, March 24, 2011

Recursive (Sub directory) File System Watcher in Android.

Today, I was looking into monitoring directory changes in Android. It looks like FileObserver class in Android does not support recursive sub-directory watching even though it uses Linux internal "inotify".

Android documentations says:

Each FileObserver instance monitors a single file or directory. If a directory is monitored, events will be triggered for all files and subdirectories (recursively) inside the monitored directory.

But it does not work this way.

Anyway, then I looked in more and found
here it's been reported to Google and they have fixed it in 2.3 or 3.0 it seems. I tried to integrate the same code into my code and it failed because it's using Native functions.

Then I found this code on here with few compile errors, then i fixed it and thought of posting it here, because it might help someone else time.

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import android.os.FileObserver;
import android.util.Log;


public class RecursiveFileObserver extends FileObserver
{
/** Only modification events */
public static int CHANGES_ONLY = CREATE | DELETE | CLOSE_WRITE | MOVE_SELF
| MOVED_FROM | MOVED_TO;

List mObservers;
String mPath;
int mMask;

public RecursiveFileObserver(String path)
{
this(path, ALL_EVENTS);
}

public RecursiveFileObserver(String path, int mask)
{
super(path, mask);
mPath = path;
mMask = mask;
}

@Override
public void startWatching()
{
if (mObservers != null)
return ;

mObservers = new ArrayList();
Stack stack = new Stack();
stack.push(mPath);

while (!stack.isEmpty())
{
String parent = String.valueOf(stack.pop());
mObservers.add(new SingleFileObserver(parent, mMask));
File path = new File(parent);
File[]files = path.listFiles();
if (null == files)
continue;
for (File f: files)
{
if (f.isDirectory() && !f.getName().equals(".") && !f.getName()
.equals(".."))
{
stack.push(f.getPath());
}
}
}

for (SingleFileObserver sfo: mObservers)
{
sfo.startWatching();
}
}

@Override
public void stopWatching()
{
if (mObservers == null)
return ;

for (SingleFileObserver sfo: mObservers)
{
sfo.stopWatching();
}
mObservers.clear();
mObservers = null;
}

@Override
public void onEvent(int event, String path)
{
switch (event)
{
case FileObserver.ACCESS:
Log.i("RecursiveFileObserver", "ACCESS: " + path);
break;
case FileObserver.ATTRIB:
Log.i("RecursiveFileObserver", "ATTRIB: " + path);
break;
case FileObserver.CLOSE_NOWRITE:
Log.i("RecursiveFileObserver", "CLOSE_NOWRITE: " + path);
break;
case FileObserver.CLOSE_WRITE:
Log.i("RecursiveFileObserver", "CLOSE_WRITE: " + path);
break;
case FileObserver.CREATE:
Log.i("RecursiveFileObserver", "CREATE: " + path);
break;
case FileObserver.DELETE:
Log.i("RecursiveFileObserver", "DELETE: " + path);
break;
case FileObserver.DELETE_SELF:
Log.i("RecursiveFileObserver", "DELETE_SELF: " + path);
break;
case FileObserver.MODIFY:
Log.i("RecursiveFileObserver", "MODIFY: " + path);
break;
case FileObserver.MOVE_SELF:
Log.i("RecursiveFileObserver", "MOVE_SELF: " + path);
break;
case FileObserver.MOVED_FROM:
Log.i("RecursiveFileObserver", "MOVED_FROM: " + path);
break;
case FileObserver.MOVED_TO:
Log.i("RecursiveFileObserver", "MOVED_TO: " + path);
break;
case FileObserver.OPEN:
Log.i("RecursiveFileObserver", "OPEN: " + path);
break;
default:
Log.i("RecursiveFileObserver", "DEFAULT(" + event + ";) : " +
path);
break;
}
}

/**
* Monitor single directory and dispatch all events to its parent, with full path.
*/
class SingleFileObserver extends FileObserver
{
String mPath;

public SingleFileObserver(String path)
{
this(path, ALL_EVENTS);
mPath = path;
}

public SingleFileObserver(String path, int mask)
{
super(path, mask);
mPath = path;
}

@Override public void onEvent(int event, String path)
{
String newPath = mPath + "/" + path;
RecursiveFileObserver.this.onEvent(event, newPath);
}
}
}


How to use
-----------

RecursiveFileObserver mObserver;

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

File DIRECTORY_DCIM = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);

mObserver = new RecursiveFileObserver(DIRECTORY_PICTURES.getAbsolutePath(), RecursiveFileObserver.CREATE);
mObserver.startWatching();

Toast.makeText(getApplicationContext(), "Watching " + DIRECTORY_PICTURES.getAbsolutePath(), Toast.LENGTH_LONG).show();
}


Android 0, Me 1 :)

Tuesday, March 22, 2011

Reading Emails in Android.

Today I was trying to hack into Android EMail client. When i tried to pull out something from the content://com.android.email.provider/account Uri, i am always throwing an exception like this,

java.lang.SecurityException: Permission Denial: reading com.android.email.provider.EmailProvider uri content://com.android.email.provider/account requires com.android.email.permission.ACCESS_PROVIDER

so decided to decomplie the Android EmailGoogle.apk file :D which contains the classes for com.android.email namespace

AndroidManifest.xml definition looks like this,




It looks like content provider can only be accessed by either the system, or by applications signed with the same key. So my dreams were shattered.

Android 1, Me 0 :|

Tuesday, March 15, 2011

How to export Outlook contacts to Android ?

I used to keep all my contacts on Outlook and today I wanted to sync all my contacts with my Android phone and i could not find a easy way to do it. Finally found a easy work around.

1. Open Outlook -> Select Contacts -> Select all contacts (Ctrl + A) -> Right Click -> Send As Business Card
2. This will popup a new email message window with all the contacts attached.
3. Save all the contacts to a folder.
4. Plug Android phone to PC - Select Disk Drive
5. copy above folder into android SD Card.
6. Open People/Contacts in android.
7. Press Menu Key -> Select Import from SD Card. This will look for all the vCard files in the phone.
8. Then you can select import all or one by one.

good luck

Monday, March 14, 2011

how to send a MMS programmatically in Android

Last couple of day I have been researching on how to send a MMS in android without using Intents, to be honest it is not an easy task and help on Google is limited on this case.

However, one post on stackoverflow.com which helped me immensely.

http://stackoverflow.com/questions/2972845/i-want-send-image-through-using-mms-in-android/2973016#2973016

it seems to be author has looked into the android MMS source code and provided vital information on how to send a MMS. For me, being a rookie hooking up all the MMS code in my project seems to be a nightmare.

When i further look, I found a nice library called "jmmslib" here

which can be directly used in Android to create a MMS but in my cause i found it not to be working very well because sometimes it works, sometime not. (may be something wrong with my code) but it was giving me a hard time and had to look for a better solution.

Then, I found a Nokia Java based MMS impelmentation. You can found it here

you can download the my source code here.
https://github.com/kakopappa/AndroidMMS


Update - 2013-09-17

I just saw TextSecure app is sending MMS messages.. You can find the code here

You guys can use http://androidshell.io/ to connect to remote android devices

Tuesday, March 8, 2011

How to read a file in bytes - Android

private static final int BUFFER_SIZE = 0x1000; // 4K

FileInputStream fin;

try {
fin = new FileInputStream(directory);
BufferedInputStream bis = new BufferedInputStream(fin);
DataInputStream dis = new DataInputStream(bis);
byte fileContent[] = toByteArray(dis);
}
catch(Exception e)
{
}

public static byte[] toByteArray(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
copy(in, out);
return out.toByteArray();
}


public static long copy(InputStream from, OutputStream to) throws IOException {
byte[] buf = new byte[BUFFER_SIZE];
long total = 0;
while (true) {
int r = from.read(buf);
if (r == -1) {
break;
}
to.write(buf, 0, r);
total += r;
}
return total;
}

Monday, February 21, 2011

Can not receiver android.provider.Telephony.WAP_PUSH_RECEIVED in MMS?

I have seen most of the people complaining about not receiving android.provider.Telephony.WAP_PUSH_RECEIVED intent. This is because most of the time they missed out on adding the MIME Type. This is the correct way to define the receiver

Sunday, February 13, 2011

Could not load definitions from resource proguard/ant/task.properties

To fix this,

1. Open add-proguard-release.xml
2. Goto Line 19.
3. add "lib" to the following location

value="${proguard.dir}/lib/proguard.jar"

Expecting class path separator ':' before '{' in argument number in Ant + Android build scripts

Today when I tried to Incorporate Ant build scripting with ProGard I got this error.

BUILD FAILED
/path/to/add-proguard-release.xml:35: Expecting class path separator ':' before '{' in argument number 1

to fix this error add following line to your default.properties file:

external.libs.dir=libs

Wednesday, February 9, 2011

-Dosgi.requiredJavaVersion=1.5 Error

---------------------------
Eclipse
---------------------------
JVM terminated. Exit code=-1
-Dosgi.requiredJavaVersion=1.5
-Xms40m
-Xmx512m
-XX:MaxPermSize=256m
-Djava.class.path=C:\Aruna\Android\eclipse-jee-galileo-win32\eclipse\plugins/org.eclipse.equinox.launcher_1.0.200.v20090520.jar
-os win32
-ws win32
-arch x86
-showsplash C:\Aruna\Android\eclipse-jee-galileo-win32\eclipse\\plugins\org.eclipse.platform_3.3.200.v200906111540\splash.bmp
-launcher C:\Aruna\Android\eclipse-jee-galileo-win32\eclipse\eclipse.exe
-name Eclipse
--launcher.library C:\Aruna\Android\eclipse-jee-galileo-win32\eclipse\plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.0.200.v20090519\eclipse_1206.dll
-startup C:\Aruna\Android\eclipse-jee-galileo-win32\eclipse\plugins/org.eclipse.equinox.launcher_1.0.200.v20090520.jar
-product org.eclipse.epp.package.jee.product
-vm C:\Program Files\Java\jdk1.6.0_23\bin\..\jre\bin\server\jvm.dll
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms40m
-Xmx512m
-XX:MaxPermSize=256m
-Djava.class.path=C:\Aruna\Android\eclipse-jee-galileo-win32\eclipse\plugins/org.eclipse.equinox.launcher_1.0.200.v20090520.jar
---------------------------
OK
---------------------------

I started getting this error message today morning and after few hours of googling I found how to fix this.

For some reason, Eclipse is using 32-Bit version of the Java Run time and when it kicks up, it's looking for the 32-Bit version of the Runtime. To fix this you need to download 32-bit version of the SDK from here . Then make sure Path variable in the Envirnment variable set to the 32 bit path as well.

Hope this will save someones day.

Sunday, January 23, 2011

android eclipse main.out.xml parsing error?

I got this error early in the morning today and kind of pissed me off. after few hours of googling I found the solution to this problem,


1. Debug Configurations -> Target -> Automatic
2. delete any main.xml.out files
3. Clean the solution
4. Open any .java file in the editor
5. Run

Thursday, January 20, 2011

android.intent.action.BOOT_COMPLETED not working ?

Today, I spent most of the time wondering why, this is the AndroidManifest.xml





after hours of searching I posted it on StackOverflow.com, and one guy came with an answer it was because '' I is in capital letter!

yah.. bummer! hope this will help to someone else,

cheers

Wednesday, January 19, 2011

Android ADB Interface This device cannot start. (Code 10) Error !

Today, I for the first time, I wanted to debug an application on an Android device. to do this, First you must install google usb driver which is located in the SDK folder. If its not there, You have to get it manually using the SDKManager.exe

After installing the driver as a new hardware I got this exclamation mark on the driver !



So, I googled and nothing came up. Then only it hit me to install my HTC phone drivers. I got the android drivers from here

Application - HTC Sync for all HTC Android Phones

after that i can still see the exclamation mark but Eclipse debugger can debug applications!. strange but it worked!

Or you guys can use my awsome app http://androidshell.io/ to connect to remote android devices without doing all this!

Tuesday, January 18, 2011

how to wipe data when starting Android emulator?

Today, I wanted to wipe out all the test programs i have created in my android emulator. I googled it few times and found -wipe-data parameter in SDK documentation.

http://developer.android.com/guide/developing/tools/emulator.html

but how to use -wipe-data parameter ? it's easy, )but I could not find a way to do it using the Eclipse IDE)

Open command prompt,

android-sdk-windows\tools>emulator -avd -wipe-data
eg.
emulator -avd androidavd2 -wipe-data

this should work!

How to debug multiple versions of Android source code in Eclipse?

Today, I wanted to know what's going on inside Android because it was keep throwing an exception . So i wanted to check how to debug an Android application right from Eclipse IDE. When I googled I found this link,

http://android.opensourceror.org/2010/01/18/android-source/

but it says how to debug a single version of android eg. Cupcake. Now problem is how to debug multiple versions of Android ?

it's easy.

all you have to do is open the .project in notepad
\workspace\.metadata\.plugins\org.eclipse.jdt.core\.org.eclipse.jdt.core.external.folders

and another element to the
linkedresources section.

Today, I wanted to know what's going on inside Android because it was keep throwing an exception . So i wanted to check how to debug an Android application right from Eclipse IDE. When I googled I found this link,

http://android.opensourceror.org/2010/01/18/android-source/

but it says how to debug a single version of android eg. Cupcake. Now problem is how to debug multiple versions of Android ?

it's easy.

all you have to do is open the .project in notepad
\workspace\.metadata\.plugins\org.eclipse.jdt.core\.org.eclipse.jdt.core.external.folders

and another element to the
linkedresources section.

.link1
2
android-sdk-windows/Donut

Monday, January 17, 2011

How to run multiple instances of Android emulator to SMS?

Today, I wanted to run two instances of emulator to simulate sending and receiving SMS messages.

This is how i managed to make it work.

To create the 2nd instance you need to,

1. Need to create a separate virtual device on Android SDK and AVD Manager.
1.1 Open Eclips -> Window -> Android SDK and AVD Manager

2. Select virtual devices from left panel, Click on New button.

3. Set the name Eg. androidavd2

4. Set the Target Android 2.3 API Level 9 or any other you prefer.

5. Click on ok.

ok, now we have a Android Virtual Device created.

6. Open the Android SDK Tools folder in the command prompt.
C:\android-sdk_r08-windows\android-sdk-windows\Tools

Type:
emulator.exe -avd androidavd2

this will tell the emulator.exe to open android virtual device "androidavd2".

that's it.

Also you can use the telnet. (Windows Vista Up operating systems, you have to download telnet.exe separately because it doesn't come with the default Windows installation.)

to connect using telnet type
telnet localhost 5554

you can use the
adb devices command to see the list of devices currently running. if not You need to start the emulator first!.

then
sms send
eg:
sms send 5554 "Hello android!"

if you have any questions, please drop a line here. good luck.