Showing posts with label android. Show all posts
Showing posts with label android. Show all posts

Saturday, December 15, 2012

Scala And Android Were Made For Each Other, Part 2

This is the second in a 2 part post.  To read the first post, Click Here.

Now that we've gone over the Service in our application, lets review the Activity.  Just in case you haven't read part 1, here's a 10 second recap:

We're building a countdown timer for the specific case of tracking a Pomodoro, a 25 minute block of time.  For more info, visit the Pomodoro Technique site, or maybe, order Pomodoro Technique Illustrated...

We've reviewed the Service and seen how the Scala language allows us to reduce a lot of boilerplate code.  Now lets look at the Activity:

1:  class ScalaDoro extends FragmentActivity with Actionable with MessageReceiver {  
2:   /** Messenger for communicating with service. */  
3:   var mService: Messenger = null  
4:   /** Flag indicating whether we have called bind on the service. */  
5:   var mIsBound: Boolean = false  
6:   var running = false  
7:   override def onCreate(savedInstanceState: Bundle) {  
8:    super.onCreate(savedInstanceState)  
9:    setContentView(R.layout.activity_main)  
10:    spawn {  
11:     startService(new Intent(ScalaDoro.this, classOf[BackgroundTimer]))  
12:    }  
13:    if (savedInstanceState != null) {  
14:     running = savedInstanceState.getBoolean("running", false)  
15:     val timerString = savedInstanceState.getString("timerText")  
16:     getSupportFragmentManager().findFragmentById(R.id.timer).asInstanceOf[CountdownTimerFragment].updateTime(if (timerString != null) timerString else "")  
17:    }  
18:    val button = findViewById(R.id.foo_button).asInstanceOf[Button]  
19:    //awesome lack of boilerplate code...  
20:    if (!running) {  
21:     button.setOnClickListener(toOnClickListener(startClickListener))  
22:     button.setText(R.string.start)  
23:    } else {  
24:     button.setOnClickListener(toOnClickListener(stopClickLister))  
25:     button.setText(R.string.stop)  
26:    }  
27:    val donate = findViewById(R.id.donate).asInstanceOf[TextView]  
28:    if(donate != null) {  
29:     donate.setText(Html.fromHtml("<a href='https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2RYS72VS6BJAA'>Is this useful to you? Donate via PayPal.</a>"));  
30:     donate.setMovementMethod(LinkMovementMethod.getInstance());  
31:    }  
32:   }  
33:   override def onSaveInstanceState(bundle: Bundle) = {  
34:    bundle.putBoolean("running", running)  
35:    bundle.putString("timerText", getSupportFragmentManager().findFragmentById(R.id.timer).asInstanceOf[CountdownTimerFragment].getTime.toString())  
36:   }  
37:   def onMessage(m: Message) = {  
38:    Log.i("BAA", "Message in Activity")  
39:    m.what match {  
40:     case BackgroundTimer.TICK =>  
41:      val textFragment = getSupportFragmentManager().findFragmentById(R.id.timer).asInstanceOf[CountdownTimerFragment]  
42:      if (textFragment != null) {  
43:       runOnUiThread {  
44:        textFragment.updateTime(m.obj.asInstanceOf[String])  
45:       }  
46:      }  
47:     case BackgroundTimer.STOPPED =>  
48:      val button = findViewById(R.id.foo_button).asInstanceOf[Button]  
49:      button.setOnClickListener(toOnClickListener(startClickListener))  
50:      button.setText(R.string.start)  
51:    }  
52:   }  
53:   def stopClickLister(v: View): Unit = {  
54:    val button = findViewById(R.id.foo_button).asInstanceOf[Button]  
55:    try {  
56:     running = false  
57:     // Give it some value as an example.  
58:     Log.i("BAA", "Sent message")  
59:     button.setOnClickListener(toOnClickListener(startClickListener))  
60:     val msg = Message.obtain(null, BackgroundTimer.STOP)  
61:     msg.replyTo = mMessenger  
62:     mService.send(msg);  
63:    } catch {  
64:     case ex: Exception => Log.i("BAA", ex.getMessage())  
65:    }  
66:    button.setText(R.string.start)  
67:   }  
68:   def startClickListener(v: View): Unit = {  
69:    val button = findViewById(R.id.foo_button).asInstanceOf[Button]  
70:    try {  
71:     // Give it some value as an example.  
72:     button.setOnClickListener(toOnClickListener(stopClickLister))  
73:     running = true  
74:     val msg = Message.obtain(null,  
75:      BackgroundTimer.START)  
76:     msg.replyTo = mMessenger  
77:     mService.send(msg);  
78:     Log.i("BAA", "Sent message")  
79:    } catch {  
80:     case ex: Exception => Log.i("BAA", ex.getMessage())  
81:    }  
82:    button.setText(R.string.stop)  
83:   }  
84:   //binding code..  
85:   val mConnection = new ServiceConnection() {  
86:    override def onServiceConnected(className: ComponentName, service: IBinder) = {  
87:     Log.i("BAA", "OnServiceConnected called")  
88:     // This is called when the connection with the service has been  
89:     // established, giving us the service object we can use to  
90:     // interact with the service. We are communicating with our  
91:     // service through an IDL interface, so get a client-side  
92:     // representation of that from the raw service object.  
93:     mService = new Messenger(service)  
94:     // We want to monitor the service for as long as we are  
95:     // connected to it.  
96:     try {  
97:      // Register to receive the notifications  
98:      val msg = Message.obtain(null,  
99:       BackgroundTimer.REGISTER)  
100:      msg.replyTo = mMessenger  
101:      mService.send(msg)  
102:      //Now get status  
103:      val status = Message.obtain(null, BackgroundTimer.STATUS)  
104:      status.replyTo = mMessenger  
105:      mService.send(status);  
106:      Log.i("BAA", "Sent message")  
107:     } catch {  
108:      case ex: Exception => Log.i("BAA", ex.getMessage())  
109:     }  
110:     mIsBound = true;  
111:    }  
112:    def onServiceDisconnected(className: ComponentName) = {  
113:     // This is called when the connection with the service has been  
114:     // unexpectedly disconnected -- that is, its process crashed.  
115:     mService = null;  
116:    }  
117:   }  
118:   override def onStart = {  
119:    super.onStart()  
120:    // Bind to the service  
121:    Log.i("BAA", "Binding")  
122:    bindService(new Intent(this, classOf[BackgroundTimer]), mConnection, Context.BIND_AUTO_CREATE);  
123:   }  
124:   @Override  
125:   override def onStop = {  
126:    super.onStop()  
127:    Log.i("BAA", "Unbinding")  
128:    // Unbind from the service  
129:    if (mIsBound) {  
130:     try {  
131:      // Give it some value as an example.  
132:      val msg = Message.obtain(null,  
133:       BackgroundTimer.UNREGISTER)  
134:      msg.replyTo = mMessenger  
135:      mService.send(msg)  
136:      Log.i("BAA", "Sent message")  
137:     } catch {  
138:      case ex: Exception => Log.i("BAA", ex.getMessage())  
139:     }  
140:     unbindService(mConnection)  
141:     mIsBound = false;  
142:    }  
143:   }  
144:  }  

