diff options
author | Danny Baumann <dannybaumann@web.de> | 2013-10-11 11:19:34 +0200 |
---|---|---|
committer | Danny Baumann <dannybaumann@web.de> | 2013-10-13 13:37:05 +0200 |
commit | 505d24a32029d4b98b88885ff4a85c12c9be66fd (patch) | |
tree | a3cc7bc3ac173291fb019aca42f912634c563c9e /src | |
parent | d0ea3088d7b866315e9a54e875de6caae71b48b1 (diff) | |
download | android_packages_apps_LockClock-505d24a32029d4b98b88885ff4a85c12c9be66fd.tar.gz android_packages_apps_LockClock-505d24a32029d4b98b88885ff4a85c12c9be66fd.tar.bz2 android_packages_apps_LockClock-505d24a32029d4b98b88885ff4a85c12c9be66fd.zip |
Avoid NPE when closing custom location dialog.
Also factor out custom location preference handling to own class to
make it a little easier to implement.
Change-Id: I081997c1ece13789ca908f3e87ebf24a25ce2fd1
Diffstat (limited to 'src')
-rw-r--r-- | src/com/cyanogenmod/lockclock/preference/CustomLocationPreference.java | 200 | ||||
-rw-r--r-- | src/com/cyanogenmod/lockclock/preference/WeatherPreferences.java | 138 |
2 files changed, 204 insertions, 134 deletions
diff --git a/src/com/cyanogenmod/lockclock/preference/CustomLocationPreference.java b/src/com/cyanogenmod/lockclock/preference/CustomLocationPreference.java new file mode 100644 index 0000000..33454b4 --- /dev/null +++ b/src/com/cyanogenmod/lockclock/preference/CustomLocationPreference.java @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2012 The CyanogenMod Project (DvTonder) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cyanogenmod.lockclock.preference; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.AsyncTask; +import android.os.Bundle; +import android.preference.EditTextPreference; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.Toast; + +import com.cyanogenmod.lockclock.R; +import com.cyanogenmod.lockclock.misc.Preferences; +import com.cyanogenmod.lockclock.weather.WeatherProvider.LocationResult; +import com.cyanogenmod.lockclock.weather.YahooWeatherProvider; + +import java.util.List; + +public class CustomLocationPreference extends EditTextPreference { + private static final String TAG = "CustomLocationPreference"; + + public CustomLocationPreference(Context context) { + super(context); + } + public CustomLocationPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + public CustomLocationPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + protected void showDialog(Bundle state) { + super.showDialog(state); + + final AlertDialog d = (AlertDialog) getDialog(); + Button okButton = d.getButton(DialogInterface.BUTTON_POSITIVE); + + okButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CustomLocationPreference.this.onClick(d, DialogInterface.BUTTON_POSITIVE); + new WeatherLocationTask(d, getEditText().getText().toString()).execute(); + } + }); + } + + @Override + protected void onBindDialogView(View view) { + super.onBindDialogView(view); + + String location = Preferences.customWeatherLocationCity(getContext()); + if (location != null) { + getEditText().setText(location); + getEditText().setSelection(location.length()); + } + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + // we handle persisting the selected location below, so pretend cancel + super.onDialogClosed(false); + } + + private class WeatherLocationTask extends AsyncTask<Void, Void, List<LocationResult>> { + private Dialog mDialog; + private ProgressDialog mProgressDialog; + private String mLocation; + + public WeatherLocationTask(Dialog dialog, String location) { + mDialog = dialog; + mLocation = location; + } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + + final Context context = getContext(); + + mProgressDialog = new ProgressDialog(context); + mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); + mProgressDialog.setMessage(context.getString(R.string.weather_progress_title)); + mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + cancel(true); + } + }); + } + + @Override + protected List<LocationResult> doInBackground(Void... input) { + return new YahooWeatherProvider(getContext()).getLocations(mLocation); + } + + @Override + protected void onPostExecute(List<LocationResult> results) { + super.onPostExecute(results); + + final Context context = getContext(); + + if (results == null || results.isEmpty()) { + Toast.makeText(context, + context.getString(R.string.weather_retrieve_location_dialog_title), + Toast.LENGTH_SHORT) + .show(); + } else if (results.size() > 1) { + handleResultDisambiguation(results); + } else { + applyLocation(results.get(0)); + } + mProgressDialog.dismiss(); + } + + private void handleResultDisambiguation(final List<LocationResult> results) { + CharSequence[] items = buildItemList(results); + new AlertDialog.Builder(getContext()) + .setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + applyLocation(results.get(which)); + dialog.dismiss(); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .setTitle(R.string.weather_select_location) + .show(); + } + + private CharSequence[] buildItemList(List<LocationResult> results) { + boolean needCountry = false, needPostal = false; + String countryId = results.get(0).countryId; + String postalCity = null, postalCountryId = null; + + for (LocationResult result : results) { + if (!TextUtils.equals(result.countryId, countryId)) { + needCountry = true; + } + if (TextUtils.equals(result.city, postalCity) + && TextUtils.equals(result.countryId, postalCountryId)) { + needPostal = true; + } + if (postalCity == null) { + postalCity = result.city; + postalCountryId = result.countryId; + } + if (needPostal && needCountry) { + break; + } + } + + int count = results.size(); + CharSequence[] items = new CharSequence[count]; + for (int i = 0; i < count; i++) { + LocationResult result = results.get(i); + StringBuilder builder = new StringBuilder(); + if (needPostal && result.postal != null) { + builder.append(result.postal).append(" "); + } + builder.append(result.city); + if (needCountry) { + String country = result.country != null + ? result.country : result.countryId; + builder.append(" (").append(country).append(")"); + } + items[i] = builder.toString(); + } + return items; + } + + private void applyLocation(final LocationResult result) { + Preferences.setCustomWeatherLocationId(getContext(), result.id); + setText(result.city); + mDialog.dismiss(); + } + } +} diff --git a/src/com/cyanogenmod/lockclock/preference/WeatherPreferences.java b/src/com/cyanogenmod/lockclock/preference/WeatherPreferences.java index dde2e9e..327b3e1 100644 --- a/src/com/cyanogenmod/lockclock/preference/WeatherPreferences.java +++ b/src/com/cyanogenmod/lockclock/preference/WeatherPreferences.java @@ -18,40 +18,30 @@ package com.cyanogenmod.lockclock.preference; import android.app.AlertDialog; import android.app.Dialog; -import android.app.ProgressDialog; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.location.LocationManager; import android.os.Bundle; -import android.os.AsyncTask; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.Preference; -import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceFragment; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; -import android.view.View; -import android.widget.Toast; import com.cyanogenmod.lockclock.ClockWidgetProvider; import com.cyanogenmod.lockclock.R; import com.cyanogenmod.lockclock.misc.Constants; import com.cyanogenmod.lockclock.misc.Preferences; import com.cyanogenmod.lockclock.weather.WeatherUpdateService; -import com.cyanogenmod.lockclock.weather.WeatherProvider.LocationResult; -import com.cyanogenmod.lockclock.weather.YahooWeatherProvider; - -import java.util.List; public class WeatherPreferences extends PreferenceFragment implements - OnPreferenceClickListener, OnSharedPreferenceChangeListener { + SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = "WeatherPreferences"; private static final String[] LOCATION_PREF_KEYS = new String[] { @@ -82,14 +72,10 @@ public class WeatherPreferences extends PreferenceFragment implements // Load items that need custom summaries etc. mUseCustomLoc = (CheckBoxPreference) findPreference(Constants.WEATHER_USE_CUSTOM_LOCATION); - mUseCustomLoc.setOnPreferenceClickListener(this); mCustomWeatherLoc = (EditTextPreference) findPreference(Constants.WEATHER_CUSTOM_LOCATION_CITY); - mCustomWeatherLoc.setOnPreferenceClickListener(this); - updateLocationSummary(); mFontColor = (ListPreference) findPreference(Constants.WEATHER_FONT_COLOR); mTimestampFontColor = (ListPreference) findPreference(Constants.WEATHER_TIMESTAMP_FONT_COLOR); - updateFontColorsSummary(); mUseMetric = (CheckBoxPreference) findPreference(Constants.WEATHER_USE_METRIC); @@ -105,6 +91,8 @@ public class WeatherPreferences extends PreferenceFragment implements public void onResume() { super.onResume(); getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); + updateLocationSummary(); + updateFontColorsSummary(); } @Override @@ -121,7 +109,7 @@ public class WeatherPreferences extends PreferenceFragment implements pref.setSummary(listPref.getEntry()); } - if (pref == mUseCustomLoc) { + if (pref == mUseCustomLoc || pref == mCustomWeatherLoc) { updateLocationSummary(); } @@ -167,128 +155,10 @@ public class WeatherPreferences extends PreferenceFragment implements mContext.sendBroadcast(updateIntent); } - @Override - public boolean onPreferenceClick(Preference preference) { - if (preference == mCustomWeatherLoc) { - String location = Preferences.customWeatherLocationCity(mContext); - if (location != null) { - mCustomWeatherLoc.getEditText().setText(location); - mCustomWeatherLoc.getEditText().setSelection(location.length()); - } - - final View okButton = mCustomWeatherLoc.getDialog().findViewById(android.R.id.button1); - okButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - final ProgressDialog d = new ProgressDialog(mContext); - d.setProgressStyle(ProgressDialog.STYLE_SPINNER); - d.setMessage(mContext.getString(R.string.weather_progress_title)); - d.show(); - - final String location = mCustomWeatherLoc.getEditText().getText().toString(); - final WeatherLocationTask task = new WeatherLocationTask() { - @Override - protected void onPostExecute(final List<LocationResult> results) { - if (results == null || results.isEmpty()) { - Toast.makeText(mContext, - mContext.getString(R.string.weather_retrieve_location_dialog_title), - Toast.LENGTH_SHORT) - .show(); - } else if (results.size() > 1) { - handleResultDisambiguation(results); - } else { - applyLocation(results.get(0)); - } - d.dismiss(); - } - }; - task.execute(location); - } - - private void handleResultDisambiguation(final List<LocationResult> results) { - CharSequence[] items = buildItemList(results); - new AlertDialog.Builder(mContext) - .setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - applyLocation(results.get(which)); - dialog.dismiss(); - } - }) - .setNegativeButton(android.R.string.cancel, null) - .setTitle(R.string.weather_select_location) - .show(); - } - - private CharSequence[] buildItemList(List<LocationResult> results) { - boolean needCountry = false, needPostal = false; - String countryId = results.get(0).countryId; - String postalCity = null, postalCountryId = null; - - for (LocationResult result : results) { - if (!TextUtils.equals(result.countryId, countryId)) { - needCountry = true; - } - if (TextUtils.equals(result.city, postalCity) - && TextUtils.equals(result.countryId, postalCountryId)) { - needPostal = true; - } - if (postalCity == null) { - postalCity = result.city; - postalCountryId = result.countryId; - } - if (needPostal && needCountry) { - break; - } - } - - int count = results.size(); - CharSequence[] items = new CharSequence[count]; - for (int i = 0; i < count; i++) { - LocationResult result = results.get(i); - StringBuilder builder = new StringBuilder(); - if (needPostal && result.postal != null) { - builder.append(result.postal).append(" "); - } - builder.append(result.city); - if (needCountry) { - String country = result.country != null - ? result.country : result.countryId; - builder.append(" (").append(country).append(")"); - } - items[i] = builder.toString(); - } - return items; - } - private void applyLocation(final LocationResult result) { - Preferences.setCustomWeatherLocationId(mContext, result.id); - mCustomWeatherLoc.setText(result.city); - mCustomWeatherLoc.setSummary(result.city); - mCustomWeatherLoc.getDialog().dismiss(); - } - }); - return true; - } - return false; - } - //=============================================================================================== // Utility classes and supporting methods //=============================================================================================== - private class WeatherLocationTask extends AsyncTask<String, Void, List<LocationResult>> { - @Override - protected List<LocationResult> doInBackground(String... input) { - try { - return new YahooWeatherProvider(mContext).getLocations(input[0]); - } catch (Exception e) { - Log.e(TAG, "Could not resolve location", e); - } - - return null; - } - } - private void updateLocationSummary() { if (mUseCustomLoc.isChecked()) { String location = Preferences.customWeatherLocationCity(mContext); |