Amazon Gift Cards

Friday, November 27, 2009

Calling private methods in Android

First and foremost, I won't be held responsible for the content of the article if applied to your apps, and if it results in any kinds of misfunctions and such. Use it at your own risk and use it when there's are no other way that is available in android.

In java, there is a set of API called Reflection API, see this for more detailed look and this for examples. What Reflection does is that it will, from its name, reflect the class for you, reflecting public, private, protected, static and even native variables, function/methods, classes and more. By getting their reflection you could execute private functions or get private class. In this article however, will focus on calling private methods on a public class. We would use SmsManager and test it on Android 1.6 throughout this article.

Update:
1- There is a bug on the emulator, i tested this on G1, sendRawPdu is missing on the reflection


try {
  // the following would just be (but using reflections)
  // sm.sendTextMessage("", null, "Test", null, null);

  // initialize variables
  SmsManager sm = SmsManager.getDefault();
  Class c = sm.getClass();

  // debug, print all methods in this class , there are 2 private methods in this class
  Method[] ms = c.getDeclaredMethods();
  for (int i = 0; i < ms.length; i++)     Log.d("ListMethos",ms[i].toString());   // get private method 1   Method m1 = SmsManager.class.getDeclaredMethod("createMessageListFromRawRecords", List.class);   Log.d("success","success getting sendRawPdu");   // get private method 2   byte[] bb = new byte[1];   Method m2 = SmsManager.class.getDeclaredMethod("sendRawPdu",bb.getClass(),bb.getClass(), PendingIntent.class,PendingIntent.class);   Log.d("success","success getting sendRawPdu");   // send message   m2.setAccessible(true);   SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu( null,"", "Test", false);
  m2.invoke(sm, pdus.encodedScAddress, pdus.encodedMessage, null, null );

  Log.d("success","success sedding message");
} catch (SecurityException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
} catch (NoSuchMethodException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
} catch (IllegalArgumentException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
} catch (IllegalAccessException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
} catch (InvocationTargetException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}



Explanation
Get the private method from the SmsManager class having one argument of List
Method m1 = SmsManager.class.getDeclaredMethod("createMessageListFromRawRecords", List.class);
-- From our trace: D/ListMethos( 2900): private java.util.ArrayList android.telephony.SmsManager.createMessageListFromRawRecords(java.util.List)

Get another method from SmsManager that has 4 argument
Method m2 = SmsManager.class.getDeclaredMethod("sendRawPdu",bb.getClass(),bb.getClass(), PendingIntent.class,PendingIntent.class);
-- From our trace: D/ListMethos( 2900): private void android.telephony.SmsManager.sendRawPdu(byte[],byte[],android.app.PendingIntent,android.app.PendingIntent)

Make the private function to be public
m2.setAccessible(true);

Call the method m2(sendRawPdu) on SmsManager object with the following parameters
m2.invoke(sm, pdus.encodedScAddress, pdus.encodedMessage, null, null );

Basically thats it :) Hope this helps and remember limit the use of this, its not recommended by all means :)

Tuesday, November 24, 2009

Releasing SpeakUp Android App Source

After not making it through ADC2, me and my friends decided to release the source code of SpeakUp, unlike previous projects like Monmonja Battery and Talking Caller, we are releasing it under GPLv3. We believe this would be better to keep this project and other projects that will use the source base to be in and stay in the open source world. We are releasing the official ADC version of the App, the market version of the app would remain closed source until we decided to open it up too (most probably, and currently they are almost the same). Anyway hope this sources would help others in making android apps.

On the new source, there are few updates and few fixes and uses the default TextToSpeech in android 1.6.

Head over Google code for the source.
SpeakUp in Google Code

Thursday, November 19, 2009

Select a RadioButton from Multiple RadioGroup in Android

I bounds into Radiogroup layout question while trying out something in android. The problem is that you want a RadioButton but you don't want it to just be either horizontally placed or vertically placed which is the default way RadioGroup does. Say you want 2 rows of 4 RadioButton, by default you cant do this with one RadioGroup, so the solution is to make 2 RadioGroup but the problem now is that you need to handle both RadioGroup in turn that when one RadioButton is selected on one RadioGroup the other RadioGroup/s will deselect itself. To do this here is the code on how i did it (it has 3 RadioGroups), it might not be the best solution :)

private Boolean changeGroup = false;
public void onCheckedChanged(RadioGroup group, int checkedId){
  if (group != null && checkedId > -1 && changeGroup == false){
    if(group == frequencyGroup1){
      changeGroup = true;
      frequencyGroup2.clearCheck();
      frequencyGroup3.clearCheck();
      changeGroup = false;
    }else if(group == frequencyGroup2){
      changeGroup = true;
      frequencyGroup1.clearCheck();
      frequencyGroup3.clearCheck();
      changeGroup = false;
    }else if(group == frequencyGroup3){
      changeGroup = true;
      frequencyGroup1.clearCheck();
      frequencyGroup2.clearCheck();
      changeGroup = false;
    }
  }
}


Explanation
Create a flag stating that we mark as whether the function could be execute or not (see below)
private Boolean changeGroup = false;

On the default change function of RadioGroup, create a conditional statement that would execute the change function of all RadioGroup only when our flag state that it can execute the next code block. By default this function will execute when you select a RadioButton on a Group and/or when you call clearCheck() of each RadioGroup, and you may not want to do that especially when we call clearCheck.
if (group != null && checkedId > -1 && changeGroup == false){

The following code will just set the flag to true when users select a RadioButton on any group, thus when other RadioGroup call clearCheck() the code block in the function will not be called.
.....


Hope i could explain it more clearly but its kinda hard :)

Update History
   Jan 17, 2012 - Visual Update

Sunday, November 8, 2009

Want to test your app in x86 android?

After weeks of being busy, finally had a time to play with android :) So i tried the live cd of android x86. Head over http://code.google.com/p/live-android/downloads/list and download the latest version.

Im using parallel on mac and i could get the internet and other stuff to work, the market is not the default market you have on your android phone right now but its an okay market. Its quite fast since i allocated 1Gb of ram to it. lol

Search Amazon.com for android phone

By this I its faster to debug your application using this than the emulator. If you want do to so, here is a brief concept of how it could work.
* Make sure you have a webserver (XAMPP should be fine)
* If its newly installed then change the DocumentRoot of Apache (not really recommended) to the location of your working environment (your workspace folder), the configuration of apache is at under xamppfiles/etc/httpd.conf of your XAMPP folder on
* If you dont want to change the DocumentRoot of your Apache or if the previous step didnt work, then either make a symbolic link of the folder, mount the folder, create a VirtualHost on httpd.conf. I'm not really sure of this one. Will any apache expert shared a light on this one. Thanks.
* Start and restart your apache (use the XAMPP control applet/panel)
* On your virtual machine, head over the browser to download your app. By default when you compile in eclipse an apk is generated under the bin folder. For example http://192.168.1.100/workspace/monBattery/bin/monBattery.apk and it should install.

I'll update the last part of the post when the concept becomes a reality. :)

Sunday, October 18, 2009

Turn off, Turn on wifi in android using code tutorial

Here is how to turn on and turn off wifi in android.

First you need to declare the following in your manifest file
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>

After doing it that on your Activity class
private WifiManager wifiManager;
@Override 
public void onCreate(Bundle icicle) {
  ....................
  wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
  if(wifiManager.isWifiEnabled()){
    wifiManager.setWifiEnabled(false);
  }else{
    wifiManager.setWifiEnabled(true);
  }
}


Explanation
Get the Wifi service from our system
wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);

