package pl.llp.aircasting.activity; import android.os.AsyncTask; import android.view.*; import pl.llp.aircasting.Intents; import pl.llp.aircasting.R; import pl.llp.aircasting.activity.menu.MainMenu; import pl.llp.aircasting.event.ui.TapEvent; import pl.llp.aircasting.helper.LocationHelper; import pl.llp.aircasting.helper.SettingsHelper; import pl.llp.aircasting.model.Session; import pl.llp.aircasting.model.SessionManager; import pl.llp.aircasting.receiver.SyncBroadcastReceiver; import android.content.Context; import android.content.Intent; import android.location.LocationManager; import android.os.Bundle; import android.widget.Button; import android.widget.Toast; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import com.google.inject.Inject; import com.google.inject.internal.Nullable; import pl.llp.aircasting.storage.UnfinishedSessionChecker; import roboguice.inject.InjectView; import java.util.concurrent.TimeUnit; /** * A common superclass for activities that want to display left/right * navigation arrows */ public abstract class ButtonsActivity extends RoboMapActivityWithProgress implements View.OnClickListener { public static final String SHOW_BUTTONS = "showButtons"; @Inject Context context; @Inject EventBus eventBus; @Nullable @InjectView(R.id.heat_map_button) View heatMapButton; @Nullable @InjectView(R.id.graph_button) View graphButton; @InjectView(R.id.context_buttons) ViewGroup contextButtons; @Inject LocationManager locationManager; @Inject SessionManager sessionManager; @Inject LayoutInflater layoutInflater; @Inject LocationHelper locationHelper; @Inject SettingsHelper settingsHelper; @Inject MainMenu mainMenu; private boolean suppressTap = false; private boolean initialized = false; @Inject SyncBroadcastReceiver syncBroadcastReceiver; SyncBroadcastReceiver registeredReceiver; @Nullable @InjectView(R.id.zoom_in) Button zoomIn; @Nullable @InjectView(R.id.zoom_out) Button zoomOut; @Inject UnfinishedSessionChecker checker; @Inject ApplicationState state; private long lastChecked = 0; public static final long DELTA = TimeUnit.SECONDS.toMillis(15); @Override protected void onResume() { super.onResume(); initialize(); locationHelper.start(); updateButtons(); if (!sessionManager.isSessionSaved()) { Intents.startSensors(context); } registerReceiver(syncBroadcastReceiver, SyncBroadcastReceiver.INTENT_FILTER); registeredReceiver = syncBroadcastReceiver; eventBus.register(this); checkForUnfinishedSessions(); } @Override protected void onPause() { super.onPause(); if (!sessionManager.isSessionSaved()) { Intents.stopSensors(context); } locationHelper.stop(); if (registeredReceiver != null) { unregisterReceiver(syncBroadcastReceiver); registeredReceiver = null; } eventBus.unregister(this); } @Override protected boolean isRouteDisplayed() { // The maps server needs to know if we are displaying any routes return false; } private void initialize() { if (!initialized) { if (graphButton != null) graphButton.setOnClickListener(this); if (heatMapButton != null) heatMapButton.setOnClickListener(this); initialized = true; } } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); showButtons = savedInstanceState.getBoolean(SHOW_BUTTONS, true); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(SHOW_BUTTONS, showButtons); } protected boolean showButtons = true; /** * The next tap will not change the state of the toggleable * buttons. Use this if clicking something makes the toggleable * buttons toggle. */ public void suppressNextTap() { suppressTap = true; } @Override public void onClick(View view) { switch (view.getId()) { case R.id.back_to_dashboard: finish(); break; case R.id.toggle_aircasting: toggleAirCasting(); break; case R.id.edit: Intents.editSession(this, sessionManager.getSession()); break; case R.id.note: Intents.makeANote(this); break; case R.id.share: Intents.shareSession(this, sessionManager.getSession().getId()); break; } } @Override public boolean onCreateOptionsMenu(Menu menu) { return mainMenu.create(this, menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { return mainMenu.handleClick(this, item); } @Subscribe public void onEvent(TapEvent event) { if (suppressTap) { suppressTap = false; } } public void update() { updateButtons(); } protected void updateButtons() { clearButtons(); if (sessionManager.isSessionStarted()) { addButton(R.layout.context_button_stop); if(sessionManager.canSessionHaveNotes()) addButton(R.layout.context_button_note); } else if (sessionManager.isSessionSaved()) { addButton(R.layout.context_button_edit); addButton(R.layout.context_button_share); } else { addButton(R.layout.context_button_record); addButton(R.layout.context_button_placeholder); } addContextSpecificButtons(); } protected void addContextSpecificButtons() { } protected void clearButtons() { contextButtons.removeAllViews(); } protected void addButton(int id) { View view = layoutInflater.inflate(id, contextButtons, false); view.setOnClickListener(this); contextButtons.addView(view); } private synchronized void toggleAirCasting() { if (sessionManager.isSessionStarted()) { stopAirCasting(); } else { startAirCasting(); } updateButtons(); } private void stopAirCasting() { Session session = sessionManager.getSession(); if (session.isFixed()) stopFixedAirCasting(session); else stopMobileAirCasting(session); } private void stopMobileAirCasting(Session session) { locationHelper.stop(); Long sessionId = session.getId(); if (session.isEmpty()) { Toast.makeText(context, R.string.no_data, Toast.LENGTH_SHORT).show(); sessionManager.discardSession(sessionId); } else { sessionManager.stopSession(); Intent intent = new Intent(this, SaveSessionActivity.class); intent.putExtra(Intents.SESSION_ID, sessionId); startActivityForResult(intent, Intents.SAVE_DIALOG); } } private void stopFixedAirCasting(Session session) { locationHelper.stop(); Long sessionId = session.getId(); if (session.isEmpty()) { Toast.makeText(context, R.string.no_data, Toast.LENGTH_SHORT).show(); sessionManager.discardSession(sessionId); } else { sessionManager.stopSession(); sessionManager.finishSession(sessionId); } } private void startAirCasting() { if (settingsHelper.isFixedSessionStreamingEnabled()) startFixedAirCasting(); else startMobileAirCasting(); } private void startMobileAirCasting() { if (settingsHelper.areMapsDisabled()) { sessionManager.startMobileSession(true); } else { if (locationHelper.getLastLocation() == null) { RecordWithoutGPSAlert recordAlert = new RecordWithoutGPSAlert(context, sessionManager, this, true); recordAlert.display(); } else { sessionManager.startMobileSession(false); if (settingsHelper.hasNoCredentials()) { Toast.makeText(context, R.string.account_reminder, Toast.LENGTH_LONG).show(); } if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { if (locationHelper.hasNoGPSFix()) { Toast.makeText(context, R.string.no_gps_fix_warning, Toast.LENGTH_LONG).show(); } } else { Toast.makeText(context, R.string.gps_off_warning, Toast.LENGTH_LONG).show(); } } } } private void startFixedAirCasting() { if (settingsHelper.hasNoCredentials()) Toast.makeText(context, R.string.account_reminder, Toast.LENGTH_LONG).show(); else startActivity(new Intent(this, StartFixedSessionActivity.class)); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case Intents.SAVE_DIALOG: startActivity(new Intent(getApplicationContext(), StreamsActivity.class)); break; case Intents.EDIT_SESSION: if (resultCode == R.id.save_button) { Session session = Intents.editSessionResult(data); sessionManager.updateSession(session); } break; default: super.onActivityResult(requestCode, resultCode, data); } } private void checkForUnfinishedSessions() { if (shouldCheckForUnfinishedSessions()) { new AsyncTask<Void, Void, Void>(){ @Override protected Void doInBackground(Void... voids) { checker.check(ButtonsActivity.this); lastChecked = System.currentTimeMillis(); return null; } }.execute(); } } private boolean shouldCheckForUnfinishedSessions() { if(sessionManager.isRecording()) return false; if(state.saving().isSaving()) return false; long timeout = System.currentTimeMillis() - lastChecked; return timeout > DELTA; } }