I am writing a timer application that counts backward from a time and
notifies when the timer reaches zero.  It is intended to allow the
user to start a timer that continues to tick and will notify them when
complete even after the activity is backgrounded.  Also, it will show
the correct in-progress countdown after the activity is re-
foregrounded.

TimerActivity.onCreate() inflates the TimerView (allowing the user to
set the time and hit the start button) and starts the TimerService.
When the start button is pressed the TimerView broadcasts a START
intent containing the number of seconds.  The TimerService contains a
BroadcastReceiver listening for the START intent.  When the
TimerService receives START it begins broadcasting a TICK intent
(containing the number of seconds remaining) every second until zero
is reached.

The TimerService looks like this.  The BroadastReceiver is inside of
the TimerService because it must set the TimerService's members.

public class TimerService extends Service
{
        private int _seconds = 0;
        private Handler _timerHandler;

        @Override
        public void onCreate()
        {
                _timerHandler = new Handler( );
        }

        ...

        public class StartListener extends BroadcastReceiver
        {
                @Override
                public void onReceive(Context context, Intent intent)
                {
                        _seconds = intent.getIntExtra( "seconds", 0 );
                        _timerHandler.postAtTime( runTimer, 
SystemClock.uptimeMillis() +
1000 );
                }

                private Runnable runTimer = new Runnable()
                {
                        public void run()
                        {
                                // Decrement the counter ======
                                if( _seconds > 0 )
                                        _seconds--;

                                // Broadcast the tick =========
                                Intent intent = new Intent(TICK_ACTION);
                                intent.putExtra( "seconds", _seconds );
                                sendBroadcast( intent );

                                // Schedule another tick? ======
                                if( _seconds > 0 )
                                        scheduleTick( this );
                        }
                };
        }
}


I would like the TimerView to be able to receive the TICK broadcasts
from the TimerService and update itself accordingly.  So, something
like this...


public class TimerView extends FrameLayout
{
        public TimerView(Context context, AttributeSet attrs, int defStyle)
        {
                super( context, attrs, defStyle );
                LayoutInflater.from( context ).inflate( R.layout.timerview, 
this,
true );
                ...
                mStartButton = (ToggleButton)findViewById( R.id.Start );
                mStartButton.setOnClickListener( new OnClickListener()
                        public void onClick(View view)
                        {
                                requestFocus();

                                Intent intent = new Intent(START_ACTION);
                                intent.putExtra( "seconds", getTimeInSeconds() 
);

                                Context context = this.getContext();
                                context.sendBroadcast( intent );
                        }
                } );
        }

        public class TickListener extends BroadcastReceiver
        {
                @Override
                public void onReceive(Context context, Intent intent)
                {
                        int seconds = intent.getIntExtra( "seconds", 0 );
                        setTimeInSeconds( seconds ); // Sets the view to the 
number of
seconds remaining
                }
        }
}


The <application> tag in the manifest contians this to tie it all
together

<manifest xmlns:android="http://schemas.android.com/apk/res/android";
      package="com.poof.timer"
      android:versionCode="1"
      android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label="@string/
app_name">

        <activity android:name=".TimerActivity" android:label="@string/
app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category
android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name="TimerActivity$TickListener">
          <intent-filter>
            <action android:name="com.poof.timer.action.TICK"/>
          </intent-filter>
        </receiver>

        <service android:name=".TimerService" android:enabled="true">
        </service>

        <receiver android:name="TimerService$StartListener">
          <intent-filter>
            <action android:name="com.poof.timer.action.START"/>
          </intent-filter>
        </receiver>

    </application>
</manifest>


Look good so far?  Well, it isnt.  The problem is that it wont build
because, according to Eclipse, "com.icd.timer.TimerService
$StartListener is enclosed, but not static".  Its the same with
TickListener.  I could simply make the StartReceiver and TickReceiver
classes static but that wont work because both of them need to set the
state of their containing objects.

How do I get around this?  Am I using the architecture for this
incorrectly?  (Its my first android app).  If not then how should I do
it?

Thanks much!
Clark

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to