The first thing to notice is that we are using 2 Traits.  Actionable and MessageReceiver.  You can see, even with this simple app, we're composing functionality from small pieces, and we're reusing code from the Service.  I've never NEEDED multiple inheritance, but in this case, it sure is nice.  We've already seen MessageReceiver, but lets take a look at Actionable:


1:  package com.example.scaladoro.activity  
2:  import android.view.View  
3:  trait Actionable {  
4:   implicit def toRunnable[F](f: => F): Runnable = new Runnable() { def run() = f }  
5:   implicit def toOnClickListener(f: View => Unit): View.OnClickListener = new View.OnClickListener() { def onClick(v: View) = f(v) }  
6:  }  

Actionable simply holds 2 implicit definitions.  These allow us to use functions in our Activity instead of having to constantly create new Abstract inner classes.  Now when I want to run something on the UI thread, I just use the syntax on line 43.  No 'new' keyword, no class definition, no methods to mark @Override.  Just the code that will be run.  All the cruft that obfuscates what we're trying to do is gone.

Notice I had to use additional syntax to set the click listeners (line 21).  I defined the click listener functions in the activity, and Scala's compiler didn't like them until I wrapped them in the implicit.  It doesn't add a ton of code and I find it to be a much cleaner implementation of the state/strategy pattern than creating abstract classes, so I'm willing to live with it.

Take another look at the code. Once again, there is is very little 'boilerplate' and nice cohesion.  Once you understand the Scala syntax, its also a lot easier to read and to reason about what is going on than the equivalent Java code.  At least, it is for me.

If you are interested in seeing the app run, go ahead and download it.  I've posted it to the Play store:

Want to try the app out?  Download Campari Pomodoro.


Saturday, December 8, 2012

Scala And Android Were Made For Each Other

I've been experimenting with Scala for a while now, and the more I use it, the more I like it.  Scala isn't exactly what I would call an approachable language, but if you are familiar with Java or C# and you slowly work your way into it, Scala is really a joy to work in.

