package edu.gmu.cs.fireresponse.presentation;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.NotificationManager;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import edu.gmu.cs.fireresponse.R;
import edu.gmu.cs.fireresponse.domain.model.ISemanticEvent;
import edu.gmu.cs.fireresponse.domain.service.DomainService;
import edu.gmu.cs.fireresponse.presentation.map.MapViewActivity;
public class SemanticEventActivity extends Activity {
static final private int MENU_UPDATE = Menu.FIRST;
static final private int MENU_PREFERENCES = Menu.FIRST+1;
static final private int MENU_EARTHQUAKE_MAP = Menu.FIRST+2;
static final private int MENU_ESCAPE_ROUTE_MAP = Menu.FIRST+3;
// static final private int MENU_WINDWAVE_MAP = Menu.FIRST+4;
static final private int QUAKE_DIALOG = 1;
private static final int SHOW_PREFERENCES = 1;
NotificationManager notificationManager;
EarthquakeReceiver receiver;
ListView earthquakeListView;
ArrayAdapter<ISemanticEvent> aa;
ArrayList<ISemanticEvent> earthquakes = new ArrayList<ISemanticEvent>();
ISemanticEvent selectedQuake;
int minimumMagnitude = 0;
boolean autoUpdate = false;
int updateFreq = 0;
private ProgressDialog progressDialog;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
earthquakeListView = (ListView)this.findViewById(R.id.earthquakeListView);
earthquakeListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView _av, View _v, int _index, long arg3) {
selectedQuake = earthquakes.get(_index);
showDialog(QUAKE_DIALOG);
}
});
int layoutID = android.R.layout.simple_list_item_1;
aa = new ArrayAdapter<ISemanticEvent>(this, layoutID , earthquakes);
earthquakeListView.setAdapter(aa);
// loadSemanticEventFromDomainService();
updateFromPreferences();
refreshEarthquakes();
String svcName = Context.NOTIFICATION_SERVICE;
notificationManager = (NotificationManager)getSystemService(svcName);
}
private void addSemanticEventToArray(ISemanticEvent _event) {
if (_event.getMagnitude() > -1) {
// Add the new quake to our list of earthquakes.
earthquakes.add(_event);
// Notify the array adapter of a change.
aa.notifyDataSetChanged();
}
}
private void loadSemanticEventFromDomainService() {
Log.i("SemanticEventActivity.loadSemanticEventFromDomainService", " load Semantic Event invoked");
// Clear the existing earthquake array
earthquakes.clear();
// Bind to the service
doBindService();
// Return all the events
if (domainService != null) {
for(ISemanticEvent semanticEvent: domainService.getSemanticEvents()){
addSemanticEventToArray(semanticEvent);
}
}
if (this.progressDialog != null && this.progressDialog.isShowing()) {
this.progressDialog.dismiss();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, MENU_UPDATE, Menu.NONE, R.string.menu_update).setIcon(android.R.drawable.ic_menu_directions);
menu.add(0, MENU_PREFERENCES, Menu.NONE, R.string.menu_preferences).setIcon(android.R.drawable.ic_menu_preferences);
menu.add(0, MENU_EARTHQUAKE_MAP, Menu.NONE, R.string.menu_earthquake_map).setIntent(new Intent(this, MapViewActivity.class)).setIcon(android.R.drawable.ic_menu_mapmode);
menu.add(0, MENU_ESCAPE_ROUTE_MAP, Menu.NONE, R.string.menu_escape_route_map).setIntent(new Intent(this, EscapeRouteActivity.class)).setIcon(android.R.drawable.ic_menu_mapmode);
// menu.add(0, MENU_WINDWAVE_MAP, Menu.NONE, R.string.menu_windwave_map).setIntent(new Intent(this, MapViewActivity.class));
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case (MENU_UPDATE): {
refreshEarthquakes();
return true;
}
case (MENU_PREFERENCES): {
Intent i = new Intent(this, Preferences.class);
startActivityForResult(i, SHOW_PREFERENCES);
return true;
}
}
return false;
}
@Override
public Dialog onCreateDialog(int id) {
switch(id) {
case (QUAKE_DIALOG) :
LayoutInflater li = LayoutInflater.from(this);
View quakeDetailsView = li.inflate(R.layout.quake_details, null);
AlertDialog.Builder quakeDialog = new AlertDialog.Builder(this);
quakeDialog.setTitle("Fire Event Time");
quakeDialog.setView(quakeDetailsView);
return quakeDialog.create();
}
return null;
}
@Override
public void onPrepareDialog(int id, Dialog dialog) {
switch(id) {
case (QUAKE_DIALOG) :
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
String dateString = sdf.format(selectedQuake.getDate());
String quakeText = "Event: " + selectedQuake.getProvider() + "\n" +
"Confidence: " + selectedQuake.getConfidence() + "\n" +
"Relevance: " + selectedQuake.getRelevance() + "\n" +
"Detail: " + selectedQuake.getDetails() + "\n" +
"Link: " + selectedQuake.getLink();
AlertDialog quakeDialog = (AlertDialog)dialog;
quakeDialog.setTitle(dateString);
TextView tv = (TextView)quakeDialog.findViewById(R.id.quakeDetailsTextView);
tv.setText(quakeText);
break;
}
}
private void refreshEarthquakes() {
this.progressDialog = ProgressDialog.show(this, "Processing . . .", "Getting Semantic Event Data", true, true);
startService(new Intent(this, DomainService.class));
}
private void updateFromPreferences() {
Context context = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
minimumMagnitude = Integer.parseInt(prefs.getString(Preferences.PREF_MIN_MAG, "0"));
updateFreq = Integer.parseInt(prefs.getString(Preferences.PREF_UPDATE_FREQ, "0"));
autoUpdate = prefs.getBoolean(Preferences.PREF_AUTO_UPDATE, false);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SHOW_PREFERENCES)
if (resultCode == Activity.RESULT_OK) {
updateFromPreferences();
refreshEarthquakes();
// loadSemanticEventFromDomainService();
}
}
public class EarthquakeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
loadSemanticEventFromDomainService();
notificationManager.cancel(DomainService.NOTIFICATION_ID);
}
}
@Override
public void onResume() {
notificationManager.cancel(DomainService.NOTIFICATION_ID);
IntentFilter filter;
filter = new IntentFilter(DomainService.NEW_EARTHQUAKE_FOUND);
receiver = new EarthquakeReceiver();
registerReceiver(receiver, filter);
// loadSemanticEventFromDomainService();
super.onResume();
if (this.progressDialog != null && this.progressDialog.isShowing()) {
this.progressDialog.dismiss();
}
}
@Override
public void onPause() {
unregisterReceiver(receiver);
super.onPause();
if (this.progressDialog != null && this.progressDialog.isShowing()) {
this.progressDialog.dismiss();
}
}
private boolean domainServiceIsBound;
private DomainService domainService;
// Handles the connection between the service and activity
private ServiceConnection domainServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. Because we have bound to a explicit
// service that we know is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
domainService = ((DomainService.DomainServiceBinder)service).getService();
Log.i("ServiceConnection", "DomainService Connected onServiceConnected" + ": " + domainService);
// Tell the user about this for our demo.
//Toast.makeText(Binding.this, R.string.local_service_connected, Toast.LENGTH_SHORT).show();
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
// Because it is running in our same process, we should never
// see this happen.
//domainService = null;
//Toast.makeText(Binding.this, R.string.local_service_disconnected, Toast.LENGTH_SHORT).show();
}
};
void doBindService() {
// Establish a connection with the service. We use an explicit
// class name because we want a specific service implementation that
// we know will be running in our own process (and thus won't be
// supporting component replacement by other applications).
// Bind to the service
Intent bindIntent = new Intent(SemanticEventActivity.this, DomainService.class);
domainServiceIsBound = bindService(bindIntent, domainServiceConnection, Context.BIND_AUTO_CREATE);
}
void doUnbindService() {
if (domainServiceIsBound) {
// Detach our existing connection.
unbindService(domainServiceConnection);
domainServiceIsBound = false;
}
}
}
|