Check the our wifi is currently turned on or turned off
if(wifiManager.isWifiEnabled()){

Turn on/off our wifi
wifiManager.setWifiEnabled(<true|false>);

Reference
WifiEnabler
Permissions Journey: ACCESS_WIFI_STATE

Update History
   Jan 17, 2012 - Visual Update

Monday, October 12, 2009

How to insert image data to sqlite database in Android and how to retrieve it back

I ran across doing something that would required me to get an image from the internet and save it in the database instead of saving it in the file system then retrieving back the stored image from the database to be displayed in ImageView. Using other database server, we usually use blob to store binary data to the database, since SQLite has no field type we could use BLOB as its field type. Your create statement should appear like this
CREATE TABLE storedImages (_id INTEGER PRIMARY KEY, myImage BLOB)

To get the image from the internet and store it on our database
DefaultHttpClient mHttpClient = new DefaultHttpClient();
HttpGet mHttpGet = new HttpGet("your image url");
HttpResponse mHttpResponse = mHttpClient.execute(mHttpGet);
if (mHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
  HttpEntity entity = mHttpResponse.getEntity();
    if ( entity != null) {
      // insert to database
      ContentValues values = new ContentValues();
      values.put(MyBaseColumn.MyTable.ImageField, EntityUtils.toByteArray(entity));
      getContentResolver().insert(MyBaseColumn.MyTable.CONTENT_URI, values);
    }
}


Explanation
Create a new HTTP Client
DefaultHttpClient mHttpClient = new DefaultHttpClient();

Make a request to get our image
HttpGet mHttpGet = new HttpGet("your image url");
HttpResponse mHttpResponse = mHttpClient.execute(mHttpGet);


See if our request is a 200 or has an okay return status
if (mHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {

Get the entity of our request
HttpEntity entity = mHttpResponse.getEntity();

Convert the content of the entity to byte array so that we could store it on our database
values.put(MyBaseColumn.MyTable.ImageField, EntityUtils.toByteArray(entity));

Insert our image to the databse
getContentResolver().insert(MyBaseColumn.MyTable.CONTENT_URI, values);

Retrieving the image back
Here is it assumed that you are using Custom CursorAdaptor, see Custom View in your ListActivity and Custom Adapter in Android
ImageView myImage = (ImageView) findViewById(R.id.myImage);
byte[] bb = cursor.getBlob(cursor.getColumnIndex(MyBaseColumn.MyTable.ImageField));
myImage.setImageBitmap(BitmapFactory.decodeByteArray(bb, 0, bb.length));


Explanation
Get the image back from our database
byte[] bb = cursor.getBlob(cursor.getColumnIndex(MyBaseColumn.MyTable.ImageField));

Decode our image to become a bitmap so that our imageView will display it properly
myImage.setImageBitmap(BitmapFactory.decodeByteArray(bb, 0, bb.length));

Thursday, October 8, 2009

Launching other application using code in Android

Previously we blogged about how to delete application by their package name. Now here is how to open applications using code, note this is not the same as intent-filter.

Say you want to open fuelgauge in Android 1.6, to do this.
final Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.fuelgauge.PowerUsageSummary");
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity( intent);


Explanation
To open other people's application, you need to make sure that in their manifest file, the author specify the class to have the android.intent.action.MAIN intent-filter added to them.
final Intent intent = new Intent(Intent.ACTION_MAIN, null);

We then add category that this new intent will be launching something
intent.addCategory(Intent.CATEGORY_LAUNCHER);

Then we get identify the application we need to open by using ComponentName, here you specify the package name of the application as first argument and the class we want to open as the second one. You must understand that com.android.settings has a lot of classes that have Main intent-filter under it making the second argument to be the specific class that we need. (this is more than one line)
final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.fuelgauge.PowerUsageSummary");

After we identify the component we want, we set it to our intent
intent.setComponent(cn);

We then tell the intent that open opening this one make it as a new task
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Then finally start our intent
startActivity( intent);

Resources
LauncherProvider.java
IRC #android-dev room

Update History
   Jan 17, 2012 - Visual Update

Tuesday, October 6, 2009

Deleting applications by their package name using codes in android

After releasing the application to delete applications by their package name, you may asked how is this done on android. And here is how i did it.
Uri uri = Uri.fromParts("package", <Your Package name here>, null);
Intent deleteIntent = new Intent(Intent.ACTION_DELETE, uri);
startActivity(deleteIntent);


Explanation
We build the proper package name using Uri.fromParts function, this will results in something like package://xxx
Uri uri = Uri.fromParts("package", <Your Package name here>, null);

We then create a new intent that have the delete action with our package uri
Intent deleteIntent = new Intent(Intent.ACTION_DELETE, uri);

Finally we start the deleteIntent that would show us the uninstall application dialog box
startActivity(deleteIntent);

Hope this helps

Update History
   Jan 17, 2012 - Visual Update

Saturday, September 19, 2009

Using the official TextToSpeech in Android 1.6 tutorial

Update There is a official post from android team on this on http://android-developers.blogspot.com/2009/09/introduction-to-text-to-speech-in.html

Android 1.6 SDK had been released and previously if you want TTS on your app, you have to use the one from eyes-free, while this one was the whole inspiration of having TTS by default on android, an official API is official. lol

If you have used the one from eyes-free, its mostly the same way except you'll be using android.speech.tts.TextToSpeech

Main
public class Main extends Activity implements TextToSpeech.OnInitListener {
  TextToSpeech tts;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    tts = new TextToSpeech(this,this);
  }

  public void onInit(int status) {
    Locale loc = new Locale("es", "","");
    if(tts.isLanguageAvailable(loc) >= TextToSpeech.LANG_AVAILABLE){
      tts.setLanguage(loc);
    }
    tts.speak("hola mundo", TextToSpeech.QUEUE_FLUSH, null);
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    tts.shutdown();
  }
}


Explanation
We implement the OnInitListener for us know that the TextToSpeech is ready
public class Main extends Activity implements TextToSpeech.OnInitListener

Create a TextToSpeech instance where the first param is the context and second is the init function (the one we implemented)
tts = new TextToSpeech(this,this);

Function that we implemented, this function will be called after the TextToSpeech is ready to be used
public void onInit(int status) {

Determine if the language is available for us to use ( > TextToSpeech.LANG_AVAILABLE coz higher value means the language is available, use LANG_COUNTRY_AVAILABLE if you want to use UK english or Portuguese spanish)
if(tts.isLanguageAvailable(loc) >= TextToSpeech.LANG_AVAILABLE){

Set new language if the language data is present
tts.setLanguage(loc);

Speak the words, and TextToSpeech.QUEUE_FLUSH means speak it right away.
tts.speak("hola mundo", TextToSpeech.QUEUE_FLUSH, null);

Hope this helps

References
TextToSpeech
TextToSpeech GIT snapshot
Eyes free

Update History
   Jan 17, 2012 - Visual Update

Friday, September 4, 2009

Extending and Customizing GridView with Custom Listener in Android

After customizing ListView now we will see how to customize and extend your GridView then we will add Custom Listener to it as well.

First we need to create our custom GridView, we used the package com.almondmendoza.myGridView
public class MyCustomGridView extends GridView implements OnItemClickListener{
  private Listener mListener;

  public MyCustomGridView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setOnItemClickListener(this);
  }

  public void onItemClick(AdapterView parent, View v, int position, long id) {
    if (mListener != null) {
      mListener.onClick(position);
    }
  }

  public void setListener(Listener l){
    mListener = l;
  }

  public interface Listener{
    void onClick(int position); 
  }   
}



Explanation
Let us extend GridView and implement OnItemClickListener so that we could have a click even on each item
public class MyCustomGridView extends GridView implements OnItemClickListener

Use this constructor so we could use this class on our xml
public MyCustomGridView(Context context, AttributeSet attrs) { ... }

Create an Listener interface for us to use in other classes
public interface Listener{ void onClick(int position); }

Function which will be called when an item is clicked (implementation of OnItemClickListener)
public void onItemClick(AdapterView parent, View v, int position, long id) {

Call our onClick function from the instance that uses our Listener interface
if (mListener != null) { mListener.onClick(position); }







Main Class
public class Main extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    MyCustomGridView mGrid = (MyCustomGridView) findViewById(R.id.my_custom_grid_view);
    mGrid.setListener(new ItemListener());
    mGrid.setAdapter(new ImageAdapter(this)); 
  }

  private class ItemListener implements MyCustomGridView.Listener{
    public void onClick(int position) {
      Log.d("almond","test");
    }
  }

  public class ImageAdapter extends BaseAdapter {
    private Context mContext;
    public ImageAdapter(Context c) {
      mContext = c;
    }

    public int getCount() {
      return mThumbIds.length;
    }

    public Object getItem(int position) {
      return null;
    }

    public long getItemId(int position) {
      return 0;
    }

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
      ImageView imageView;
      if (convertView == null) {  // if it's not recycled, initialize some attributes
        imageView = new ImageView(mContext);
        imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setPadding(8, 8, 8, 8);
      } else {
        imageView = (ImageView) convertView;
      }
      imageView.setImageResource(mThumbIds[position]);
      return imageView;
    }

    private Integer[] mThumbIds = {
      R.drawable.icon,R.drawable.icon,R.drawable.icon
    };
  }
}



Explanation
We had used xml with our MyCustomGridView and here we get that view
MyCustomGridView mGrid = (MyCustomGridView) findViewById(R.id.my_custom_grid_view);

Create a class that uses the Listener interface we used in MyCustomGridView
private class ItemListener implements MyCustomGridView.Listener{ ... }

Set an instance of the ItemListener class
mGrid.setListener(new ItemListener());

As GridView is an extension of a AbsListView, we need a ListAdapter and we extend BaseAdapter (Please read this for the explanation of the codes inside - Hello GridView)
public class ImageAdapter extends BaseAdapter { ... }

We then set an instance of ImageAdaptor to be our adapter to our GridView
mGrid.setAdapter(new ImageAdapter(this));






Main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
>
  <com.almondmendoza.myGridView.MyCustomGridView
    android:id="@+id/my_custom_grid_view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:cacheColorHint="#00000000"
    android:listSelector="@android:color/transparent"
    android:numColumns="auto_fit"
    android:columnWidth="160px"
  />
</LinearLayout>



Explanation
Use our class with our XML
<com.almondmendoza.myGridView.MyCustomGridView ... >


References
Launcher app
Browser App
Hello GridView

Update History
   Jan 17, 2012 - Visual Update

Tuesday, September 1, 2009

Speak Up!!!

The pass few weeks I had been in silent for the reason that I was preparing to submit an application for ADC2 (besides the time i had for my sister's wedding). And now I'm breaking the silence and getting myself to Speak Up!!!

Speak Up!!! is an android application designed to test your English speaking skills, it has 3 levels (easy, medium and hard) to choose from, and over 100+ words to randomized. On each stage you will have N randomized words (you could change N on the preference menu) and you have to speak each words correctly. In the end it will calculate the correct and wrong words that you have spoken.

From the technology standpoint, the app uses the Speech-to-text function of the phone (abuses it, lol) and used the database to store the words that you need to say. It's designed to be simple and designed for non native English speakers though native English Speakers are fully welcome to try it out.

At the end, either we win or not, we hope to change the world, to make it a better place through technology and through the gifts that had been given to us. We sincerely hope that our application would help you all in any way possible.

And I would like to thank Gary Law for this wonderful designs and layout.

Monday, August 10, 2009

Custom View in your ListActivity and Custom Adapter in Android

After 2-3 weeks of being absent in Android land, due to over working (going home pass 12am.......), i'm back with another tutorial on how to make your ListActivity have a view that you like or custom view. In order for us to jump right ahead, you must first know that custom view on your ListActivity means custom view per row on the ListView and usually we need to create or its better to create a custom adapter for it.

For this tutorial, i would reference to the Display Contact Names in Android therefore we need to add READ_CONTACTS on our manifest file.

On our custom_list.xml we would have
<?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:id="@+id/txtName"
  />

  <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/txtPhone"
  />

  <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/txtDisplayName"
  />
</LinearLayout>



Explanation
This would just give us 3 TextView on vertical order, this would be our custom row therefore on your application if you want to customize the row then this is the file that you might want to work upon.



Main.java
public class Main extends ListActivity  {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Cursor contactsCursor = this.managedQuery(People.CONTENT_URI, null, null, null, null);
    this.setListAdapter(new MyContactsAdapter(this,contactsCursor));
  }

  private class MyContactsAdapter extends CursorAdapter{
    private Cursor mCursor;
    private Context mContext;
    private final LayoutInflater mInflater;

    public MyContactsAdapter(Context context, Cursor cursor) {
      super(context, cursor, true);
      mInflater = LayoutInflater.from(context);
      mContext = context;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
      TextView t = (TextView) view.findViewById(R.id.txtName);
      t.setText(cursor.getString(cursor.getColumnIndex(People.NAME)));

      t = (TextView) view.findViewById(R.id.txtDisplayName);
      t.setText(cursor.getString(cursor.getColumnIndex(People.DISPLAY_NAME)));

      t = (TextView) view.findViewById(R.id.txtPhone);
      t.setText(cursor.getString(cursor.getColumnIndex(People.NUMBER)));
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
      final View view = mInflater.inflate(R.layout.custom_list, parent, false);
      return view;
    }
  }
}



Explanation
Query our contacts table
Cursor contactsCursor = this.managedQuery(People.CONTENT_URI, null, null, null, null);

Set the adapter for our ListView
this.setListAdapter(new MyContactsAdapter(this,contactsCursor));

We create a class for our custom adapter named MyContactsAdapter extending it to CursorAdapter (There are a lot of adapter that you could extend upon)
private class MyContactsAdapter extends CursorAdapter

We get the LayoutInflater from the calling context, what this does is that it will inflate your xml to codes via View object. see newView function
mInflater = LayoutInflater.from(context);

On newView function we inflate our layout to the binded view inside CursorAdapter
final View view = mInflater.inflate(R.layout.custom_list, parent, false);

At this point we have our custom_list as the layout of our ListActivity, now what we need is to use it on every row, you would do it with bindView function
public void bindView(View view, Context context, Cursor cursor) { ..... }

The following should be just binding our TextView in xml to our codes and getting values from our cursor and putting that value to the respective TextView
TextView t = (TextView) view.findViewById(R.id.txtName);
t.setText(cursor.getString(cursor.getColumnIndex(People.NAME)));



Notes
Do note that we extend to CursorAdapter here and it might be different on other adapter, like for ArrayAdapter you will use getView function, good luck....


Reference
http://www.google.com/codesearch/p?hl=en&sa=N&cd=1&ct=rc#kZ0MkhnKNzw/trunk/Photostream/src/com/google/android/photostream/LoginActivity.java&q=CursorAdapter%20package:http://apps-for-android\.googlecode\.com

Hope this help.

Thursday, July 16, 2009

Permissions Journey: RECEIVE_BOOT_COMPLETED Tutorial

When you need your application to start when the phone had powered on, then you need to use the RECEIVE_BOOT_COMPLETED permission. On this tutorial i will use the Battery Status Application for reference.

First up, you need to add the permission on the manifest file and the receiver class
<application android:icon="@drawable/icon" android:label="@string/app_name">
  .....
  <receiver android:name=".BatteryReceiver">
  <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
  </receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

Explanation
Tell android that we have a receiver
<receiver android:name=".BatteryReceiver">

Tell android that we need to do something after the boot is completed
<action android:name="android.intent.action.BOOT_COMPLETED" />

Now tell android that we need a boot complete permission
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />





BatteryReceiver Class
public class BatteryReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    // do what ever you want
    PrefsActivity.connectToBatteryService(context);
  }
}