I also like to write apps for Android.  Since Scala runs on the JVM, it runs on Android, too.  Recently I've started to think that Google made a mistake using Java for Android.  It probably helped Android gain apps and popularity since thousands of developers could install the Eclipse Android Plugin and start coding, but that's the thing - Coding on Android is very different than coding, say, a Web app.  It's even quite different than coding a desktop app.  And it is because of the way that things should be written on Android that Java seems to be a poor fit.  All those thousands of programmers started writing apps - and did it wrong.

I know.  I made tons of mistakes.  As I read more about the platform and become more familiar with how things ran, it is clear that a lot of what I did often wasn't a best practice.  Some of what I did was just wrong.

This is where I get to the title of this post.  I recently experimented and wrote an application for Android using Scala.  I have to say, after writing the application this way, I don't ever want to go back. It is my sincere belief that Scala is a much better fit for writing applications on Android than Java.  To prove my point, I am going to go through the app I wrote and show you the Scala code. I am going to assume if you are reading this that you already have some familiarity with Android development so I will refrain from showing the Java alternative.

I'm also going to point out that I am in no way a functional programming expert.  As I said, I use Scala as a better Java.  My code continues to become 'more functional', but I'm sure this is not idiomatic Scala.  That's okay by be, though, because things are just easier.  To me, that's the best measure of how good the code is.

Background

We recently had half our staff move to an office in San Francisco.  Our company has always moved at a rapid pace, but with the additional overhead of working with a team 2 hours difference and across the US, I was feeling like I was getting distracted. I wanted to find a management technique that was simple and that would help me stay on track.  I picked the Pomodoro technique - it was simple. It suited me. It was invented by a programmer, and there were several apps in the Play store for me to use. Of course, I wanted to write my own anyway.

For the purpose of this app, all you need to know is that a Pomodoro is a 25 minute block of time where you concentrate on doing work. Since this is a pretty straight forward app to write, though, I thought I would implement it in Scala to see how it went.

If you want to know more about the Pomodoro Technique, you can visit the official Pomodoro Technique page or Buy the book on Amazon (convenient link on the left).




Application Definition

Here are the things I want the application to do:
  • Allow me to start a Pomodoro (a 25 minute block of time)
  • Play the ticker sound while in a Pomodoro (for some reason, hearing this helps me stay on track)
  • Play a bell when the Pomodoro finishes
  • Allow me to cancel a Pomodoro if I have to
  • Keep the Pomodoro timer running, even if I close the application 
Here are the constituent parts of my application:
  • Activity - Main activity, only Activity.  It has the text that shows you the time left and a button that changes states.  The button will either start or stop the timer.
  • Service - A background service that will run the timer task - counting down 
If you've done any Android programming in the past, you realize that even these simple requirements will result in a slew of callbacks, threads, anonymous inner classes, binders, messengers...need I go on?  Okay, that was a bit of an exaggeration, but not as exaggerated as it seems.

Let's think about this for a moment. In order to prevent ANR warnings we need to keep things off the main thread, which, means any communication with our service should be run in separate threads.  Allowing the service to run separately from the Activity (and allow it to potentially be started and called from any activity, even someone else's) will require it to be started and bound so we'll need a Binder and then we'll need to implement its callbacks. Then communication should happen with Messages so we'll need a Messenger and we'll need to implement its callbacks. Oh, and if we want to update the UI so users know whats going on, we need to then run updates from background threads on the UI thread, which, requires a Runnable.

When you add all this up, it makes for lots of  boilerplate code.  Thankfully, the language features of Scala make this less verbose, easier to write,  more understandable, and ultimately easier to maintain.  It also makes it much easier to write code that will follow Android best practices.

Now that we know the what and the how, let's talk code.

The Code


We know we want a bound service that we can send messages to.  When you read the Android docs on it, you'll see that there is a abstract inner class that implements Handler and is passed to a Messenger that is returned in the Services onBind method.

Wow, that was a lot to say.  It is also a lot of boilerplate code.  I wanted to move this to a common class so it was out of my way.  In Java we might make an Abstract base class.  But wait, the Activity in our application also needs a Handler and a Messenger, and if we Make an AbstractService, we could not use that code in an Activity. If we make an AbstractActivity, we cannot use it for our Service.   Here is the first place where Scala is quite handy.  I was able to make a Trait.  Traits are very powerful and I'm using the one below as a 'better interface', which, might be under-utilizing this great feature.  It serves its purpose well, however.

1:  trait MessageReceiver {  
2:   implicit def toIncomingHandler(f: Message => Unit): Handler = new Handler() { override def handleMessage(message: Message) = f(message) }  
3:    
4:   val mMessenger = new Messenger({ m: Message => 
5:    onMessage(m)  
6:   })  
7:    
8:   def onMessage(m: Message)  
9:  }  

