package com.transitwidget; import android.app.Activity; import android.app.Dialog; import android.app.TimePickerDialog; import android.appwidget.AppWidgetManager; import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.Button; import android.widget.Spinner; import android.widget.TextView; import android.widget.TimePicker; import com.transitwidget.adapters.BaseItemAdapter; import com.transitwidget.feed.model.Agency; import com.transitwidget.prefs.*; import com.transitwidget.service.AlarmSchedulerService; import com.transitwidget.utils.AdapterUtils; import com.transitwidget.utils.TimeUtils; import java.util.ArrayList; import java.util.Calendar; import java.util.List; /** * The configuration screen for the ExampleAppWidgetProvider widget sample. */ public class WidgetConfigActivity extends Activity { static final String TAG = "MBTAWidgetConfig"; int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; private NoDefaultSpinner agencySpinner; private NoDefaultSpinner routeSpinner; private NoDefaultSpinner directionSpinner; private NoDefaultSpinner stopSpinner; private Button saveButton; private TextView startTimeView; private TextView endTimeView; private BaseItemAdapter<? extends NextBusValue> routeAdapter; private BaseItemAdapter<? extends NextBusValue> agencyAdapter; private BaseItemAdapter<? extends NextBusValue> directionAdapter; private BaseItemAdapter<? extends NextBusValue> endPointAdapter; private NextBusObserverConfig config; private int startHour; private int startMinute; private int endHour; private int endMinute; static final int TIME_START_DIALOG_ID = 0; static final int TIME_END_DIALOG_ID = 1; private static void updateDisplay(TextView display, int hour, int minute) { StringBuilder build = new StringBuilder(); String ampm = ""; if (hour < 12) { if (hour == 0) hour = 12; // 0 => 12am ampm = "am"; } else { if (hour > 12) hour -= 12; // 13-23 => 1-11pm ampm = "pm"; } build.append(hour).append(":"); if (minute < 10) build.append("0"); build.append(minute).append(ampm); display.setText(build.toString()); } private void updateStartDisplay() { updateDisplay(startTimeView, startHour, startMinute); } private void updateEndDisplay() { updateDisplay(endTimeView, endHour, endMinute); } @Override protected Dialog onCreateDialog(int id) { switch (id) { case TIME_START_DIALOG_ID: return new TimePickerDialog(this, mStartTimeSetListener, startHour, startMinute, false); case TIME_END_DIALOG_ID: return new TimePickerDialog(this, mEndTimeSetListener, endHour, endMinute, false); } return null; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(TAG, "Start OnCreate"); // Set the result to CANCELED. This will cause the widget host to cancel // out of the widget placement if they press the back button. setResult(RESULT_CANCELED); // Set the view layout resource to use. setContentView(R.layout.widget_config); startTimeView = (TextView) findViewById(R.id.startTimePickerValue); endTimeView = (TextView) findViewById(R.id.endTimePickerValue); Calendar cal = Calendar.getInstance(); startHour = cal.get(Calendar.HOUR_OF_DAY); startMinute = cal.get(Calendar.MINUTE); cal.add(Calendar.MINUTE, 60); endHour = cal.get(Calendar.HOUR_OF_DAY); endMinute = cal.get(Calendar.MINUTE); updateStartDisplay(); updateEndDisplay(); findViewById(R.id.startTimePicker).setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDialog(TIME_START_DIALOG_ID); } }); findViewById(R.id.endTimePicker).setOnClickListener(new View.OnClickListener() { public void onClick(View v) { showDialog(TIME_END_DIALOG_ID); } }); // Bind the action for the save button. saveButton = (Button) findViewById(R.id.saveBtn); saveButton.setEnabled(false); saveButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { final Context context = WidgetConfigActivity.this; // Until there are UI selectors, we'll start in 5 seconds and run for 10 minutes. Calendar start = Calendar.getInstance(); start.set(Calendar.HOUR_OF_DAY, startHour); start.set(Calendar.MINUTE, startMinute); start.set(Calendar.SECOND, 0); int startTime = TimeUtils.getTimeFromBeginingOfDay(start); Calendar end = Calendar.getInstance(); end.set(Calendar.HOUR_OF_DAY, endHour); end.set(Calendar.MINUTE, endMinute); end.set(Calendar.SECOND, 0); int endTime = TimeUtils.getTimeFromBeginingOfDay(end); config.setStartObserving(startTime); config.setStopObserving(endTime); // When the button is clicked, save the string in our prefs and return that they // clicked OK. savePreferences(context, mAppWidgetId); // Push widget update to surface with newly set prefix //AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); // Make sure we pass back the original appWidgetId Intent resultValue = new Intent(); resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); setResult(RESULT_OK, resultValue); Intent serviceIntent = new Intent(getApplicationContext(), AlarmSchedulerService.class); serviceIntent.putExtra(AlarmSchedulerService.EXTRA_WIDGET_ID, mAppWidgetId); serviceIntent.putExtra(AlarmSchedulerService.EXTRA_DAY_START_TIME, startTime); serviceIntent.putExtra(AlarmSchedulerService.EXTRA_DAY_END_TIME, endTime); startService(serviceIntent); finish(); } }); findViewById(R.id.cancelBtn).setOnClickListener(new View.OnClickListener() { public void onClick(View v) { finish(); } }); // Find the widget id from the intent. Intent intent = getIntent(); Bundle extras = intent.getExtras(); if (extras != null) { mAppWidgetId = extras.getInt( AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); } // If they gave us an intent without the widget id, just bail. if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { finish(); } agencySpinner = (NoDefaultSpinner) findViewById(R.id.agencySpinner); routeSpinner = (NoDefaultSpinner) findViewById(R.id.routeSpinner); directionSpinner = (NoDefaultSpinner) findViewById(R.id.directionSpinner); stopSpinner = (NoDefaultSpinner) findViewById(R.id.endPointSpinner); resetRouteSpinner(); resetDirectionSpinner(); resetStopSpinner(); agencySpinner.setEnabled(false); agencySpinner.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView<?> arg0, View arg1, int pos, long id) { Log.i(TAG, "Agency selected: " + id); resetRouteSpinner(); resetDirectionSpinner(); resetStopSpinner(); updateRoute(); // Save selected id Cursor cursor = getContentResolver().query(ContentUris.withAppendedId(Agency.CONTENT_URI, id), new String[] { Agency.TAG }, null, null, null); String tag = null; if (cursor.moveToFirst()) { tag = cursor.getString(0); } Log.i(TAG, "Saving selected agency with id " + id + " and tag " + tag); getSharedPreferences(MainActivity.PREFS, MODE_PRIVATE).edit() .putLong("agency", id) .putString("agencyTag", tag) .commit(); } public void onNothingSelected(AdapterView<?> arg0) {} }); routeSpinner.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView<?> arg0, View arg1, int pos, long id) { Log.i(TAG, "Route selected: " + id); resetDirectionSpinner(); resetStopSpinner(); updateDirection(); } public void onNothingSelected(AdapterView<?> arg0) {} }); directionSpinner.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { resetStopSpinner(); updateStop(); } public void onNothingSelected(AdapterView<?> arg0) {} }); stopSpinner.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView<?> arg0, View arg1,int arg2, long arg3) { saveButton.setEnabled(true); } public void onNothingSelected(AdapterView<?> arg0) { saveButton.setEnabled(false); } }); config = new NextBusObserverConfig(WidgetConfigActivity.this, mAppWidgetId); new UpdateAgencies().execute(config); Log.i(TAG, "End OnCreate"); } private BaseItemAdapter<NextBusValue> createAdapter(List<? extends NextBusValue> data, Spinner spinner) { ArrayList<NextBusValue> tmp = new ArrayList<NextBusValue>(); BaseItemAdapter<NextBusValue> adapter; tmp.add(new NextBusValue("Unspecified")); if(data != null) { tmp.addAll(data); } adapter = new BaseItemAdapter<NextBusValue>(WidgetConfigActivity.this, android.R.layout.simple_spinner_item, tmp); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); return adapter; } private void resetRouteSpinner() { routeSpinner.setEnabled(false); routeAdapter = createAdapter(null, routeSpinner); } private void resetStopSpinner() { stopSpinner.setEnabled(false); endPointAdapter = createAdapter(null, stopSpinner); saveButton.setEnabled(false); } private void resetDirectionSpinner() { directionSpinner.setEnabled(false); directionAdapter = createAdapter(null, directionSpinner); } // Write the prefix to the SharedPreferences object for this widget void savePreferences(Context context, int appWidgetId) { int pos; pos = stopSpinner.getSelectedItemPosition(); config.setStop((NextBusStop) endPointAdapter.getItem(pos)); config.save(); Log.i(TAG, config.getStops().toString()); } void updateRoute() { if(agencySpinner.getSelectedItemPosition() > 0) { int pos = agencySpinner.getSelectedItemPosition(); config.setAgency((NextBusAgency) agencyAdapter.getItem(pos)); new UpdateRoutes().execute(config); } } void updateDirection() { if(routeSpinner.getSelectedItemPosition() > 0) { int pos = routeSpinner.getSelectedItemPosition(); config.setRoute((NextBusRoute) routeAdapter.getItem(pos)); new UpdateDirection().execute(config); } } void updateStop() { if(directionSpinner.getSelectedItemPosition() > 0) { int pos = directionSpinner.getSelectedItemPosition(); config.setDirection((NextBusDirection) directionAdapter.getItem(pos)); new UpdateEndPoint().execute(config); } } private class UpdateAgencies extends AsyncTask<NextBusObserverConfig, Void, List<NextBusAgency>> { @Override protected List<NextBusAgency> doInBackground(NextBusObserverConfig... arg) { return arg[0].getAgencies(); } @Override protected void onPostExecute(List<NextBusAgency> result) { agencyAdapter = createAdapter(result, agencySpinner); agencySpinner.setEnabled(true); // Load previously selected agency from preferences long selectedAgency = getSharedPreferences(MainActivity.PREFS, MODE_PRIVATE).getLong("agency", -1); if (selectedAgency >= 0) { int position = AdapterUtils.getAdapterPositionById(agencySpinner.getAdapter(), selectedAgency); agencySpinner.setSelection(position); } } } private class UpdateRoutes extends AsyncTask<NextBusObserverConfig, Void, List<NextBusRoute>> { @Override protected List<NextBusRoute> doInBackground(NextBusObserverConfig... arg) { return arg[0].getRoutes(); } @Override protected void onPostExecute(List<NextBusRoute> result) { routeAdapter = createAdapter(result, routeSpinner); routeSpinner.setEnabled(true); } } private class UpdateDirection extends AsyncTask<NextBusObserverConfig, Void, List<NextBusDirection>> { @Override protected List<NextBusDirection> doInBackground(NextBusObserverConfig... arg) { return arg[0].getDirections(); } @Override protected void onPostExecute(List<NextBusDirection> result) { directionAdapter = createAdapter(result, directionSpinner); directionSpinner.setEnabled(true); } } private class UpdateEndPoint extends AsyncTask<NextBusObserverConfig, Void, List<NextBusStop>> { @Override protected List<NextBusStop> doInBackground(NextBusObserverConfig... arg) { return arg[0].getStops(); } @Override protected void onPostExecute(List<NextBusStop> result) { endPointAdapter = createAdapter(result, stopSpinner); stopSpinner.setEnabled(true); saveButton.setEnabled(false); } } // the callback received when the user "sets" the time in the dialog private TimePickerDialog.OnTimeSetListener mStartTimeSetListener = new TimePickerDialog.OnTimeSetListener() { public void onTimeSet(TimePicker view, int hourOfDay, int minute) { startHour = hourOfDay; startMinute = minute; updateStartDisplay(); } }; // the callback received when the user "sets" the time in the dialog private TimePickerDialog.OnTimeSetListener mEndTimeSetListener = new TimePickerDialog.OnTimeSetListener() { public void onTimeSet(TimePicker view, int hourOfDay, int minute) { endHour = hourOfDay; endMinute = minute; updateEndDisplay(); } }; }