Explanation
First we need to extend our class to BroadcastReceiver to receive an instruction
public class BatteryReceiver extends BroadcastReceive

Then the magic takes place at onReceive function, on my app i just enable the BatteryService class
// do what ever you want

Hope this helps

Update History
   Jan 17, 2012 - Visual Update

Monday, July 13, 2009

Exporting Bitmap to Image Folder in Android

Say you have a bitmap (dynamically created or what) and you want to save that bitmap to the image folder of the external sdcard. you could do something like this. For better result you could use Threads to preform this operation.

String filename = String.valueOf(System.currentTimeMillis()) ;
ContentValues values = new ContentValues();   
values.put(Images.Media.TITLE, filename);
values.put(Images.Media.DATE_ADDED, System.currentTimeMillis()); 
values.put(Images.Media.MIME_TYPE, "image/jpeg");

Uri uri = context.getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);
try {
  OutputStream outStream = context.getContentResolver().openOutputStream(uri);
  mBitmap.compress(Bitmap.CompressFormat.JPEG, 90, outStream);
  outStream.flush();
  outStream.close();
  Log.d("done","done");
} catch (FileNotFoundException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
}




Explanation
First we create the current time as the filename of our new image
String filename = String.valueOf(System.currentTimeMillis()) ;

Create a ContentValue and put the fields needed to insert a new image to our Image Database
ContentValues values = new ContentValues();
......