Notice that I also used an implicit to reduce the need to declare an abstract inner class to handle the message.  I probably didn't save any code, but I like the way this looks far better than the Java alternative.

Now that we have the MessageReceiver defined, let's define our Service.  Before I show you the code, here are some things I want you to notice about the class:

  • We override onMessage and implement it.  This is the only code in this class that is related to receiving a message.  All the boilerplate has been moved to the Trait which can be used by both Activity and Service classes.
  • The start method has an internal method called timer that is recursive. This also happens to be tail recursive, and Scala is smart enough to unwind this, so it won't grow my stack.  
  • We run the timer in a background thread.  Notice that all we have to do is surround it with a spawn{} block.  (I omitted the imports, but you need to import scala.concurrent.ops._ to do this)


1:  case class BackgroundTimer extends Service with MessageReceiver {  
2:     
3:   var millis = 0L;  
4:   /** Keeps track of all current registered clients. */  
5:   var mClients = List[Messenger]()  
6:   var currentTime = "0:00"  
7:    
8:   val mediaPlayer = new SoundPool(2, AudioManager.STREAM_MUSIC, 0)  
9:    
10:   var tickId: Int = -1  
11:   var alarmId: Int = -1  
12:   var tickStreamId = -1  
13:     
14:   override def onMessage(m:Message) = {  
15:    m.what match {  
16:     case BackgroundTimer.REGISTER =>
18:       mClients ::= m.replyTo  
19:      }  
20:     case BackgroundTimer.UNREGISTER =>
21:      if (m.replyTo != null) {  
22:       mClients = mClients.remove(messenger =>
23:        if (messenger == m.replyTo) {  
24:         true  
25:        } else {  
26:         false  
27:        })  
28:      }  
29:     case BackgroundTimer.START >  
30:      start()  
31:     case BackgroundTimer.STOP =>
32:      //don't play the alarm bell  
33:      stop(true)  
34:    }  
35:   }  
36:    
37:   override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = {  
38:    Log.i("BAA", "Received start id " + startId + ": " + intent)  
39:    try {  
40:     tickId = mediaPlayer.load(this, R.raw.singletick, 1)  
41:     alarmId = mediaPlayer.load(this, R.raw.alarm, 1)  
42:    } catch {  
43:     case e: Exception => Log.d("BAA", e.getMessage())  
44:    }  
45:    Service.START_STICKY; // run until explicitly stopped.  
46:   }  
47:    
48:   /**  
49:    * Must override this to allow the service to bind to the Activity so we can start/stop timers  
50:    */  
51:   override def onBind(intent: Intent): IBinder = {  
52:    Log.i("BAA", "OnBind called")  
53:    return mMessenger.getBinder()  
54:   }  
55:    
56:   def start() = {  
57:    if (millis == 0) {  
58:     spawn {  
59:        
60:      var alarmStreamId = -1  
61:      try {  
62:       tickStreamId = mediaPlayer.play(tickId, 2.0f, 2.0f, 1, -1, 1.0f)  
63:      } catch {  
64:       case e: Exception => Log.d("BAA", e.getMessage())  
65:      }  
66:        
67:      def timer(millisLeft: Long): Unit = {  
68:       if (millis > 0) {  
69:        millis = millisLeft  
70:       }  
71:       val seconds = (millisLeft / 1000) % 60;  
72:       val minutes = ((millisLeft / (1000 * 60)) % 60);  
73:       currentTime = minutes + ":" + (if (seconds > 9) seconds else "0" + seconds)  
74:    
75:       if (millis > 0) {  
76:        mClients.foreach { messenger =>
77:         val response = Message.obtain(null, BackgroundTimer.TICK, 0, 0, currentTime)  
78:         messenger.send(response)  
79:        }  
80:        Thread.sleep(995);  
81:        timer(millisLeft - 995)  
82:       } else {  
83:        stop(false)  
84:          
85:       }  
86:      }  
87:      //now start it off...  
88:      millis = 1000 * 60 * 25  
89:      timer(millis)  
90:     }  
91:    }  
92:   }  
93:    
94:   def stop(forced:Boolean) = {  
95:    millis = 0  
96:    currentTime = "0:00"  
97:    mediaPlayer.stop(tickStreamId)  
98:    if(!forced)  
99:     mediaPlayer.play(alarmId, 0.2f, 0.2f, 1, 0, 1.0f)  
100:    mClients.foreach { messenger =>  
101:     val response = Message.obtain(null, BackgroundTimer.STOPPED, 0, 0, currentTime)  
102:     messenger.send(response)  
103:    }  
104:   }  
105:  }  
106:    
107:  /**  
108:   * Define an object to hold some statics  
109:   */  
110:  object BackgroundTimer {  
111:   val REGISTER = 1  
112:   val START = 2  
113:   val STOP = 3  
114:   val UNREGISTER = 4  
115:   val STARTED = 5  
116:   val STOPPED = 6  
117:   val TICK = 7  
118:  }   
119:    

