Thursday, May 24, 2012

Android Emulator Properties

The downloadable platform includes the following emulator skins:


  • QVGA (240x320, low density, small screen)
  • WQVGA400 (240x400, low density, normal screen)
  • WQVGA432 (240x432, low density, normal screen)
  • HVGA (320x480, medium density, normal screen)
  • WVGA800 (480x800, high density, normal screen)
  • WVGA854 (480x854 high density, normal screen)
  • WXGA720 (1280x720, extra-high density, normal screen)
  • WSVGA (1024x600, medium density, large screen)
  • WXGA (1280x800, medium density, xlarge screen)
To test your application on an emulator that represents the latest Android device, you can create an AVD with the new WXGA720 skin (it's an xhdpi, normal screen device). Note that the emulator currently doesn't support the new on-screen navigation bar for devices without hardware navigation buttons, so when using this skin, you must use keyboard keys Home for the Home button, ESC for the Back button, and F2 or Page-up for the Menu button.
However, due to performance issues in the emulator when running high-resolution screens such as the one for the WXGA720 skin, we recommend that you primarily use the traditional WVGA800 skin (hdpi, normal screen) to test your application.

Wednesday, May 9, 2012

Simple Calendar control android


Hi developers, here the example for simple calendar control in android.

CalendarActivity .java


public class CalendarActivity extends Activity
{
 private EditText Calctrl;
 static final int DATE_DIALOG_ID = 0;
 final Calendar c = Calendar.getInstance();
 private int mYear, mMonth, mDay;
 private String sdate;
 private String[] arrayMonth = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

  @Override
  public void onCreate(Bundle savedInstanceState)
  {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.main);
   Calctrl = (EditText) findViewById(R.id.datepicker);
   mYear = c.get(Calendar.YEAR);
   mMonth = c.get(Calendar.MONTH);
   mDay = c.get(Calendar.DAY_OF_MONTH);
   sdate = currentDate(mYear, mMonth, mDay);
  Calctrl.setText(sdate);  

  Calctrl.setOnTouchListener(new OnTouchListener()
  {
   @Override
   public boolean onTouch(View v, MotionEvent event)
   {
    showDialog(DATE_DIALOG_ID);
    return true;
   }
  });
 }

 @Override
 protected Dialog onCreateDialog(int id)
 {
  switch (id)
  {
  case DATE_DIALOG_ID:
   return new DatePickerDialog(this, mDateSetListener, mYear, mMonth,mDay);
  }
  return null;
 }

 @Override
 protected void onPrepareDialog(int id, Dialog dialog)
 {
  switch (id)
  {
  case DATE_DIALOG_ID:
   ((DatePickerDialog) dialog).updateDate(mYear, mMonth, mDay);
   break;
  }
 } 

 private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener()
 {
  public void onDateSet(DatePicker view, int year, int monthOfYear,int dayOfMonth)
  {
   mYear = year;
   mMonth = monthOfYear;
   mDay = dayOfMonth;
   String sdate = currentDate(mYear, mMonth, mDay);
   Calctrl.setText(sdate);
  }
 };

 private static String LPad(String schar, String spad, int len)
 {
  String sret = schar;
  for (int i = sret.length(); i < len; i++)
  {
   sret = spad + sret;
  }
  return new String(sret);
 }

 private String currentDate(int year, int month, int day)
 {
  String sdate = arrayMonth[month] + " " + LPad(day + "", "0", 2) + ", "+ year;
  return sdate;
 }
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/app_background"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/datepicker"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:editable="false"
        android:inputType="none" />

</LinearLayout>


Android Layout Background Issue


First of all, make sure that your original image looks good so you're not just getting the problem from there.
Then, in your onCreate() method, do:
code1:
getWindow().setFormat(PixelFormat.RGBA_8888);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DITHER);
And to load your image explicitly as a 32-bit image (RGBA-8888 configuration) add the following where you load your views:

code2:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap gradient = BitmapFactory.decodeResource(getResources(), R.drawable.gradient, options);

findViewById(R.id.main).setBackgroundDrawable(new BitmapDrawable(gradient));

Comparison between different approaches: (these are all screenshots from the resulting application)
My source images (64 colors to the left, 24 bit to the right):
image1 and image2:
64-color24 bit
1: Raw 64-color image (image1) set as background from layout XML:
Raw image
2: The same image (image1), using code1:
Dithered image
3: The same image (image1) using both code1 and code2:
explicit 32bit
4: image2, loaded with code1 and code2 (in this case the dithering is not really important as both the source and destination use 8 bits per color):
higher original quality
Notice how the resulting artifacts in image 3 already exists in the original image.

Monday, April 30, 2012

Android email example


SendEmailActivity .java

public class SendEmailActivity extends Activity 
{
Button buttonSend;
EditText textTo;
EditText textSubject;
EditText textMessage;

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

buttonSend = (Button) findViewById(R.id.buttonSend);
textTo = (EditText) findViewById(R.id.editTextTo);
textSubject = (EditText) findViewById(R.id.editTextSubject);
textMessage = (EditText) findViewById(R.id.editTextMessage);

buttonSend.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

 String to = textTo.getText().toString();
 String subject = textSubject.getText().toString();
 String message = textMessage.getText().toString();

 Intent email = new Intent(Intent.ACTION_SEND);
 email.putExtra(Intent.EXTRA_EMAIL, new String[]{ to});
 //email.putExtra(Intent.EXTRA_CC, new String[]{ to});
 //email.putExtra(Intent.EXTRA_BCC, new String[]{to});
 email.putExtra(Intent.EXTRA_SUBJECT, subject);
 email.putExtra(Intent.EXTRA_TEXT, message);