Tell the Image Database on which type are we going to save, you can change this to image/png if you need the alphas
values.put(Images.Media.MIME_TYPE, "image/jpeg");

Add the new record to our image Database
Uri uri = context.getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);

Open an output stream of our bitmap on the URI that is returned after we inserted a new record
OutputStream outStream = context.getContentResolver().openOutputStream(uri);

Using our bitmap (mBitmap), output the bitmap with the compression and quality to the output stream
mBitmap.compress(Bitmap.CompressFormat.JPEG, 90, outStream);

Flush and close the stream
outStream.flush();
outStream.close();


Hope this helps


Reference
http://www.developer.com/java/j2me/article.php/3748281

Update History
   Jan 17, 2012 - Visual Update

Monday, June 8, 2009

Drawing with Canvas in Android

Update - Nov 21, 2010
Created a series over this topic over at Drawing with Canvas Series, more articles would appear in the future :)

Update - Nov 13, 2010
There is a renewed/enchanced version of this tutorial though i still recommend to read this article if you're completely new to Android or Canvas in Android, for we reference back to this article. The updated one is at Drawing with Canvas in Android Renewed

Introduction
If you had been reading previous post then you'll know i'm not a java guy, i literally spend hours trying to figure out how canvas works perfectly on java. Then i remember that javascript/html5 has canvas too, so i revisited this one (haven't visited it for almost half a year) https://developer.mozilla.org/en/drawing_graphics_with_canvas and see that i must use paths (2nd example, beginPath) rather than drawing point by point. So together with this article http://www.droidnova.com/playing-with-graphics-in-android-part-iv,182.html. I come up with a pretty descend drawing app.


To do this:
Copy the whole code from droidnova the replace the following.

On your Activity
private ArrayList _graphics = new ArrayList();
private Paint mPaint;
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(new DrawingPanel(this));
  mPaint = new Paint();
  mPaint.setDither(true);
  mPaint.setColor(0xFFFFFF00);
  mPaint.setStyle(Paint.Style.STROKE);
  mPaint.setStrokeJoin(Paint.Join.ROUND);
  mPaint.setStrokeCap(Paint.Cap.ROUND);
  mPaint.setStrokeWidth(3);
}


On your SurfaceView
@Override
public boolean onTouchEvent(MotionEvent event) {
  synchronized (_thread.getSurfaceHolder()) {
    if(event.getAction() == MotionEvent.ACTION_DOWN){
      path = new Path();
      path.moveTo(event.getX(), event.getY());
      path.lineTo(event.getX(), event.getY());
    }else if(event.getAction() == MotionEvent.ACTION_MOVE){
      path.lineTo(event.getX(), event.getY());
    }else if(event.getAction() == MotionEvent.ACTION_UP){
      path.lineTo(event.getX(), event.getY());
      _graphics.add(path);
    }
    return true;
  }
}
@Override
public void onDraw(Canvas canvas) {
  for (Path path : _graphics) {
    //canvas.drawPoint(graphic.x, graphic.y, mPaint);
    canvas.drawPath(path, mPaint);
  }
}


Explanation
We create a path and start that path when the MotionEvent is down, or when the user first touch the screen, then add a lineTo, the x and y when the user moves his fingers. Then stop and push the path we had build to our array of Paths.
public boolean onTouchEvent(MotionEvent event) { .... }

Then during the draw function we loop through the array and print them on our canvas.
public void onDraw(Canvas canvas) { ... }


References
http://www.droidnova.com/playing-with-graphics-in-android-part-iv,182.html
https://developer.mozilla.org/en/drawing_graphics_with_canvas
Android IRC - irc://freenode/android-dev

Sunday, June 7, 2009

Implement GestureDetector in Android

You want to implement Gesture on your Android, gladly android has a build in Simple GestureDetector for you. Here is how you use it
private GestureDetector mGestureDetector;
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  mGestureDetector = new GestureDetector(this, new LearnGestureListener());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
  if (mGestureDetector.onTouchEvent(event))
    return true;
  else
    return false;
}
class LearnGestureListener extends GestureDetector.SimpleOnGestureListener{
  @Override
  public boolean onSingleTapUp(MotionEvent ev) {
    Log.d("onSingleTapUp",ev.toString());
    return true;
  }
  @Override
  public void onShowPress(MotionEvent ev) {
    Log.d("onShowPress",ev.toString());
  }
  @Override
  public void onLongPress(MotionEvent ev) {
    Log.d("onLongPress",ev.toString());
  }
  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    Log.d("onScroll",e1.toString());
    return true;
  }
  @Override
  public boolean onDown(MotionEvent ev) {
    Log.d("onDownd",ev.toString());
    return true;
  }
  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    Log.d("d",e1.toString());
    Log.d("e2",e2.toString());
    return true;
  }
}



Explanation
First we create a GestureDetector instance
private GestureDetector mGestureDetector;

Then we create a GestureListener for us to listen
class LearnGestureListener extends GestureDetector.SimpleOnGestureListener{ ...... }

After creating those 2, we bind our listener to our GestureDetector instance
mGestureDetector = new GestureDetector(this, new LearnGestureListener());

Lastly we need to know where the event listener will be trigger, that is where onTouchEvent comes in
public boolean onTouchEvent(MotionEvent event) {
if (mGestureDetector.onTouchEvent(event)) .....
}


** The function on our LearnGestureListener class have logical name except onFling which means on swipe.