I don't know about you, but this class looks very clean to me.  Almost all the code is directly related to what this class is intended to do with no messy boilerplate code for messaging or threading.  In fact, threading is now too easy -  just add a spawn block and done.  The 'business logic' is also very compact.  Since timer can be declared inside start, all the logic for actually running the timer is in one spot - no need to jump to a different section of code to see what's going on.

Want to try the app out?  Download Campari Pomodoro.

Next up, the Activity

Saturday, January 14, 2012

StudyBlue Flashcards nominated for Best App Ever Awards

I've been working for StudybBlue for about 9 months now.  If you don't know what StudyBlue is, it's a fantastic place for students to create online flashcards, study those flashcards, create quizzes from them, and track their progress.  In other words, its a product that makes students more efficient and effective.  


StudyBlue is more than a Web site, however.  It also produces native flashcard applications for iPhone and Android to allow students to study their cards on the go.  The goal for our company is to create a total user experience and we invest a lot of time, effort and energy into our application designs.  Apparently, that hard work is starting to payoff.  


We were recently notified that we were nominated for the the Best App Ever Awards.  While its not the biggest award or the best known, the interesting thing about it is that it is a user-driven award.  It means that one of our users nominated our app and other users will be voting on it.  In my mind this is one of the highest compliments StudyBlue could be paid.  After all, it doesn't really matter what anyone thinks but your users, and it seems that we're keeping at least some of ours pretty happy.  


If you are a student and use StudyBlue, please vote for our app.  There would be nothing more satisfying than knowing that our users think we're the Best App Ever.
Vote for STUDYBLUE Flashcards for Best High School Student App

Sunday, May 23, 2010

Android Application Part 6 - SQLLite Database

This post is part 6 of a series.  Click here to go to part 5.


In my previous post, I walked through the scaffolding for the ListService, which will query a REST Web service and sync data locally.  Of course, the code was just the implementation to allow the service to run in a new Thread.  Today I am going to start implementing the storage part of the application.  Android has a a SQLLite. Database.  The OS makes it available through a service.  It even comes packaged with a SQLLiteOpenHelper class.  The implementation for this one is rather easy.  Here I've modified the sample presented on the Android Developer Site.  First I'll show you the code, then I'll talk through what its doing.   

package com.arciszewski.family.shopping.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;

public class FamilyListOpenHelper extends SQLiteOpenHelper {

private static final int DATABASE_VERSION = 1;
private static final String FAMILY_LIST_TABLE_NAME = "familyList.db";
private static final String LIST_TABLE_CREATE = "CREATE TABLE LIST (ID INTEGER PRIMARY KEY AUTOINCREMENT, SERVER_ID INTEGER, NAME TEXT, DESCRIPTION TEXT);";
private static final String ITEM_TABLE_CREATE = "CREATE TABLE ITEM (ID INTEGER PRIMARY KEY AUTOINCREMENT, SERVER_ID INTEGER, NAME TEXT, LIST_ID INTEGER NOT NULL, NEEDED BOOLEAN, UPDATED_DATE TEXT, UPDATED_BY TEXT);";

public FamilyListOpenHelper(Context context) {
this(context, null);
}

public FamilyListOpenHelper(Context context, CursorFactory factory) {
super(context, FAMILY_LIST_TABLE_NAME, factory, DATABASE_VERSION);;
}

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(LIST_TABLE_CREATE);
db.execSQL(ITEM_TABLE_CREATE);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub

}
}


So what is this code doing? First, I've defined which version of the DB this is:


DATABASE_VERSION = 1;


I like this feature of Android. They have built-in support for upgrading. You'll notice, I have not implemented the onUpgrade method, that is because I have no need for it yet. But when I come out with version 2.0, I will have the opportunity to perform upgrade operations.


Next, I define the table names and create SQL for the List and Item tables.


private static final String LIST_TABLE_CREATE = "CREATE TABLE LIST (ID INTEGER PRIMARY KEY AUTOINCREMENT, SERVER_ID INTEGER, NAME TEXT, DESCRIPTION TEXT);"; private static final String ITEM_TABLE_CREATE = "CREATE TABLE ITEM (ID INTEGER PRIMARY KEY AUTOINCREMENT, SERVER_ID INTEGER, NAME TEXT, LIST_ID INTEGER NOT NULL, NEEDED BOOLEAN, UPDATED_DATE TEXT, UPDATED_BY TEXT);";


