Browse through more Android tutorials. If you'd like to see a tutorial on any particular topic, do leave a comment in the wishlist page. We frequently post new tutorials along with app releases. You may subscribe to our newsletter to get all updates in your inbox.
Now you can get the latest Java source bundled with each app update. Install the app from Google Play and go to Settings > Extras.

«  Create Flappy Bird in Android Create an instant messaging app  »

Create an elegantly designed Reminder/Alarm clock application

DownloadDownload

Keywords: ListActivity SimpleCursorAdapter SQLiteDatabase AlarmManager NotificationManager IntentService BroadcastReceiver ToggleButton ViewSwitcher DatePicker TimePicker RadioGroup

Contents

4 « Prev Page


Here is some relevant portion of the MainActivity.java file.








	public class MainActivity extends ListActivity {
		
		private TextView headingText;	
		private Typeface font;
		
		public final Calendar cal = Calendar.getInstance();
		public final Date dt = new Date();

		@Override
		public void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			requestWindowFeature(Window.FEATURE_NO_TITLE);
			setContentView(R.layout.main);
			
			headingText = (TextView) findViewById(R.id.heading_tv);
			font = Typeface.createFromAsset(getAssets(), "fonts/OpenSans.ttf");
			headingText.setTypeface(font);
			
			registerForContextMenu(getListView());			
		}
		
		private Cursor createCursor() {
			long time = cal.getTimeInMillis();
			Cursor c = RemindMe.db.rawQuery("SELECT * FROM Notification WHERE time BETWEEN "+
												time+" AND "+(time+86400000), null);
			startManagingCursor(c);
			return c;
		}
		
		@Override
		protected void onResume() {
			super.onResume();

			SimpleCursorAdapter adapter = new SimpleCursorAdapter(
					this, 
					R.layout.row, 
					createCursor(), 
					new String[]{Notification.COL_MSG, Notification.COL_DATETIME}, 
					new int[]{R.id.msg_tv, R.id.time_tv});
			
			adapter.setViewBinder(new ViewBinder() {
				@Override
				public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
					if (view.getId() == R.id.msg_tv) 
						return false;

					TextView tv = (TextView)view;
					switch(view.getId()) {
					case R.id.time_tv:
						dt.setTime(cursor.getLong(columnIndex));
						tv.setText(dt.getHours()+":"+dt.getMinutes());
						break;
					}
					return true;
				}
			});
			setListAdapter(adapter);
		}	
		
	}
					
Notice how we used custom fonts in our application. For this put the particular fonts file in assets directory of the project preferably under a sub folder, ex. fonts.
Another thing to note is the use of custom layout file for list rows and the ability to bind view data selectively. The layout file row.xml simply contains a RelativeLayout with few TextViews.
We specified an onClick function for the buttons in main.xml layout file. Here is the implementation.
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.imageButton1:
			startActivity(new Intent(this, SettingsActivity.class));
			break;		
		case R.id.imageButton2:
			startActivity(new Intent(this, AddAlarmActivity.class));
			break;
		case R.id.imageButton3:
			cal.add(Calendar.DATE, -1);
			((SimpleCursorAdapter)getListAdapter()).changeCursor(createCursor());
			break;
		case R.id.imageButton4:
			cal.add(Calendar.DATE, 1);
			((SimpleCursorAdapter)getListAdapter()).changeCursor(createCursor());
			break;
		}
	}
					
We have overridden onSaveInstanceState() and onRestoreInstanceState() methods of the Activity to save the current date range so that it's not lost when the Activity is recreated upon orientation change.
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putLong("cal", cal.getTimeInMillis());
	}	

	@Override
	protected void onRestoreInstanceState(Bundle state) {
		super.onRestoreInstanceState(state);
		cal.setTimeInMillis(state.getLong("cal"));
	}
					

11. The Options Menu

The options menu pops out on pressing the menu button of the device and gives an option to delete all notifications listed on the screen.
We just need to override few methods of the Activity to implement options menu.
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.options_menu, menu);
        return true;
	}
	
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
        if (getListAdapter().isEmpty()) {
        	menu.findItem(R.id.menu_delete_all).setEnabled(false);
        } else {
        	menu.findItem(R.id.menu_delete_all).setEnabled(true);
        }
		return true;
	}	

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_delete_all:		
			Intent cancelAll = new Intent(this, AlarmService.class);
			cancelAll.putExtra("startTime", cal.getTimeInMillis());
			cancelAll.putExtra("endTime", cal.getTimeInMillis()+86400000);
			cancelAll.setAction(AlarmService.CANCEL);
			startService(cancelAll);
			
			SimpleCursorAdapter adapter = (SimpleCursorAdapter) getListAdapter();
	    	adapter.getCursor().requery();
	    	adapter.notifyDataSetChanged();			
			return true;
		}		
		return super.onOptionsItemSelected(item);
	}
					
Only onCreateOptionsMenu() and onOptionsItemSelected() methods are required but we have overridden onPrepareOptionsMenu() as well for disabling delete option when list is empty.
We need to create a xml file under res/menu directory for declaring the options. Here is the content of options_menu.xml file.
	<?xml version="1.0" encoding="utf-8"?>
	<menu xmlns:android="http://schemas.android.com/apk/res/android" >
		<item android:id="@+id/menu_delete_all" 
			android:title="@string/delete_all" 
			android:icon="@android:drawable/ic_menu_delete" />
	</menu>
						

12. The Context Menu

Next we'll implement the context menu for ListView which allows user to take action on a specific item, for ex. edit, delete.
Override the two methods onCreateContextMenu() and onContextItemSelected().
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
		if (v.getId() == android.R.id.list) {
			getMenuInflater().inflate(R.menu.context_menu, menu);
			menu.setHeaderTitle("Choose an Option");
			menu.setHeaderIcon(R.drawable.ic_dialog_menu_generic);
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) 
													item.getMenuInfo();
		
		switch (item.getItemId()) {
		case R.id.menu_edit:
			showDialog(R.id.menu_edit);
			break;
			
		case R.id.menu_delete:
			Intent cancel = new Intent(this, AlarmService.class);
			cancel.putExtra("notificationId", String.valueOf(info.id));
			cancel.setAction(AlarmService.CANCEL);
			startService(cancel);
			
			SimpleCursorAdapter adapter = (SimpleCursorAdapter) getListAdapter();
	    	adapter.getCursor().requery();
	    	adapter.notifyDataSetChanged();			
			break;
		}
		
		return true;
	}
					

Note there is no method corresponding to onPrepareOptionsMenu() for context menu since onCreateContextMenu() is called every time unlike onCreateOptionsMenu() in case of options menu.

We need to create context_menu.xml file under res/menu directory.
	<?xml version="1.0" encoding="utf-8"?>
	<menu xmlns:android="http://schemas.android.com/apk/res/android" >
		<item android:id="@+id/menu_edit" android:title="@string/edit" />
		<item android:id="@+id/menu_delete" android:title="@string/delete" />
	</menu>
						
It is necessary to register a view for context menu using registerForContextMenu() method. Note that we have already done this for ListView in the onCreate() method.
The context menu pops out when a list item is long pressed but we can open it on click as well. ListActivity makes it simple by just overriding a method.
	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		openContextMenu(v);
	}
					
Share the love:  

Next Page » 4

App Gen
App Name:
Project Name:
Package:
Screens:
Splash
Login
Help
Main
List  Grid  Pager
Detail
Settings
Options:
Action Bar
Navigation Drawer
Dummy Data
Generate
Free Apps