Reference
Code Shogun
Calandar Android App

Update History
   Jan 17, 2012 - Visual Update

Trace your post data in server side using HttpPost in Android

By default you could trace your variables or your post data (or even get data) using breakpoints, but after that what happens between android and your server is a bit hard to trace specially if somewhere a long the way there's an error on your post data. This piece of code is from my flash experiences where the firebug or httpwatch or even charles cannot see the flash requesting the server. This is done on php but it could be used on other server side languages since its just echo command from linux based or mac or unix based os.
exec("echo '". addslashes(print_r($_REQUEST,true)) . addslashes(print_r($_FILES,true)). "' > /Applications/xampp/htdocs/something.out");


Explanation
As you can see it will print the array and echo that array to something.out. You could open something.out with vi or any texteditor.

**NOTE
* There are some servers that cannot use exec, for this you have to call your System Administrator
* For java, take a look at Runtime, there is something like runtime.exec("command")

Sunday, May 31, 2009

How to use XmlPullParser in Android

A post from androidguys.com stated that using XmlPullParser instead of DOM might be better in power saving. As i non java guy, i first didn't know what this one is. So today i tried to examine how to use it. And here is what i come up with. Please comment if the stuff i did is wrong or could be further optimized.

Note: XmlUtils is by default not included in the SDK, you can grab the class here. If there is an error, just remove the error.

public static void getAllXML(String url) throws 
XmlPullParserException, IOException, URISyntaxException{ 
  XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
  factory.setNamespaceAware(true);
  XmlPullParser parser = factory.newPullParser(); 
  parser.setInput(new InputStreamReader(getUrlData(url)));  
  XmlUtils.beginDocument(parser,"results");
  int eventType = parser.getEventType();
  do{
    XmlUtils.nextElement(parser);
    parser.next();
    eventType = parser.getEventType();
    if(eventType == XmlPullParser.TEXT){
      Log.d("test",parser.getText());
    }
  } while (eventType != XmlPullParser.END_DOCUMENT) ;       
}
public InputStream getUrlData(String url) 
throws URISyntaxException, ClientProtocolException, IOException {
  DefaultHttpClient client = new DefaultHttpClient();
  HttpGet method = new HttpGet(new URI(url));
  HttpResponse res = client.execute(method);
  return  res.getEntity().getContent();
}



Explanation
The getAllXml function would call getUrlData that would return an InputStream and pass it to the XmlPullParser
XmlPullParser parser = factory.newPullParser();
parser.setInput(new InputStreamReader(getUrlData(url)));


Then we would loop through the whole xml. This part is a bit complicated to explain so i apologize in advance if you would understand the following sentences.
On the loop we first we have to find out, base on the parser, which eventType the current element is at. The common event type that you would use are START_DOCUMENT, END_DOCUMENT, START_TAG, END_TAG, TEXT. Since we use the XMLUtils, which have a function that would help us get the nextElement without worrying about the closetags, text or comments in between the current tag and the next tag. After we get the next element tag, we parse the next one and see if its a TEXT (This might have some errors on your xml), if its a TEXT then we do our magic here. If you have an attribute, you may use getAttribute before the parse.next() on the current tag.

References
TelephonyProvider.java
XmlSnapshot.java (See this to understand the eventType stuff)
WebClient.java

Update History
   Jan 17, 2012 - Visual Update

Tuesday, May 26, 2009

Permissions Journey: ACCESS_NETWORK_STATE

ACCESS_NETWORK_STATE as what the description on the permissions page stated, it allows your application to access information about your network. To use this permissions.

Manifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" ></uses-permission>

Main.java
ConnectivityManager conMan = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = conMan.getActiveNetworkInfo();
Log.d("Connected state",networkInfo.getState().toString());
if(networkInfo.isConnected()){
  Log.d("Connected",networkInfo.toString());
}

Explanation
First we need to get the system service that answers queries about the state of network connectivity.
ConnectivityManager conMan = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);

Then we get our active network
NetworkInfo networkInfo = conMan.getActiveNetworkInfo();

We then check the current state of the network
Log.d("Connected state",networkInfo.getState().toString());

We check if this network is connected or not
if(networkInfo.isConnected()){ ...... }

If our network is connected then most likely we would do our magic on that block, but for now let us trace the network
Log.d("Connected",networkInfo.toString());

References
ConnectivityManager
NetworkInfo
http://www.google.com/codesearch/p?hl=en#MkYB9wOx8C4/trunk/DroidGuide/Client/src/br/ufmg/ubicomp/droidguide/utils/AndroidUtils.java&q=networkinfo%20android

Update History
   Jan 17, 2012 - Visual Update

Permissions Journey: ACCESS_WIFI_STATE

ACCESS_WIFI_STATE allows applications to access information about Wi-Fi networks, pretty much explained it all.

Manifest file
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" ></uses-permission>

Main.java
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
Log.d("wifiInfo",wifiInfo.toString());

Explanation
First we need to get our Wifi service, WifiManager class is pretty much the class you need for wifi connectivity.
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);

Get the infomration of the current wifi connection information with getConnectionInfo
WifiInfo wifiInfo = wifiManager.getConnectionInfo();

For now we trace our connection
Log.d("wifiInfo",wifiInfo.toString())

I got this result since i didnt turn on my wifi, you could turn your wifi on via settings and try to trace it again.
SSID: , BSSID: , MAC: 00:18:41:c8:62:98, Supplicant state: UNINITIALIZED, RSSI: -200, Link speed: 54, Net ID: -1

References
WifiManager
WifiInfo
http://www.google.com/codesearch/p?hl=en#8ckgoBxhL4o/trunk/src/android/tether/TetherApplication.java&q=WiFi%20android

Update History
   Jan 17, 2012 - Visual Update

Sunday, May 24, 2009

Permissions Journey: VIBRATE

Lets jump to Vibrate Permissions on Android. By default everything you need to know could be found at the Vibrator Class. To give an example of using vibrate:

Manifest file
<uses-permission android:name="android.permission.VIBRATE" ></uses-permission>

Archos 5 32 GB Internet Tablet with Android

Main.xml Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
>
  <Button  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:id="@+id/simpleBtn"
    android:text="Simple Vibrate"
  />
  <Button
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/patternBtn"
    android:text="Pattern Vibrate"
  />
  <Button  
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/cancelBtn"
    android:text="Cancel Vibrate"
  />
</LinearLayout>


Main.java
private Button simpleBtn;
private Button patternBtn;
private Button cancelBtn;
private Vibrator vibrator; 
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  simpleBtn = (Button)findViewById(R.id.simpleBtn);
  simpleBtn.setOnClickListener(this);
  patternBtn = (Button)findViewById(R.id.patternBtn);
  patternBtn.setOnClickListener(this);
  cancelBtn = (Button)findViewById(R.id.cancelBtn);
  cancelBtn.setOnClickListener(this);
  vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
}
public void onClick(View v) {
  if(v==simpleBtn){
    vibrator.vibrate(500);
  }else if(v == patternBtn){
    long[] pattern = {0L,100L,250L,1000L,250L,500L};
    vibrator.vibrate(pattern,2);
  }else{
    vibrator.cancel();
  }
}


Explanation
We create 3 buttons simpleBtn, patternBtn and cancelBtn and bind the onclick listener to the class.

First we get our vibrator service
vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);

Then on our simpleBtn, we use the vibrate function and vibrate the phone for 500ms
vibrator.vibrate(500);

