package com.mehmetakiftutuncu.eshotroid.task; import java.util.ArrayList; import android.app.Activity; import android.content.Context; import android.os.AsyncTask; import android.os.Handler; import android.util.Log; import com.mehmetakiftutuncu.eshotroid.BuildConfig; import com.mehmetakiftutuncu.eshotroid.R; import com.mehmetakiftutuncu.eshotroid.activity.Times; import com.mehmetakiftutuncu.eshotroid.database.BusDatabase; import com.mehmetakiftutuncu.eshotroid.fragment.BusTimesFragment; import com.mehmetakiftutuncu.eshotroid.model.Bus; import com.mehmetakiftutuncu.eshotroid.model.BusTime; import com.mehmetakiftutuncu.eshotroid.model.BusTimeTypes; import com.mehmetakiftutuncu.eshotroid.utility.Connection; import com.mehmetakiftutuncu.eshotroid.utility.Constants; import com.mehmetakiftutuncu.eshotroid.utility.Messages; import com.mehmetakiftutuncu.eshotroid.utility.Parser; import com.mehmetakiftutuncu.eshotroid.utility.Processor; /** An asynchronous task for getting the times of a bus page * * @author mehmetakiftutuncu */ public class GetBusTimesPageTask extends AsyncTask<Void, Void, Void> implements Runnable { /** {@link Context} of the activity that uses runs this task */ private Context myContext; /** {@link BusTimesFragment} whose contents will be updated */ private BusTimesFragment myBusTimesFragment; /** {@link Bus} object whose times will be updated */ private Bus myBus; /** Type of the times, one of the values of {@link BusTimeTypes} */ private BusTimeTypes myType; /** URL of the page to be downloaded generated from * {@link GetBusTimesPageTask#myBus} and {@link GetBusTimesPageTask#myType} */ private String url; /** The contents of the page that will be downloaded and later parsed */ private String result; /** The resulting list of {@link BusTime} objects after processing * downloaded data */ private ArrayList<BusTime> busTimes; /** Tag for debugging */ private static final String LOG_TAG = "Eshotroid_GetBusTimesPageTask"; /** Constructor for background downloading * * @param context {@link GetBusTimesPageTask#myContext} * @param bus {@link GetBusTimesPageTask#myBus} * @param type {@link GetBusTimesPageTask#myType} */ public GetBusTimesPageTask(Context context, Bus bus, BusTimeTypes type) { this(context, null, bus, type); } /** Constructor for downloading and updating UI afterwards * * @param context {@link GetBusTimesPageTask#myContext} * @param busTimesFragment {@link GetBusTimesPageTask#myBusTimesFragment} * @param bus {@link GetBusTimesPageTask#myBus} * @param type {@link GetBusTimesPageTask#myType} */ public GetBusTimesPageTask(Context context, BusTimesFragment busTimesFragment, Bus bus, BusTimeTypes type) { myContext = context; myBusTimesFragment = busTimesFragment; myBus = bus; myType = type; url = String.format("%s?%s=%s&%s=%s", Constants.BUS_TIMES_URL, Constants.NUMBER_PARAMETER, bus.getNumber(), Constants.TYPE_PARAMETER, type.getCode()); } @Override protected Void doInBackground(Void... params) { if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Getting times for " + myBus.getNumber() + myType.getCode() + "..."); // Post a message to the UI thread to update UI to busy new Handler(myContext.getMainLooper()).post(new Runnable() { @Override public void run() { // If a fragment is provided if(myBusTimesFragment != null) { // Hide bus times myBusTimesFragment.showBusTimes(false); // Toggle to busy switch(myType) { case WEEK_DAY: ((Times) myContext).toggleMode(true, Constants.PAGE_ID_BUS_TIMES_H); break; case SATURDAY: ((Times) myContext).toggleMode(true, Constants.PAGE_ID_BUS_TIMES_C); break; case SUNDAY: ((Times) myContext).toggleMode(true, Constants.PAGE_ID_BUS_TIMES_P); break; } } if(myBusTimesFragment != null) { Messages.getInstance().showNeutral((Activity) myContext, myContext.getString(R.string.info_busTimes_refreshing, myBus.getNumber(), myContext.getString(myType.getNameResourceId()))); } } }); // Go and get the page result = Connection.getPage(myContext, url); // If page is downloaded successfully if(result != null) { // Parse and update the route of the bus myBus.setRoute(Parser.parseBusRoute(result)); // Parse and extract bus times information from the page ArrayList<String> parsedBusTimes = Parser.parseBusTimes(result); if(parsedBusTimes != null) { // Create BusTime objects from the parsed information busTimes = Processor.processBusTimes(parsedBusTimes); } // If BusTime objects were created successfully if(busTimes != null) { if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Saving times for " + myBus.getNumber() + myType.getCode() + "..."); // Update the times of the bus according to the type if(myType.equals(BusTimeTypes.WEEK_DAY)) { myBus.setTimesH(busTimes); } else if(myType.equals(BusTimeTypes.SATURDAY)) { myBus.setTimesC(busTimes); } else if(myType.equals(BusTimeTypes.SUNDAY)) { myBus.setTimesP(busTimes); } // Write the bus with all new BusTime objects to the database BusDatabase db = BusDatabase.getDatabase(myContext); db.addOrUpdate(myBus); db.closeDatabase(); } } // If a fragment is provided if(myBusTimesFragment != null) { // Post a message to the UI thread to update the list with new data new Handler(myContext.getMainLooper()).post(this); } return null; } @Override public void run() { // If page is downloaded successfully if(result != null) { // If bus times are created successfully if(busTimes != null) { // If a fragment is provided if(myBusTimesFragment != null) { // Toggle to normal switch(myType) { case WEEK_DAY: ((Times) myContext).toggleMode(false, Constants.PAGE_ID_BUS_TIMES_H); break; case SATURDAY: ((Times) myContext).toggleMode(false, Constants.PAGE_ID_BUS_TIMES_C); break; case SUNDAY: ((Times) myContext).toggleMode(false, Constants.PAGE_ID_BUS_TIMES_P); break; } } if(myBusTimesFragment != null) { Messages.getInstance().showPositive((Activity) myContext, myContext.getString(R.string.info_busTimes_successful, myBus.getNumber(), myContext.getString(myType.getNameResourceId()))); } } else { /* Downloaded but couldn't be parsed (meaning there was no time * for selected type) */ Messages.getInstance().showNeutral((Activity) myContext, myContext.getString(R.string.info_busTimes_noTimes, myBus.getNumber(), myContext.getString(myType.getNameResourceId()))); // Update flag on database switch(myType) { case WEEK_DAY: myBus.setTimesHExists(false); break; case SATURDAY: myBus.setTimesCExists(false); break; case SUNDAY: myBus.setTimesPExists(false); break; } // Write the bus with updated flag to the database BusDatabase db = BusDatabase.getDatabase(myContext); db.addOrUpdate(myBus); db.closeDatabase(); } // Update times in UI myBusTimesFragment.setBusTimes(busTimes); myBusTimesFragment.showBusTimes(true); } // Toggle to ready switch(myType) { case WEEK_DAY: ((Times) myContext).toggleMode(false, Constants.PAGE_ID_BUS_TIMES_H); break; case SATURDAY: ((Times) myContext).toggleMode(false, Constants.PAGE_ID_BUS_TIMES_C); break; case SUNDAY: ((Times) myContext).toggleMode(false, Constants.PAGE_ID_BUS_TIMES_P); break; } } }