 //need this to prompts email client only
 email.setType("message/rfc822");

 startActivity(Intent.createChooser(email, "Choose an Email client :"));

}
});
}
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textViewPhoneNo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="To : "
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/editTextTo"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:inputType="textEmailAddress" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/textViewSubject"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Subject : "
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/editTextSubject"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
         >
    </EditText>

    <TextView
        android:id="@+id/textViewMessage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Message : "
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/editTextMessage"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="top"
        android:inputType="textMultiLine"
        android:lines="5" />

    <Button
        android:id="@+id/buttonSend"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Send" />

</LinearLayout>

Android silent mode example

SlientMode.java

public class SilentMode extends Activity 
{
  public void onCreate(Bundle savedInstanceState) 
 {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView txt = (TextView) findViewById(R.id.txt1);

Button silent = (Button) findViewById(R.id.silent);
Button normal = (Button) findViewById(R.id.normal);
Button vibra = (Button) findViewById(R.id.vibration);

final AudioManager mode = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
silent.setOnClickListener(new View.OnClickListener() 
   {
public void onClick(View v) 
    {
txt.setText("The Mobile in Silent Mode");
mode.setRingerMode(AudioManager.RINGER_MODE_SILENT);
Toast.makeText(getBaseContext(), "Silent Mode Activated",
Toast.LENGTH_SHORT).show();
}
});

normal.setOnClickListener(new View.OnClickListener() 
{
public void onClick(View v) 
  {
txt.setText("The Mobile in Normal Mode");
mode.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
Toast.makeText(getBaseContext(), "Normal Mode Activated",
Toast.LENGTH_SHORT).show();
}
});

vibra.setOnClickListener(new View.OnClickListener() 
  {
public void onClick(View v) 
   {
txt.setText("The Mobile in Normal Mode");
mode.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
Toast.makeText(getBaseContext(), "Vibration Mode Activated",
Toast.LENGTH_SHORT).show();
}
});
}
}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

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

    <Button
        android:id="@+id/silent"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Switch to Silent Mode" />

    <Button
        android:id="@+id/normal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Switch to Normal Mode" />
   
    <Button
        android:id="@+id/vibration"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Switch to Vibration" />

</LinearLayout>

Sunday, April 29, 2012

SQLite DB Example


There are 4 ways of storing data on the android platform:

  • 1.    Preferences
  • 2.    SQLite Database
  • 3.    Files
  • 4.    Network

A word about each of them here and then I will move on to an example that shows how to work with SQLite DB that comes along with the android platform.

Preferences – 
Basically used for storing user preferences for a single application or across applications for a mobile. This is typically name-value pairs accessible to the context.

Databases – 
Android supports creating of databases based on SQLite db. Each database is private to the applications that creates it 

Files –
Files can be directly stored on the mobile or on to an extended storage medium. By default other applications cannot access it.

Network – 
Data can be stored and retrieved from the network too depending on the availability.

If an application wants to store and retrieve data for its own use, without having to share the data across applications, it can access the SQLite DB directly. There is no need of a content provider. We have seen in anearlier post how to use content providers

In this example, we will do the following:
1.    Create a database (typically a one time activity)
2.    Create a table (typically a one time activity)
3.    Insert values into the table
4.    Retrieve the values from the table
5.    Display the retrieved values as a List view
6.    Delete all the records from the table before closing the connection to the database

Step 1: Create a database:

   sampleDB =  this.openOrCreateDatabase(SAMPLE_DB_NAMEMODE_PRIVATEnull);

This opens a database defined in the constant SAMPLE_DB_NAME, if it already exists. Else it creates a database and opens it. The second parameter is operating mode : MODE_PRIVATE meaning it is accessible to only this context. The other modes are and MODE_WORLD_WRITABLE. MODE_WORLD_READABLE

Step 2: Create a Table:

sampleDB.execSQL("CREATE TABLE IF NOT EXISTS " +
                        SAMPLE_TABLE_NAME +
                        " (LastName VARCHAR, FirstName VARCHAR," +
                        " Country VARCHAR, Age INT(3));");

Step 3: Insert values into the table:

sampleDB.execSQL("INSERT INTO " +
                        SAMPLE_TABLE_NAME +
                        " Values ('Makam','Sai Geetha','India',25);");

Step 4: Retrieve values 

Cursor c = sampleDB.rawQuery("SELECT FirstName, Age FROM " +
                        SAMPLE_TABLE_NAME +
                        " where Age > 10 LIMIT 5"null);
            
      if (c != null ) {
            if  (c.moveToFirst()) {
                  do {
String firstName = c.getString(c.getColumnIndex("FirstName"));
                  int age = c.getInt(c.getColumnIndex("Age"));
                  results.add("" + firstName + ",Age: " + age);
                  }while (c.moveToNext());
            } 
       }

Step 5: Display the values as a list 
            
       this.setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,results));

The statement displays it as a list as the class extends a ListActivity.

Step 6: Delete the values from the table in the finally part of the try block

finally {
            if (sampleDB != null
                  sampleDB.execSQL("DELETE FROM " + SAMPLE_TABLE_NAME);
                  sampleDB.close();
        }

It is as simple as this to work with the SQLite DB even in android. No different from a desktop application. However, there are various overloaded methods of query() provided by the SQLIteDatabase class which can be more optimally used instead of execSQL.