On our patternBtn, we use an array (long), where the array reads as 0L(off), 100L (on), 250L (off) and so on. Then after completing the first pattern we repeat the series from the 3rd value (250L(off),2 on our function, 0 based index)
long[] pattern = {0L,100L,250L,1000L,250L,500L};
vibrator.vibrate(pattern,2);


On our cancelBtn, we simple cancel the vibration we created
vibrator.cancel();

Reference
Vibrator Class
http://www.google.com/codesearch/p?hl=en#tk1mgwvuros/trunk/src/au/id/weston/scott/Sketchaetch/Sketchaetch.java&q=VIBRATOR_SERVICE&l=287

Update History
   Jan 17, 2012 - Visual Update

Changing the Screen Brightness Programatically in Cupcake

Previously we had blogged about on how to change the screen brightness in android pre cupcake and on cupcake, the android team had added an official way to change the brightness without the hacks. Here is how to use it:

WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = 100 / 100.0f;
getWindow().setAttributes(lp);



References:
http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#screenBrightness
http://groups.google.com/group/android-developers/browse_thread/thread/6de1cb84596a1c9b

Update History
   Jan 17, 2012 - Visual Update

Friday, May 22, 2009

Permissions Journey: ACCESS_FINE_LOCATION

Our second journey takes a peek to ACCESS_FINE_LOCATION permission, where you can use GPS to locate directions. The implementation is basically the same with ACCESS_COARSE_LOCATION except on this article we would further expand the code to use the function requestLocationUpdates.

First up you need to enable your GPS
Settings -> Security and Location -> Enable GPS satellites

Then you need to add ACCESS_FINE_LOCATION to your manifest file
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>

Main.java
private SampleLocationListener mLocationListener;
private LocationManager m_location_manager;
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  mLocationListener = new SampleLocationListener();
  m_location_manager = (LocationManager) getSystemService(LOCATION_SERVICE);
  Boolean gpsEnabled  = m_location_manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
  Log.d("onCreateonCreate",String.valueOf(gpsEnabled));
  m_location_manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, mLocationListener);
}
@Override
protected void onDestroy() {
  // TODO Auto-generated method stub
  super.onDestroy();
  m_location_manager.removeUpdates(mLocationListener);
}
private class SampleLocationListener implements LocationListener {
    public void onLocationChanged(Location location) {
      // TODO Auto-generated method stub
      if(location != null){
        Log.d("SampleLocationListener",location.toString());
      }else{
        Log.d("SampleLocationListener","No location");
      }
    }
  public void onProviderDisabled(String provider) {
    // TODO Auto-generated method stub
    Log.d("SampleLocationListener onProviderDisabled",provider);
  }
  public void onProviderEnabled(String provider) {
    // TODO Auto-generated method stub
    Log.d("SampleLocationListener onProviderEnabled",provider);
  }
  public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub
    Log.d("SampleLocationListener onStatusChanged",provider);
    }
}


Samsung Moment M900 Android Phone (Sprint)

Explanation
First of you need you to create a listener class that would extends LocationListener.
private class SampleLocationListener implements LocationListener { ..... }

Then create an instance of your created LocationListener
mLocationListener = new SampleLocationListener();

Then get the location service that would create a location manager for your GPS later on
m_location_manager = (LocationManager) getSystemService(LOCATION_SERVICE);

You could then check if the GPS is enable or not
Boolean gpsEnabled = m_location_manager.isProviderEnabled(LocationManager.GPS_PROVIDER);

Then you could continue to create a listener to the GPS service, (every 1 sec, on 1 distance change)
m_location_manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, mLocationListener);

Then on your SampleLocationListener class where the magic happens, here you could know if the network had change from GPS to Network, vise versa or other types of network, if the location has been changed, etc.

** Just one piece of advice, remember to shut off or remove the listener when the users close the app
m_location_manager.removeUpdates(mLocationListener);

Rerefences
http://www.google.com/codesearch/p?hl=en#OOgMjZrCM0A/trunk/OpenStreetMapViewer/src/org/andnav/osm/OpenStreetMapActivity.java&q=requestLocationUpdates
http://www.google.com/codesearch/p?hl=en#2OJgWTG3g9s/trunk/VoteReport/src/com/votereport/android/LocationFinderActivity.java&q=requestLocationUpdates
http://www.google.com/codesearch/p?hl=en#wYGukkcNuKc/trunk/Android20090319/Tutorial/AndroidPedometer/src/chikamune/minoru/pedometer/PedometerActivity.java&q=requestLocationUpdates

Update History
   Jan 17, 2012 - Visual Update

Friday, May 15, 2009

Permissions Journey: ACCESS_COARSE_LOCATION

While having problems on ACCESS_CHECKIN_PROPERTIES permission, i decided to journey to ACCESS_COARSE_LOCATION first. Some of you might ask what's the difference between ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION. ACCESS_COARSE_LOCATION is network based location access meaning the location is by your network, it could work with buildings or underground trains as long as you have access to your network while ACCESS_FINE_LOCATION is using gps thus your phone needs to be united with the sky (Correct me if im wrong here).

Now to our code (Tested this on the phone not on emulator).
Add In Manifest.xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
In Main.java
LocationManager m_location_manager = (LocationManager) getSystemService(LOCATION_SERVICE);
Location lm = m_location_manager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Log.d("log",lm.toString());


Explanation
The first line get our system service and the second line would get the last know location based on the network provider.

* Please take note that this assumes that it has a last known location, in order to know have location please see the function requestLocationUpdates.

References:
Google Groups
LocationManager in developer.andriod.com
http://www.google.com/codesearch/p?hl=en#Dgfu4syu6ZY/trunk/src/info/yasskin/droidmuni/DroidMuni.java&q=ACCESS_COARSE_LOCATION
http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/location/java/android/location/LocationManager.java&q=file:%28/|^%29android/location/LocationManager\.java$

Update History
   Jan 17, 2012 - Visual Update

Saturday, April 11, 2009

Open URL/Website from android

Here is a small piece of code to open a URL/Website from your application, place it on your class that has startActivity function, for example your class that extends Activity

String url = "http://almondmendoza.com/android-applications/";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);


Hope this helps.

Friday, April 3, 2009

App that developers need when developing Android App - Log Collector

I barely recommend apps on my blog (or did i) but this is special, there is an application on the market called Log Collector, what it does is it collect the logs from your phone and email it to whom ever you want it to be email to. So how can i make use of this?

As a developer, most of the time you would get a force close when testing your application on a real phone, but most of the time you don't have any idea why it happened. So here is how Log Collector is really useful, after a force close, you immediate email the report log to you or the developer of an application. It might help you a lot or atleast have a clue on what's going on.

Hope this helps :)

Saturday, March 28, 2009

Notification in Android

Notification in android is handy way to notify your user. Here is a very simple example of it. We would combine it with WebView with ZoomControls in Android.

First of all rename the Main class on the WebView tutorial to WebActivity making it
public class WebActivity extends Activity {
private WebView myWebView;


Then import the following to your manifest file
<application android:icon="@drawable/icon" android:label="@string/app_name">
  .....
  <activity android:name=".WebActivity"/>
</application>
<uses-permission android:name="android.permission.INTERNET">


public class Main extends Activity implements View.OnClickListener {
  private Button Button01;
  private NotificationManager mManager;
  private static final int APP_ID = 0; 

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

    this.Button01 = (Button) this.findViewById( R.id.Button01);
    this.Button01.setOnClickListener(this);

    mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
  }

