/* * Copyright (C) 2011 - 2013 Niall 'Rivernile' Scott * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors or contributors be held liable for * any damages arising from the use of this software. * * The aforementioned copyright holder(s) hereby grant you a * non-transferrable right to use this software for any purpose (including * commercial applications), and to modify it and redistribute it, subject to * the following conditions: * * 1. This notice may not be removed or altered from any file it appears in. * * 2. Any modifications made to this software, except those defined in * clause 3 of this agreement, must be released under this license, and * the source code of any modifications must be made available on a * publically accessible (and locateable) website, or sent to the * original author of this software. * * 3. Software modifications that do not alter the functionality of the * software but are simply adaptations to a specific environment are * exempt from clause 2. */ package uk.org.rivernile.edinburghbustracker.android.fragments.general; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; import android.location.LocationManager; import android.os.Bundle; import android.provider.Settings; import android.support.v4.app.Fragment; import android.text.Html; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.Spinner; import android.widget.TextView; import java.util.List; import uk.org.rivernile.edinburghbustracker.android.BusStopDatabase; import uk.org.rivernile.edinburghbustracker.android.R; import uk.org.rivernile.edinburghbustracker.android.alerts.AlertManager; /** * This fragment allows the user to add a new proximity alert. This alerts the * user when they are within a user-selected range of a particular bus stop. * * @author Niall Scott */ public class AddProximityAlertFragment extends Fragment { /** The stopCode argument. */ public static final String ARG_STOPCODE = "stopCode"; /** The Intent used to show users device location settings. */ public static final Intent LOCATION_SETTINGS_INTENT; private Callbacks callbacks; private AlertManager alertMan; private LocationManager locMan; private BusStopDatabase bsd; private String stopCode; private CheckBox checkProxGps; private Spinner spinner; private TextView textProxDialogStop; private int meters = 100; static { // Set up the location settings intent statically. It doesn't need to // be constantly repeated. LOCATION_SETTINGS_INTENT = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS); LOCATION_SETTINGS_INTENT.addFlags( Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); } /** * Create a new instance of the AddProximityAlertFragment. * * @param stopCode The stopCode this alert setting should be for. * @return A new instance of this Fragment. */ public static AddProximityAlertFragment newInstance(final String stopCode) { final AddProximityAlertFragment f = new AddProximityAlertFragment(); final Bundle b = new Bundle(); b.putString(ARG_STOPCODE, stopCode); f.setArguments(b); return f; } /** * {@inheritDoc} */ @Override public void onAttach(final Activity activity) { super.onAttach(activity); try { callbacks = (Callbacks) activity; } catch (ClassCastException e) { throw new IllegalStateException(activity.getClass().getName() + " does not implement " + Callbacks.class.getName()); } } /** * {@inheritDoc} */ @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Bundle args = getArguments(); // Make sure that an args Bundle exists. if(args == null) throw new IllegalStateException("Arguments must be supplied to " + "the AddProximityAlertFragment."); // Get the stopCode argument and make sure it is valid. stopCode = args.getString(ARG_STOPCODE); if(stopCode == null || stopCode.length() == 0) throw new IllegalArgumentException("The stopCode argument must " + "not be null or empty."); final Activity activity = getActivity(); // Get the various resources. alertMan = AlertManager.getInstance(activity.getApplicationContext()); locMan = (LocationManager)activity .getSystemService(Context.LOCATION_SERVICE); bsd = BusStopDatabase.getInstance(activity.getApplicationContext()); } /** * {@inheritDoc} */ @Override public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { final View v = inflater.inflate(R.layout.addproxalert, container, false); checkProxGps = (CheckBox)v.findViewById(R.id.checkProxGPS); spinner = (Spinner)v.findViewById(R.id.prox_distance_select); textProxDialogStop = (TextView)v.findViewById(R.id.textProxDialogStop); Button btn = (Button)v.findViewById(R.id.btnOkay); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(final View v) { // Add a new proximity alert. alertMan.addProximityAlert(stopCode, meters); // Start the GPS preference Activity if the user has checked // the box. if(checkProxGps.isChecked()) { callbacks.onShowGpsPreferences(); } // Tell the hosting Activity that a new alert has been added. callbacks.onProximityAlertAdded(); } }); btn = (Button)v.findViewById(R.id.btnCancel); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(final View v) { // Tell the hosting Activity that the user has cancelled. callbacks.onCancelAddProximityAlert(); } }); btn = (Button)v.findViewById(R.id.btnLimitations); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(final View v) { callbacks.onShowProximityAlertLimitations(); } }); return v; } /** * {@inheritDoc} */ @Override public void onActivityCreated(final Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Sort the distance spinner. final ArrayAdapter<CharSequence> adapter = ArrayAdapter .createFromResource(getActivity(), R.array.addproxalert_distance_array, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); spinner.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(final AdapterView<?> parent, final View view, final int pos, final long id) { switch(pos) { case 0: meters = 100; break; case 1: meters = 250; break; case 2: meters = 500; break; case 3: meters = 750; break; case 4: meters = 1000; break; default: meters = 100; break; } } @Override public void onNothingSelected(final AdapterView parent) { meters = 100; } }); // Get locality information, if there is any. final String locality = bsd.getLocalityForStopCode(stopCode); final String name; if(locality != null) { name = getString(R.string.busstop_locality_coloured, bsd.getNameForBusStop(stopCode), locality, stopCode); } else { name = getString(R.string.busstop_coloured, bsd.getNameForBusStop(stopCode), stopCode); } // Set the information text. textProxDialogStop.setText(Html.fromHtml( getString(R.string.addproxalert_second, name))); } /** * {@inheritDoc} */ @Override public void onResume() { super.onResume(); // Make sure the system preferences Activity which lets the user change // GPS settings is available. final List<ResolveInfo> packages = getActivity().getPackageManager() .queryIntentActivities(LOCATION_SETTINGS_INTENT, 0); if(packages != null && !packages.isEmpty() && !locMan.isProviderEnabled(LocationManager.GPS_PROVIDER)) { checkProxGps.setVisibility(View.VISIBLE); } else { // Don't display if settings Activity is not present, or GPS is // enabled. checkProxGps.setVisibility(View.GONE); } } /** * Any Activities which host this Fragment must implement this interface to * handle navigation events. */ public static interface Callbacks { /** * This is called when the user wants to read the text about the * proximity alert limitations. */ public void onShowProximityAlertLimitations(); /** * This is called when the user has added a new proximity alert. */ public void onProximityAlertAdded(); /** * This is called when the user wants to cancel adding a new proximity * alert. */ public void onCancelAddProximityAlert(); /** * This is called when the user wants to turn on GPS on their device. */ public void onShowGpsPreferences(); } }