Finally, I've implemented a constructor that will always open the Family List Database and return it to the caller. That's it. And that is pretty easy my friends. Of course, I'm not making this available as a service to other applications, which is slightly more complex.


Next, I'll implement some querying and saving.

Sunday, May 16, 2010

Android Application Part 5 - Creating the Service

This post is part 5 of a series.  Click here to go to part 4.


In my previous posts, I outlined my general design for this application.  In this post, I will review the creation of the Service class for the Android device. This class will have one purpose: Communicate with the server to sync lists.

One of the things I hadn't decided on was how to construct the Web service.  Do I want to use a SOAP style service or a REST style service? The server side for either of these is pretty well defined for me - I've written both SOAP and REST services.  The unknown is how to build these on the client side.  I did a little Web research, and here are a few of the places I've found that have some good information on these topics:

  • It appears that Google isn't interested in including SOAP in the standard Android packages at this time, but there is a 3rd party library that provides this support: kSOAP
  • Google DOES support JSON with Android packaged,  org.json.*.  I also found a handy RestClient.
Given that JSON is less verbose, and the processing will take fewer resources, I think its a better choice for a constrained device like Android.  I also like that I have a RestClient class that I can use, but I can also see what's going on easily inside it.  So, the transport protocol for my application will be JSON.

Let's talk about the code.  Below is my first attempt at creating the ListService.  It's not fully fleshed out.  This first version is written to put in the Multithreading and get a basic framework for the application.  I will next work on pulling out the data from the JSON objects and store them locally (Using the local HSQL db Android provides).  It's also clear I need to understand Intents and bindings much better before I will be able to complete the app.  Let's start with a discussion on the ListService.  This extends the Android Service class and over rides the onCreate, onStartCommand, and stopService methods.  I also added extra logging to see what's going on.



01 package com.arciszewski.family.shopping.service;
02 
03 import android.app.Service;
04 import android.content.Intent;
05 import android.os.IBinder;
06 import android.util.Log;
07 
08 public class ListService extends Service {
09   private RunnableListService runnableListService;
10   @Override
11   public IBinder onBind(Intent arg0) {
12     
13     return null;
14   }
15 
16   @Override
17   public void onCreate() {
18     super.onCreate();
19     Log.i("BAA""created");
20   }
21 
22   @Override
23   public int onStartCommand(Intent intent, int flags, int startId) {
24     Log.i("BAA""starting");
25     if(runnableListService == null) {
26       runnableListService = new RunnableListService();
27       new Thread(runnableListService).start();
28     }
29     return START_STICKY;
30   }
31 
32   @Override
33   public boolean stopService(Intent name) {
34     Log.i("BAA", name.toString());
35     boolean superResult =  super.stopService(name);
36     if(runnableListService != null) {
37       runnableListService.setContinueRunning(false);
38       runnableListService = null;
39     }
40     return superResult;
41   }
42 }


Java2html

The ListService does nothing but create a RunnableListService and start it in a new Thread.  It also kills the flag that keep the polling loop open when stopService is called.  Here is the RunnableService:




01 /**
02  * Class that will poll the server for changes and sleep.  
03  @author barciszewski
04  *
05  */
06 public class RunnableListService implements Runnable {
07   private static final String SERVER_URI = "http://192.168.1.103/familyList";
08   private static final String APP_ID = "FL1"
09   private static boolean running = false;
10   private boolean continueRunning = true;
11   @Override
12   public void run() {
13     getListFromServer();
14   }
15   
16   private void getListFromServer() {
17     //don't want to try and connect twice
18     if(!getRunning()) {
19       setRunning(true);
20       RestClient.connect(SERVER_URI);
21       //save list data to local data store...
22       
23       setRunning(false);
24     }
25     while(continueRunning) {
26       try {
27         Thread.sleep(1000*60*5);
28       catch(InterruptedException e) {
29         //do nothing
30       }
31       getListFromServer();
32     }
33   }
34   
35   
36   public static synchronized void setRunning(boolean runnnig) {
37     RunnableListService.running = running; 
38   };
39   
40   public static synchronized boolean getRunning() {
41     return RunnableListService.running;
42   }
43   
44   public void setContinueRunning(boolean continueRunning) {
45     this.continueRunning = continueRunning;
46   }
47   
48 }
Java2html


Most of the heavy lifting is not implemented yet, but this provides the structure to poll the server.  I also modified the RestClient slightly to return the JSONObject.

Next - More implementation...

Sunday, May 9, 2010

Android Application Part 4 - The Activity and Service

This post is part 4 of a series.  Click Here to go to part 3.

After all of that, I am going to set aside any of the server programming and go straight to writing the Android portion of the system.  I know, I know, after all that work writing the UML for the core components, I'm just going ahead and writing an Android app anyway.  I have two good reasons for this.

Reason 1: I have never produced an Android app before, but I've written dozens of Web apps and Web services.  Therefore, the Android portion of the system is the least-known and most risky.  As a developer, I like to tackle these portions of a system first to reduce risk and get unknowns out of the way.  I believe this is a good practice, and leads to more successes in projects.

Reason 2: I WANT to program an Android app.  Especially now that I have my Droid  and my wife has her Incredible.

OK, so lets start on the Android app design.  My application will need to display a UI and run a background process to do synchronizations.  According to the Android Developers Web site, I will need two basic constructs, an Activity and a Service.  Let's explore the Activity first.  The Android developer site describes an Activity as:
An activity presents a visual user interface for one focused endeavor the user can undertake. For example, an activity might present a list of menu items users can choose from or it might display photographs along with their captions. A text messaging application might have one activity that shows a list of contacts to send messages to, a second activity to write the message to the chosen contact, and other activities to review old messages or change settings. Though they work together to form a cohesive user interface, each activity is independent of the others. Each one is implemented as a subclass of the Activity base class.
That seems pretty straight forward - An Activity is simply a UI component for a single task.  It sounds like my application will only need a couple of Activities.  One activity to show the grocery list, an activity to add a new item, and one to show the status of the sync.  A Service is defined as:


A service doesn't have a visual user interface, but rather runs in the background for an indefinite period of time. For example, a service might play background music as the user attends to other matters, or it might fetch data over the network or calculate something and provide the result to activities that need it. Each service extends the Service base class.
A prime example is a media player playing songs from a play list. The player application would probably have one or more activities that allow the user to choose songs and start playing them. However, the music playback itself would not be handled by an activity because users will expect the music to keep playing even after they leave the player and begin something different. To keep the music going, the media player activity could start a service to run in the background. The system would then keep the music playback service running even after the activity that started it leaves the screen.
It's possible to connect to (bind to) an ongoing service (and start the service if it's not already running). While connected, you can communicate with the service through an interface that the service exposes. For the music service, this interface might allow users to pause, rewind, stop, and restart the playback.

Like activities and the other components, services run in the main thread of the application process. So that they won't block other components or the user interface, they often spawn another thread for time-consuming tasks (like music playback). See Processes and Threads, later. 
From the description of a Service, it appears that my application will only have one service - the list sync.  This service should spawn a thread so it doesn't block other components or the UI.  It also appears that the service can be exposed to an Activity, so I should be able to force a sync through a UI action.

This all seems pretty simple.  Let's just do a quick UI sketch, though.  I've mocked up a header and one record to make sure I've got the screen space I'd like. 

This is a really rough mock up, but it demonstrates all I need for the list.  One form element, a check box, and three labels. 

It seems like the Android application design is going to be dictated by the platform.  An Activity and a Service are going to be my two main classes.  I think I'm going to tackle the Service first, as that is more complicated.

Next: Coding the Android Service




Wednesday, May 5, 2010

Android Application Part 2

This post is part 2 of a series.  Click here to go to part 1.

In my first post, I outlined the 3 major components of the system I am thinking about - Web site, Web service, and Android app.  At first I thought I would dive right into programming the Android application, but then I realized that I was about to make the same mistake my business users make.  I was about to develop something without first thinking through the use-cases I wanted to accommodate.   So, this post is going to deal with the use-cases I will be developing.

First let's talk about the Web site.  Here are the use cases I want available for my first revision:

  • Allow a user to set up a new account
  • Allow a user to set up a new 'Family' (or group)
  • Allow a user to send invitations to other users to sign up/join the group
  • Allow a user to add a list to the Family
  • Allow a user to add an item to a list
  • Allow a user to mark an item as purchased
  • Allow a user to mark an item as needed again
Of course, I can think of about a dozen more use cases, but I am going to limit this first build to just those 7. Now lets talk about the Android application.  Here is what I want it to do:

  • Periodically poll the server for lists
  • Synchronize the local list with the server and save it (rules for conflicts?)
  • Allow a user to view lists
  • Allow a user to mark an item as purchased
  • Allow a user to mark an item as needed again
  • Allow a user to force a sync (He may want to do this right before entering a store)
Given the functionality on the Android application, I believe the needs of the Web service become apparent
  • Provide a service to allow a user to sync the lists from his groups
Now that I look at that, I believe this is going to be a bit more work than I thought, but not too bad.  I can see that there are many more use cases for the Web application than I thought, and many fewer for the Web service.  

Next: Let's do some UML and Sequence diagrams.

Tuesday, May 4, 2010

Android Application Attempt 2