  @Override
  public void onClick(View v) {
    Intent intent = new Intent(this,WebActivity.class);

    Notification notification = new Notification(R.drawable.icon,
"Notify", System.currentTimeMillis());
    notification.setLatestEventInfo(Main.this,
"App Name","Description of the notification",
PendingIntent.getActivity(this.getBaseContext(), 0, intent,
PendingIntent.FLAG_CANCEL_CURRENT));
    mManager.notify(APP_ID, notification);
  }
}



Quick Explanation:
(Most of it is explained on the android dev site)

mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Call the notification service

Notification notification = new Notification(R.drawable.icon,"Notify", System.currentTimeMillis());
*** Create a new notification with an icon and label and do the notification now. See Notification Class

notification.setLatestEventInfo(Main.this,"App Name","Description of the notification",PendingIntent.getActivity(this.getBaseContext(), 0, intent,PendingIntent.FLAG_CANCEL_CURRENT));
*** Set the info of the notification, see Notification Class

mManager.notify(APP_ID, notification);
Notify the notification manager about our new notification and pass an id for it

Output:


Reference:
PhotoStream Source

Update History
   Jan 17, 2012 - Visual Update

Monday, March 23, 2009

Connecting and debugging your application with your phone on Ubuntu 9.04

After a long time, i'm back with an android post. This time is how to connect your g1 to Ubuntu 9.04 (im using 64bit). I won't explain that detailed coz i found an article that could help you with the detailed explanation. Anyway here's how i made it.

* Alt + F2, gnome-terminal then enter

* type: lsusb
look for and memorize the words after ID and before the colon(:) :
Bus 001 Device 004: ID 0bb4:0c02 High Tech Computer Corp.

* sudo gedit /etc/udev/rules.d/50-android.rules

paste the following to the file (the {idVendor} is the one you memorized previously)
* SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"

* sudo chmod a+rx /etc/udev/rules.d/50-android.rules

* sudo /etc/init.d/udev restart


Done with the ubuntu's part, now on android's part
* go to tools folder of your sdk

* sudo ./adb kill-server

* sudo ./adb devices

If it still doesn't work, try connecting it to your computer's back usb post or change the usb cord (coz some usb has lower power then the others)

If you want a detailed explanation on the Ubuntu's part
http://www.johandekoning.nl/index.php/2009/02/07/android-dev-phone-ubuntu-and-vmware-server/
Other resources: http://androidforums.com/support/3534-problems-mounting-communicating-g1-ubuntu.html

Wednesday, February 18, 2009

Detecting if the Sd-Card had been mounted in Android

Here is short article on how to detect if the sd-card had been mounted on android.

String storagestate = Environment.getExternalStorageState();
if (!storagestate.equals(Environment.MEDIA_MOUNTED) ) {
  AlertDialog alertDialog = new AlertDialog.Builder(this).create();
  alertDialog.setTitle(this.getText(R.string.error_sd_card_title));
  alertDialog.setMessage(this.getText(R.string.error_sd_card_desc));
  alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {
      finish();
      return;
  } });
  alertDialog.show();
}

Quick Explanation
String storagestate = Environment.getExternalStorageState();
--- This line gets the storage state, external means your sd-card, change it to internal then it means get the state of your phone memory.

if (!storagestate.equals(Environment.MEDIA_MOUNTED) ) { }
--- This check if the storage's state is mounted, then ! at the front would reverse the result. For more values to compare to, see Environment class


Update History
   Jan 17, 2012 - Visual Update

Saturday, February 14, 2009

MaxLength in EditText using Codes

In android there is EditText and sometimes you may want to limit the character input. EditText in XML layout would give you android:maxLength to do this thing but in codes you might wonder why there isn't any setMaxLength function. The reason behind this is that when you want to restrict the EditText to accept certain value, you have to filter them and this would be invoke by setFilters and thus to make our EditText to have a fixed size we shall.
EditText et = new EditText(this);
int maxLength = 3;
InputFilter[] FilterArray = new InputFilter[1];
FilterArray[0] = new InputFilter.LengthFilter(maxLength);
et.setFilters(FilterArray);


Reference:
androidblogger

Update History
   Jan 17, 2012 - Visual Update

Tuesday, February 3, 2009

WebView with ZoomControls in Android

Here is an article on how to use WebView with ZoomControls enabled. First of all add an Internet permission to your manifest file.
<uses-permission android:name="android.permission.INTERNET">
</uses-permission>

Layout (webview.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" 
>
  <WebView
    android:id="@+id/webView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
  />
</LinearLayout>


public class Main extends Activity {
  private WebView myWebView;
  private static final FrameLayout.LayoutParams ZOOM_PARAMS =
new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
Gravity.BOTTOM);

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.webview);
    this.myWebView = (WebView) this.findViewById(R.id.webView);

    FrameLayout mContentView = (FrameLayout) getWindow().
    getDecorView().findViewById(android.R.id.content);
    final View zoom = this.myWebView.getZoomControls();
    mContentView.addView(zoom, ZOOM_PARAMS);
    zoom.setVisibility(View.GONE);

    this.myWebView.loadUrl("http://www.almondmendoza.com");
  }
}



Quick Explanation:
The stuff here were extracted from BrowserActivity, so if there is an error on my explanation, i apologize in advance.

FrameLayout mContentView = (FrameLayout) getWindow().getDecorView().findViewById(android.R.id.content);
-- According to Windows Decoration, this would retrieve the top-level window decor view.

final View zoom = this.myWebView.getZoomControls();
-- this would get the zoom controls of the webview object

mContentView.addView(zoom, ZOOM_PARAMS);
-- this would add the zoom controls to our our top-level window, the ZOOM_PARAMS was just copied from BrowserActivity, so i dont actually know what it means :)

zoom.setVisibility(View.GONE);
-- This would hide the zoom at the start, we do this because we want to show the zoom controls only when the user's scroll the browser.

this.myWebView.loadUrl("http://www.almondmendoza.com");
-- This would load the url to our webview.


Source:
The codes above are all the sources, you just have to import the right classes. In eclipse just highlight the errors and right click then Quick Fix.

Reference:
BrowserActivity

Saturday, January 31, 2009

Getting the Contact Info when on a number

On android when someone call you or you receive a message, a non formatted number would be shown to you and for you to find out whom that number is, you have to use Contacts.Phones.CONTENT_FILTER_URL on your query. This article is based on Get Phone State When Someone is calling using BroadcastReceiver Example
public class MyPhoneStateListener extends PhoneStateListener {
  private String[] projection = new String[] {
    People._ID, People.NAME, People.NUMBER
  };
  public void onCallStateChanged(int state,String incomingNumber){
    switch(state)
    {
      case TelephonyManager.CALL_STATE_IDLE:
        Log.d("DEBUG", "IDLE");
      break;
      case TelephonyManager.CALL_STATE_OFFHOOK:
        if(!incomingNumber.equals("")){
          handleCall(incomingCall);
        }
      break;
      case TelephonyManager.CALL_STATE_RINGING:
        Log.d("DEBUG", "RINGING");
      break;
    }
  }
  public void handleCall(String incomingCall){
    Uri contactUri = Uri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL, incomingNumber);
    contactsCursor = context.getContentResolver().query(contactUri, projection, null , null, People.NAME + " ASC");
    if(contactsCursor.moveToFirst()){
      int phoneNameIndex = contactsCursor.getColumnIndex(People.NAME);
      String phoneNameStr = contactsCursor.getString(phoneNameIndex);
      Log.d("DEBUG",phoneNameStr + " is calling");
    }else{
      Log.d("DEBUG","Not a contact");
    }
  }
}



Quick Explanation
Looking on the handleCall function, there is nothing really new here, for the BroadcastReceiver explanation go to this page and for the displaying contact names go to this page. Sorry i'm too lazy to explain here coz i already explained it on the previous post.

