First steps in Android programming

Last week I finished my first Android application. All through the development stage I had to Google a lot for examples which some were really hard to find (even though you can find reference for everything in the SDK, for me, it's easier to understand from a code sample).

My mobile company allows you to send 10 free daily SMS through their website, and after that each text message is still half priced, so I decided to take a challenge and create a UI that allows me to send my messages from the phone through the website automatically.

The core of my software was pure java, so even though it wasn't straight forward to accomplish, I kinda know the material.

The main issues were after – when I got to the android implementation and UI

Here are the issues I needed, and will supply examples for in this post:
(Of course – for you that are more experienced than me with Android development, please forgive if I'm not doing everything 'by the book', it's simply what I could find. So if you have any suggestions or improvement please send them to me or post a comment J )

  • How to find out if there is an active network on the device
  • How to create options menu
  • How to create and clear notification in the notification area
  • How to declare your program as "SMS Sender" ('Complete action using…')
  • Taking care of orientation (Landscape and Portrait mode for UI)

Here is the code I ended up using. Hope you find it helpful

This sample method returns a Boolean that states if there is an active network

private boolean anyNetworkActive() {
         TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
         WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
         WifiInfo wi = wm.getConnectionInfo();
         return !((wi == null || WifiInfo.getDetailedStateOf(wi.getSupplicantState()) == DetailedState.IDLE) &&
tm.getDataState() != TelephonyManager.DATA_CONNECTED);
}

These events populate the menu with text-only options, and do the proper action when pressed

@Override
public boolean onCreateOptionsMenu(Menu menu) {
      menu.add(getString(R.string.menuconfig));
      menu.add(getString(R.string.menuclear));
      menu.add(getString(R.string.menucontact));
      return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
      if (item.getTitle().equals(getString(R.string.menuconfig)))
      // Show config screen
      startActivity(new Intent(this, Prefs.class));
      if (item.getTitle().equals(getString(R.string.menuclear))) {
      // Clear all fields on screen
           messageBody.setText("");
           smsTarget.setText("");
      }
      if (item.getTitle().equals(getString(R.string.menucontact))) {
            getcontact = true; // for sync issues
           // Delete the contactnum variable
           prefs.edit().putString("contactnum", "").commit();
           // Show contact selection screen
           startActivity(new Intent(this, ContactList.class));
       }
       return (true);
}

The first method will create a notification for your user (an icon must be present in the drawable folder)
The second one will clear the notification

public void notifyString(String sTickerText, String sContentTitle, String sContentText) {
          String ns = Context.NOTIFICATION_SERVICE;
          NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
          int icon = R.drawable.notification_icon;
          CharSequence tickerText = sTickerText;
          long when = System.currentTimeMillis();

          Notification notification = new Notification(icon, tickerText, when);
          Context context = getApplicationContext();
          CharSequence contentTitle = sContentTitle;
          CharSequence contentText = sContentText;
          Intent notificationIntent = new Intent(this, PeleSms.class);
          PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

          notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
          final int HELLO_ID = 1;

          mNotificationManager.notify(HELLO_ID, notification);
}

public void clearNotification() {
          String ns = Context.NOTIFICATION_SERVICE;
          NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
          mNotificationManager.cancel(1);
}

These methods and AndroidManifest.xml changes will declare your program as an SMS Sender, and the user will be asked if he/she wants to use it instead of the built in messaging client when trying to send a text message (with the "Complete action using..." menu, screenshot above)

AndroidManifest.xml:

<intent-filter>
     <action android:name="android.intent.action.VIEW" />
     <action android:name="android.intent.action.SENDTO" />
     <category android:name="android.intent.category.DEFAULT" />
     <category android:name="android.intent.category.BROWSABLE" />
     <data android:scheme="sms" />
     <data android:scheme="smsto" />
</intent-filter>

Catching the intent in the beginning of activity:

@Override
public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         String param = getIntent().getDataString();
          ....

Orientation:

The grand finale. This is as simple as can be… no code needed. All you need to do, is create two folders under the root of your project: layout-port and layout-land
Then, move your UI XML to the layout-port folder, and create a copy of it with the same name in layout-land folder. That's about it. Of course, you need to adjust the layout for each. Android will know when to use which

Well, I hope I got you through rough times if you found this post useful. I know I wish I bumped into one like it J

Last thing: This is a ListActivity I created using some examples I found... It displays a list of your contacts and by clicking one, saves his phone number in a Shared Preference. Note that you must grant permission for reading contact in your AndroidManifest.xml

public class ContactList extends ListActivity{
private ListAdapter mAdapter;
SharedPreferences prefs;

/** Called when the activity is first created. */
@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        prefs = PreferenceManager.getDefaultSharedPreferences(this);
        Cursor contactsCursor = this.managedQuery(People.CONTENT_URI,
                     null, null, null, "People.NAME ASC");
        startManagingCursor(contactsCursor);

        String[] columnsToMap = new String[] {People.NAME};
        int[] mapTo = new int[] {android.R.id.text1};

        mAdapter = new SimpleCursorAdapter(this,
                     android.R.layout.simple_list_item_1,
                     contactsCursor, columnsToMap, mapTo);
        this.setListAdapter(mAdapter);
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
Cursor C = (Cursor) mAdapter.getItem(position);
String phoneNumber;
int phoneColumn = C.getColumnIndex(People.NUMBER);
phoneNumber = C.getString(phoneColumn);

//SharedPreferences.Editor editor =
prefs.edit().putString("contactnum", phoneNumber).commit();

finish();
}
}

That's about it... If you need more info on anything I've posted here just contact me or leave a comment

UPDATE: I have added some code to our project repository SVN.
It does not contain the actual backend SMS sending, since this is pure java thing, and I don't want to piss off my cellular company (making them stop giving away 10 free per day maybe? ). The project name is AndroidFirstSteps
http://morethantechnical.googlecode.com/svn/trunk/

Share