Now that my classes have finished, I am going to attempt an Android application again.  My first idea was a 'my friends' application.  It appears that Google has beat me to it.  Thanks, Latitude.

I have a second idea.  This application I call, 'Family Shopping List'.  The idea is to store a common list, say a grocery list, online, and sync it to all the family accounts tied to the list.  This way, my wife can add milk to the list, and I can pick it up on the way home.  The reason this can't be strictly an online application is simple - Cellular service is often non-existent in grocery stores.  What we can do is sync the lists while we do have service, and show the list we have when we are offline.  So, here is a basic description of the very high-level design of 'Family List'.

  • Server application - A Web site with the ability to set up a new account, view lists, send invites to users.  Accesses a backend database where all information is stored
  • Web Service - Published interface that allows clients to interact with the server.  
  • Client - Android application that communicates to the server.  This application will also have a local data store that mimics some of the tables on the server
That's it in a nutshell.  For my next post I will be going over the basic design of the application. 

Sunday, May 2, 2010

Android Development - So Easy Yet Not So Easy

I have recently started playing around with Android.  Given the success of the Droid, Droid Eris, and what looks like a phone from Google, the NexusOne, I figure the Android is going to be either the number one or number 2 development platform for mobile devices.  In either case, I want to be able to write apps for my Droid, which, I love.
So this week I have attempted to start development.  I have read through the online documentation, which, in typical Google fashion, is fairly complete and detailed. The Android Developer Guide includes step by step instructions for installation of the SDK, Eclipse Plugin, and samples to get you programming quickly.
Of course, nothing is perfect.  So here are a couple of issues with the tools.
  • It appears that sometimes changed resources don’t get updated when the emulator is re-launched.  Even though I’ve set the flag to Wipe User Data.
  • I can get one version of the Google Maps sample to run correctly but not another.  It seems that the Sample Tutorial on the Web site doesn’t work for 2.0 or 2.0.1 emulators on my machine, but the sample bundled with the toolkits do.  To be honest, it appears that the only difference is WHERE the MapView is instantiated, but I am still a noob at this, so I am probably mistaken
Is this going to be enough to cause me to give up?  Heck no.  Even though these two items are frustrating, the toolkit is still well put together and I expect to be building apps in no time.  My next posts will detail the building of an app.

Monday, January 4, 2010

Creating An Android App 1 : Introduction

OK, here it goes.  I'm going to qualify this as being my first attempt at Blogging consistently.  Certainly this is my first attempt at blogging about a project, so bear with me OK?

I want to use Android to play around with location based services.  Why?  Because its pretty new and I see lots of opportunities to leverage computers in peoples pockets, that's why.  So my next few posts will be detailing the building of a simple app I'm calling, MyFriends.

This is an app that will track my location and send it to a server.  It will also send the location of all my friends to the same server, and share the location data between devices.  Initially, all the app will do is display my location on a Google map along with the locations of my friends, if they are in the maps viewable area.

This app is pretty simple, and I've seen some similar apps on the app store, but I'm doing this as an exercise to get familiar with Android.  And who knows, maybe, just maybe, this will turn into a usable app.

Things my app will need to do:

  • Get my location data
  • Send the data to a server via HTTP(S)
  • Get my friends data from the server via HTTP(S)
  • Create a Google Map view and Overlays to show the locations of me and my friends.
So, I've defined an app and the general scope of the first revision.

Next - Installation of the development tools.

Sunday, January 3, 2010

Android Development – So Easy, Yet Not So Easy

I have recently started playing around with Android. Given the success of the Droid, Droid Eris, and what looks like a phone from Google, the NexusOne, I figure the Android is going to be either the number one or number 2 development platform for mobile devices. In either case, I want to be able to write apps for my Droid, which, I love.

So this week I have attempted to start development. I have read through the online documentation, which, in typical Google fashion, is fairly complete and detailed. The Android Developer Guide includes step by step instructions for installation of the SDK, Eclipse Plugin, and samples to get you programming quickly.

Of course, nothing is perfect. So here are a couple of issues with the tools.


  • It appears that sometimes changed resources don’t get updated when the emulator is re-launched. Even though I’ve set the flag to Wipe User Data.
  • I can get one version of the Google Maps sample to run correctly but not another. It seems that the Sample Tutorial on the Web site doesn’t work for 2.0 or 2.0.1 emulators on my machine, but the sample bundled with the toolkits do. To be honest, it appears that the only difference is WHERE the MapView is instantiated, but I am still a noob at this, so I am probably mistaken

Is this going to be enough to cause me to give up? Heck no. Even though these two items are frustrating, the toolkit is still well put together and I expect to be building apps in no time. My next posts will detail the building of an app.