Anyway i have to temporarily stop my android adventure and do some stuff for work which is webbased stuff so the next article would be web based article. Thanks

Update History
   Jan 17, 2012 - Visual Update

Wednesday, January 28, 2009

Force Localize an Application on Android

Localization has always been a problem in tech at large and products from big companies like Google, Apple and Microsoft are not immune to it and so does Android (I know they came from Google). But one thing that was cool about Android is it was built for developers to localized their apps by default but the problem is that the API or documentation is lacking. If your in a journey to further localize your application, i suggest you to read this page on the official google groups for developers.

As the title stated, you can force your application to be localize on an application basis and not system basis. In this article we would use simplied chinese and english. To do this you have to edit something on your oncreate function on your default activity.

Update for Android 2.0
Add android:configChanges="locale" to your activity nodes on the manifest file
<activity android:name=".Main" android:configChanges="locale" android:label="@string/app_name" />

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;

public class Main extends Activity {
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String languageToLoad  = "cn";
    Locale locale = new Locale(languageToLoad); 
    Locale.setDefault(locale);
    Configuration config = new Configuration();
    config.locale = locale;
    getBaseContext().getResources().updateConfiguration(config, 
    getBaseContext().getResources().getDisplayMetrics());
    this.setContentView(R.layout.main);
  }
}


Quick Explanation
String languageToLoad = "cn";
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);

-- Here we create an new Locale in ch (Simplified Chinese) and set our default locale to a specific locale (See this for more information)

Configuration config = new Configuration();
config.locale = locale;

-- This would create a new Configuration which we would use later and then we change the locale of this configuration with our chinese locale.

getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());

-- This is the core part, here we only update the configuration of our basecontext's resources. I might not be right here but according to the description of Context, Interface to global information about an application environment. Getting the baseContext should be application level.

Source Code
Main.java
main layout
strings.xml in values folder
strings.xml in values-cn folder

Update History
   Jan 17, 2012 - Visual Update

Thursday, January 22, 2009

Get Phone State When Someone is calling using BroadcastReceiver Example

In this article we shall try to listen to the phone state when contacts are calling us.

First of all we need to set our Manifest file to listen to the Phone State, to do that we need to edit our it.
<application>
  .....
  <receiver android:name=".ServiceReceiver">
    <intent-filter>
      <action android:name="android.intent.action.PHONE_STATE" />
    </intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.READ_PHONE_STATE">
</uses-permission>



Here you can see that we created a receiver xml node inside our application and have the java class ServiceReceiver to listen to it. What it would listen to is the PHONE_STATE and thus we need the permission of READ_PHONE_STATE. Then our ServiceReceiver Class would look like this.



public class ServiceReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {
    MyPhoneStateListener phoneListener=new MyPhoneStateListener();
    TelephonyManager telephony = (TelephonyManager) 
    context.getSystemService(Context.TELEPHONY_SERVICE);
    telephony.listen(phoneListener,PhoneStateListener.LISTEN_CALL_STATE);
  }
}


For the full class including the imports, please download the files below. In here we have another class called MyPhoneStateListener, which would be shown at the bottom. What this class would do is execute the phoneListener when the telephony.listen has received a LISTEN_CALL_STATE.


public class MyPhoneStateListener extends PhoneStateListener {
  public void onCallStateChanged(int state,String incomingNumber){
  switch(state){
    case TelephonyManager.CALL_STATE_IDLE:
      Log.d("DEBUG", "IDLE");
    break;
    case TelephonyManager.CALL_STATE_OFFHOOK:
      Log.d("DEBUG", "OFFHOOK");
    break;
    case TelephonyManager.CALL_STATE_RINGING:
      Log.d("DEBUG", "RINGING");
    break;
    }
  } 
}


What we have is a function called onCallStateChanged which would be fired when the LISTEN_CALL_STATE dispatches it. The states are either, ringing(CALL_STATE_RINGING), answers (CALL_STATE_OFFHOOK), or hang up/end call (CALL_STATE_IDLE). To see the logs in eclipse. Go to Window -> Show View -> Other -> Android -> LogCat

Hope it helps.


Sources
AndroidManifest.xml
ServiceReceiver.java
MyPhoneStateListener.java


References
BroadcastReceiver

Update History
   Jan 17, 2012 - Visual Update

Thursday, January 15, 2009

Calling a Contact in Android

There will be a time where you might want to use the Caller on Android. Here is how you would do it, this article also introduces how to get an individual contact from your contact list. This is based on our previous article Clicking Items in ListActivity and Display Contact Names in Android.

protected void onListItemClick(ListView l, View v, int position, long id) {
  // GET THE ITEM THAT HAD BEEN TAPPED
  Uri uri = ContentUris.withAppendedId(People.CONTENT_URI, id);
  Cursor c = managedQuery(uri, new String[] {
    People.NUMBER
  }, null, null, null);
  c.moveToFirst();

  // CALL THE NUMBER FROM THE PREVIOUS SCREEN\
  int phoneNumberIndex = c.getColumnIndex(People.NUMBER);
  Uri parsedPhoneNumber = Uri.parse("tel:"+c.getString(phoneNumberIndex)); 
  Intent i = new Intent(Intent.ACTION_CALL,parsedPhoneNumber);
  startActivity(i);

  super.onListItemClick(l, v, position, id);
}


Quick Explanation
// GET THE ITEM THAT HAD BEEN TAPPED
Uri uri = ContentUris.withAppendedId(People.CONTENT_URI, id);
Cursor c = managedQuery(uri, new String[] {
People.NUMBER
}, null, null, null);
c.moveToFirst();
- Here we query our contacts with People.CONTENT_URI but on one specific contact. Then after we got the results we move the cursor to the first record.

- int phoneNumberIndex = c.getColumnIndex(People.NUMBER);
Uri parsedPhoneNumber = Uri.parse("tel:"+c.getString(phoneNumberIndex));

The first on is used to get the index of NUMBER in our fields, we do this coz c.getString arguement is the column id. Then to create a number that our caller accepts we need to pass it a Uri that starts with "tel:"

Intent i = new Intent(Intent.ACTION_CALL,parsedPhoneNumber);
startActivity(i);

Here we create a new Intent that would use the default caller and we pass the Uri of our phone number, then we start the calling with startActivity(i).


Update History
   Jan 17, 2012 - Visual Update

Wednesday, January 14, 2009

Clicking Items in ListActivity

From our Display Contact Names in Android and Displaying AlertDialog in Android, lets further expand that so that we would make use if the items in our ListActivity when user click the an item list, this article would be a brief one. For the following code just add it to your class, you can view the full source code at the bottom if you don't know where to put them.
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
  alertDialog = new AlertDialog.Builder(this).create();
  alertDialog.setTitle("Item Selected");
  alertDialog.setMessage("You just clicked an 
  item position #" + String.valueOf(position));
  alertDialog.setButton("OK",new DialogInterface.OnClickListener(){
    public void onClick(DialogInterface dialog, int which) {
    return;
  } }); 
  alertDialog.show();

  super.onListItemClick(l, v, position, id);
}



Quick Explanation
Here all we need to do it implement a function, onListItemClick, you can do this in eclipse by Right Click->Source->Override/Implement Method->onListItemClick.
There would be 4 arguments ListView l, View v, int position, long id, view this to see that they mean.

References
Display Contact Names in Android
Displaying AlertDialog in Android
android.app.ListActivity

Source
Main.java of Clicking Items in ListActivity


Update History
   Jan 17, 2012 - Visual Update