Rev 15 | Rev 17 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 15 | Rev 16 | ||
---|---|---|---|
1 | package de.pointedears.converter.app; |
1 | package de.pointedears.converter.app; |
2 | 2 | ||
3 | import java.util.HashMap; |
3 | import java.util.HashMap; |
4 | import java.util.Map.Entry; |
4 | import java.util.Map.Entry; |
5 | 5 | ||
6 | import android.app.Activity; |
6 | import android.app.Activity; |
7 | import android.os.Bundle; |
7 | import android.os.Bundle; |
- | 8 | import android.os.Handler; |
|
8 | import android.text.Editable; |
9 | import android.text.Editable; |
9 | import android.view.KeyEvent; |
10 | import android.view.KeyEvent; |
10 | import android.view.Menu; |
11 | import android.view.Menu; |
11 | import android.view.MenuInflater; |
12 | import android.view.MenuInflater; |
12 | import android.view.MenuItem; |
13 | import android.view.MenuItem; |
13 | import android.view.View; |
14 | import android.view.View; |
14 | import android.view.View.OnClickListener; |
15 | import android.view.View.OnClickListener; |
15 | import android.view.View.OnKeyListener; |
16 | import android.view.View.OnKeyListener; |
16 | import android.widget.AdapterView; |
17 | import android.widget.AdapterView; |
17 | import android.widget.AdapterView.OnItemSelectedListener; |
18 | import android.widget.AdapterView.OnItemSelectedListener; |
18 | import android.widget.Button; |
19 | import android.widget.Button; |
19 | import android.widget.EditText; |
20 | import android.widget.EditText; |
20 | import android.widget.Spinner; |
21 | import android.widget.Spinner; |
21 | import android.widget.TableLayout; |
22 | import android.widget.TableLayout; |
22 | import android.widget.TableRow; |
23 | import android.widget.TableRow; |
23 | import android.widget.TextView; |
24 | import android.widget.TextView; |
24 | import de.pointedears.converter.R; |
25 | import de.pointedears.converter.R; |
25 | import de.pointedears.converter.db.CurrenciesDatabase; |
26 | import de.pointedears.converter.db.CurrenciesDatabase; |
26 | import de.pointedears.converter.helpers.CurrenciesUpdateThread; |
27 | import de.pointedears.converter.helpers.ConverterThread; |
- | 28 | import de.pointedears.converter.net.RatesUpdater; |
|
27 | 29 | ||
28 | /**
|
30 | /**
|
29 | * Activity that implements currency conversion
|
31 | * Activity that implements currency conversion
|
30 | *
|
32 | *
|
31 | * @author pelinux
|
33 | * @author pelinux
|
32 | */
|
34 | */
|
33 | public class CurrenciesActivity extends Activity |
35 | public class CurrenciesActivity extends Activity |
34 | {
|
36 | {
|
35 | /*
|
37 | /*
|
36 | * Constants for mapping value strings
|
38 | * Constants for mapping value strings
|
37 | *
|
39 | *
|
38 | * @todo: Use resource IDs
|
40 | * @todo: Use resource IDs
|
39 | */
|
41 | */
|
40 | /**
|
42 | /**
|
41 | * Database field/spinner value for Swiss Francs
|
43 | * Database field/spinner value for Swiss Francs
|
42 | */
|
44 | */
|
43 | public static final String VALUE_CHF = "CHF"; //$NON-NLS-1$ |
45 | public static final String VALUE_CHF = "CHF"; //$NON-NLS-1$ |
44 | 46 | ||
45 | /**
|
47 | /**
|
46 | * Database field/spinner value for Euros
|
48 | * Database field/spinner value for Euros
|
47 | */
|
49 | */
|
48 | 50 | ||
49 | public static final String VALUE_EUR = "EUR"; //$NON-NLS-1$ |
51 | public static final String VALUE_EUR = "EUR"; //$NON-NLS-1$ |
50 | 52 | ||
51 | /**
|
53 | /**
|
52 | * Database field/spinner value for US Dollars
|
54 | * Database field/spinner value for US Dollars
|
53 | */
|
55 | */
|
54 | public static final String VALUE_USD = "USD"; //$NON-NLS-1$ |
56 | public static final String VALUE_USD = "USD"; //$NON-NLS-1$ |
55 | 57 | ||
56 | /* Unit spinners (dropdowns) */
|
58 | /* Unit spinners (dropdowns) */
|
57 | private Spinner spinnerUnit1; |
59 | private Spinner spinnerUnit1; |
58 | private Spinner spinnerUnit2; |
60 | private Spinner spinnerUnit2; |
59 | private CurrenciesDatabase db; |
61 | private CurrenciesDatabase db; |
60 | 62 | ||
61 | private HashMap<String, HashMap<String, Double>> conversionRates; |
63 | private HashMap<String, Double> conversionRates; |
- | 64 | private ConverterThread updateThread; |
|
- | 65 | private Handler handler; |
|
- | 66 | ||
- | 67 | private RatesUpdater updateRates; |
|
62 | 68 | ||
63 | /** Called when the activity is first created. */
|
69 | /** Called when the activity is first created. */
|
64 | 70 | ||
65 | @Override |
71 | @Override |
66 | public void onCreate(Bundle savedInstanceState) |
72 | public void onCreate(Bundle savedInstanceState) |
67 | {
|
73 | {
|
68 | super.onCreate(savedInstanceState); |
74 | super.onCreate(savedInstanceState); |
69 | this.setContentView(R.layout.activity_currencies); |
75 | this.setContentView(R.layout.activity_currencies); |
70 | 76 | ||
71 | /* Set up currency database, and retrieve conversion rates */
|
77 | /* Set up currency database, and retrieve conversion rates */
|
72 | this.db = new CurrenciesDatabase(this); |
78 | this.db = new CurrenciesDatabase(this); |
73 | this.conversionRates = this.db.getConversionRates(); |
79 | this.conversionRates = this.db.getConversionRates(); |
74 | this.fillTableRates(); |
80 | this.fillTableRates(); |
75 | 81 | ||
76 | final EditText editValue1 =
|
82 | final EditText editValue1 =
|
77 | (EditText) this.findViewById(R.id.currencies_edit_value1); |
83 | (EditText) this.findViewById(R.id.currencies_edit_value1); |
78 | final EditText editValue2 =
|
84 | final EditText editValue2 =
|
79 | (EditText) this.findViewById(R.id.currencies_edit_value2); |
85 | (EditText) this.findViewById(R.id.currencies_edit_value2); |
80 | 86 | ||
81 | final OnKeyListener editValue1OnKey = new OnKeyListener() { |
87 | final OnKeyListener editValue1OnKey = new OnKeyListener() { |
82 | @Override |
88 | @Override |
83 | public boolean onKey(View v, int keyCode, KeyEvent event) |
89 | public boolean onKey(View v, int keyCode, KeyEvent event) |
84 | {
|
90 | {
|
85 | Editable editable1 = ((EditText) v).getText(); |
91 | Editable editable1 = ((EditText) v).getText(); |
86 | 92 | ||
87 | Double value1; |
93 | Double value1; |
88 | try
|
94 | try
|
89 | {
|
95 | {
|
90 | value1 = Double.parseDouble(editable1.toString()); |
96 | value1 = Double.parseDouble(editable1.toString()); |
91 | }
|
97 | }
|
92 | catch (NumberFormatException e) |
98 | catch (NumberFormatException e) |
93 | {
|
99 | {
|
94 | value1 = null; |
100 | value1 = null; |
95 | }
|
101 | }
|
96 | 102 | ||
97 | String string2 = ""; //$NON-NLS-1$ |
103 | String string2 = ""; //$NON-NLS-1$ |
98 | if (value1 != null) |
104 | if (value1 != null) |
99 | {
|
105 | {
|
100 | string2 = CurrenciesActivity.this.getConvertedValue(value1, false); |
106 | string2 = CurrenciesActivity.this.getConvertedValue(value1, false); |
101 | }
|
107 | }
|
102 | 108 | ||
103 | editValue2.setText(string2); |
109 | editValue2.setText(string2); |
104 | 110 | ||
105 | return false; |
111 | return false; |
106 | }
|
112 | }
|
107 | }; |
113 | }; |
108 | editValue1.setOnKeyListener(editValue1OnKey); |
114 | editValue1.setOnKeyListener(editValue1OnKey); |
109 | 115 | ||
110 | final OnKeyListener editValue2OnKey = new OnKeyListener() { |
116 | final OnKeyListener editValue2OnKey = new OnKeyListener() { |
111 | @Override |
117 | @Override |
112 | public boolean onKey(View v, int keyCode, KeyEvent event) |
118 | public boolean onKey(View v, int keyCode, KeyEvent event) |
113 | {
|
119 | {
|
114 | Editable editable2 = ((EditText) v).getText(); |
120 | Editable editable2 = ((EditText) v).getText(); |
115 | 121 | ||
116 | Double value2; |
122 | Double value2; |
117 | try
|
123 | try
|
118 | {
|
124 | {
|
119 | value2 = Double.parseDouble(editable2.toString()); |
125 | value2 = Double.parseDouble(editable2.toString()); |
120 | }
|
126 | }
|
121 | catch (NumberFormatException e) |
127 | catch (NumberFormatException e) |
122 | {
|
128 | {
|
123 | value2 = null; |
129 | value2 = null; |
124 | }
|
130 | }
|
125 | 131 | ||
126 | String string1 = ""; //$NON-NLS-1$ |
132 | String string1 = ""; //$NON-NLS-1$ |
127 | if (value2 != null) |
133 | if (value2 != null) |
128 | {
|
134 | {
|
129 | string1 = CurrenciesActivity.this.getConvertedValue(value2, true); |
135 | string1 = CurrenciesActivity.this.getConvertedValue(value2, true); |
130 | }
|
136 | }
|
131 | 137 | ||
132 | editValue1.setText(string1); |
138 | editValue1.setText(string1); |
133 | 139 | ||
134 | return false; |
140 | return false; |
135 | }
|
141 | }
|
136 | }; |
142 | }; |
137 | editValue2.setOnKeyListener(editValue2OnKey); |
143 | editValue2.setOnKeyListener(editValue2OnKey); |
138 | 144 | ||
139 | this.spinnerUnit1 = |
145 | this.spinnerUnit1 = |
140 | (Spinner) this.findViewById(R.id.currencies_spinner_unit1); |
146 | (Spinner) this.findViewById(R.id.currencies_spinner_unit1); |
141 | this.spinnerUnit2 = |
147 | this.spinnerUnit2 = |
142 | (Spinner) this.findViewById(R.id.currencies_spinner_unit2); |
148 | (Spinner) this.findViewById(R.id.currencies_spinner_unit2); |
143 | 149 | ||
144 | this.spinnerUnit1.setOnItemSelectedListener(new OnItemSelectedListener() { |
150 | this.spinnerUnit1.setOnItemSelectedListener(new OnItemSelectedListener() { |
145 | @Override |
151 | @Override |
146 | public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, |
152 | public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, |
147 | long arg3) |
153 | long arg3) |
148 | {
|
154 | {
|
149 | /* Simulate input in second EditText so that first EditText is updated */
|
155 | /* Simulate input in second EditText so that first EditText is updated */
|
150 | editValue2OnKey.onKey(editValue2, 0, null); |
156 | editValue2OnKey.onKey(editValue2, 0, null); |
151 | }
|
157 | }
|
152 | 158 | ||
153 | @Override |
159 | @Override |
154 | public void onNothingSelected(AdapterView<?> arg0) |
160 | public void onNothingSelected(AdapterView<?> arg0) |
155 | {
|
161 | {
|
156 | /* no-op */
|
162 | /* no-op */
|
157 | }
|
163 | }
|
158 | }); |
164 | }); |
159 | 165 | ||
160 | this.spinnerUnit2.setSelection(1); |
166 | this.spinnerUnit2.setSelection(1); |
161 | this.spinnerUnit2.setOnItemSelectedListener(new OnItemSelectedListener() { |
167 | this.spinnerUnit2.setOnItemSelectedListener(new OnItemSelectedListener() { |
162 | @Override |
168 | @Override |
163 | public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, |
169 | public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, |
164 | long arg3) |
170 | long arg3) |
165 | {
|
171 | {
|
166 | /* Simulate input in first EditText so that second EditText is updated */
|
172 | /* Simulate input in first EditText so that second EditText is updated */
|
167 | editValue1OnKey.onKey(editValue1, 0, null); |
173 | editValue1OnKey.onKey(editValue1, 0, null); |
168 | }
|
174 | }
|
169 | 175 | ||
170 | @Override |
176 | @Override |
171 | public void onNothingSelected(AdapterView<?> arg0) |
177 | public void onNothingSelected(AdapterView<?> arg0) |
172 | {
|
178 | {
|
173 | /* no-op */
|
179 | /* no-op */
|
174 | }
|
180 | }
|
175 | }); |
181 | }); |
176 | 182 | ||
177 | Button buttonClear = |
183 | Button buttonClear = |
178 | (Button) this.findViewById(R.id.currencies_button_clear); |
184 | (Button) this.findViewById(R.id.currencies_button_clear); |
179 | buttonClear.setOnClickListener(new OnClickListener() { |
185 | buttonClear.setOnClickListener(new OnClickListener() { |
180 | 186 | ||
181 | @SuppressWarnings("nls") |
187 | @SuppressWarnings("nls") |
182 | @Override |
188 | @Override |
183 | public void onClick(View v) |
189 | public void onClick(View v) |
184 | {
|
190 | {
|
185 | editValue1.setText(""); |
191 | editValue1.setText(""); |
186 | editValue2.setText(""); |
192 | editValue2.setText(""); |
187 | }
|
193 | }
|
188 | }); |
194 | }); |
- | 195 | ||
- | 196 | if (this.handler == null) |
|
- | 197 | {
|
|
- | 198 | this.handler = new Handler(); |
|
- | 199 | }
|
|
- | 200 | ||
- | 201 | this.updateThread = null; |
|
189 | }
|
202 | }
|
190 | 203 | ||
191 | /**
|
204 | /**
|
192 | * Fills the table with currency conversion rates
|
205 | * Fills the table with currency conversion rates
|
193 | */
|
206 | */
|
194 | private void fillTableRates() |
207 | private void fillTableRates() |
195 | {
|
208 | {
|
196 | TableLayout tableRates = |
209 | TableLayout tableRates = |
197 | (TableLayout) this.findViewById(R.id.currencies_table_rates); |
210 | (TableLayout) this.findViewById(R.id.currencies_table_rates); |
198 | 211 | ||
199 | for (String key : this.conversionRates.keySet()) |
212 | for (Entry<String, Double> factorEntry : this.conversionRates.entrySet()) |
200 | {
|
213 | {
|
201 | for (Entry<String, Double> factorEntry : this.conversionRates.get(key) |
- | |
202 | .entrySet()) |
- | |
203 | {
|
- | |
204 | TableRow row = new TableRow(this); |
214 | TableRow row = new TableRow(this); |
205 | - | ||
206 | TextView columnCurrency1 = new TextView(this); |
- | |
207 | columnCurrency1.setText(key); |
- | |
208 | row.addView(columnCurrency1); |
- | |
209 | 215 | ||
210 | TextView columnCurrency2 = new TextView(this); |
216 | TextView columnCurrency1 = new TextView(this); |
211 | columnCurrency2.setText(factorEntry.getKey()); |
217 | columnCurrency1.setText(factorEntry.getKey()); |
212 | row.addView(columnCurrency2); |
218 | row.addView(columnCurrency1); |
213 | 219 | ||
214 | TextView columnRate = new TextView(this); |
220 | TextView columnRate = new TextView(this); |
215 | columnRate.setText(factorEntry.getValue().toString()); |
221 | columnRate.setText(factorEntry.getValue().toString()); |
216 | row.addView(columnRate); |
222 | row.addView(columnRate); |
217 | 223 | ||
218 | tableRates.addView(row); |
224 | tableRates.addView(row); |
219 | }
|
- | |
220 | }
|
225 | }
|
221 | }
|
226 | }
|
222 | 227 | ||
223 | /**
|
228 | /**
|
224 | * @param value
|
229 | * @param value
|
225 | * @return
|
230 | * @return
|
226 | */
|
231 | */
|
227 | private String getConvertedValue(double value, boolean reverse) |
232 | private String getConvertedValue(double value, boolean reverse) |
228 | {
|
233 | {
|
229 | int selectedItemPosition1 = this.spinnerUnit1.getSelectedItemPosition(); |
234 | int selectedItemPosition1 = this.spinnerUnit1.getSelectedItemPosition(); |
230 | int selectedItemPosition2 = this.spinnerUnit2.getSelectedItemPosition(); |
235 | int selectedItemPosition2 = this.spinnerUnit2.getSelectedItemPosition(); |
231 | String[] items = |
236 | String[] items = |
232 | this.getResources().getStringArray(R.array.currency_units_values); |
237 | this.getResources().getStringArray(R.array.currency_units_values); |
233 | String selectedItemValue1 = items[selectedItemPosition1]; |
238 | String selectedItemValue1 = items[selectedItemPosition1]; |
234 | String selectedItemValue2 = items[selectedItemPosition2]; |
239 | String selectedItemValue2 = items[selectedItemPosition2]; |
235 | 240 | ||
236 | if (reverse) |
241 | if (reverse) |
237 | {
|
242 | {
|
238 | String tmp = selectedItemValue1; |
243 | String tmp = selectedItemValue1; |
239 | selectedItemValue1 = selectedItemValue2;
|
244 | selectedItemValue1 = selectedItemValue2;
|
240 | selectedItemValue2 = tmp;
|
245 | selectedItemValue2 = tmp;
|
241 | }
|
246 | }
|
242 | 247 | ||
243 | Double newValue = value; |
248 | Double newValue = value; |
244 | 249 | ||
- | 250 | /*
|
|
- | 251 | * NOTE: Had to do it the complicated way because somehow the Android SDK
|
|
245 | HashMap<String, Double> mapForCurrency = |
252 | * won't get it another way
|
- | 253 | */
|
|
246 | this.conversionRates.get(selectedItemValue1); |
254 | Double factorToEuro = null; |
247 | if (mapForCurrency != null) |
255 | if (selectedItemValue1 != null) |
248 | {
|
256 | {
|
249 | Double conversionFactor = mapForCurrency.get(selectedItemValue2); |
257 | factorToEuro = this.conversionRates.get(selectedItemValue1); |
250 | if (conversionFactor != null) |
- | |
251 | {
|
- | |
252 | newValue *= conversionFactor; |
- | |
253 | }
|
- | |
254 | }
|
258 | }
|
255 | 259 | ||
- | 260 | if (factorToEuro == null) |
|
- | 261 | {
|
|
- | 262 | factorToEuro = 1.0; |
|
- | 263 | }
|
|
- | 264 | ||
- | 265 | Double factorFromEuro = null; |
|
- | 266 | if (selectedItemValue2 != null) |
|
- | 267 | {
|
|
- | 268 | factorFromEuro = this.conversionRates.get(selectedItemValue2); |
|
- | 269 | }
|
|
- | 270 | ||
- | 271 | if (factorFromEuro == null) |
|
- | 272 | {
|
|
- | 273 | factorFromEuro = 1.0; |
|
- | 274 | }
|
|
- | 275 | ||
- | 276 | newValue = newValue / factorToEuro * factorFromEuro; |
|
- | 277 | ||
256 | return newValue.toString(); |
278 | return newValue.toString(); |
257 | }
|
279 | }
|
258 | 280 | ||
259 | /*
|
281 | /*
|
260 | * (non-Javadoc)
|
282 | * (non-Javadoc)
|
261 | *
|
283 | *
|
262 | * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
|
284 | * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
|
263 | */
|
285 | */
|
264 | /*
|
286 | /*
|
265 | * (non-Javadoc)
|
287 | * (non-Javadoc)
|
266 | *
|
288 | *
|
267 | * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
|
289 | * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
|
268 | */
|
290 | */
|
269 | @Override |
291 | @Override |
270 | public boolean onCreateOptionsMenu(Menu menu) |
292 | public boolean onCreateOptionsMenu(Menu menu) |
271 | {
|
293 | {
|
272 | MenuInflater inflater = this.getMenuInflater(); |
294 | MenuInflater inflater = this.getMenuInflater(); |
273 | inflater.inflate(R.menu.options, menu); |
295 | inflater.inflate(R.menu.options, menu); |
274 | return true; |
296 | return true; |
275 | }
|
297 | }
|
276 | 298 | ||
277 | /*
|
299 | /*
|
278 | * (non-Javadoc)
|
300 | * (non-Javadoc)
|
279 | *
|
301 | *
|
280 | * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
|
302 | * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
|
281 | */
|
303 | */
|
282 | @Override |
304 | @Override |
283 | public boolean onOptionsItemSelected(MenuItem item) |
305 | public boolean onOptionsItemSelected(MenuItem item) |
284 | {
|
306 | {
|
285 | // Handle item selection
|
307 | // Handle item selection
|
286 | switch (item.getItemId()) |
308 | switch (item.getItemId()) |
287 | {
|
309 | {
|
288 | case R.id.item_options_update: |
310 | case R.id.item_options_update: |
- | 311 | if (this.updateThread == null) |
|
- | 312 | {
|
|
289 | Thread updateThread = new CurrenciesUpdateThread(); |
313 | this.updateRates = new RatesUpdater(this); |
- | 314 | this.updateThread = |
|
- | 315 | new ConverterThread(this.updateRates, this.handler); |
|
- | 316 | this.updateRates.setUpdateThread(this.updateThread); |
|
- | 317 | }
|
|
- | 318 | ||
- | 319 | try
|
|
- | 320 | {
|
|
290 | updateThread.start(); |
321 | this.updateThread.start(); |
- | 322 | // this.editValue1.setText("Gestartet!");
|
|
- | 323 | }
|
|
- | 324 | catch (IllegalThreadStateException e) |
|
- | 325 | {
|
|
- | 326 | // this.editValue1.setText("Bereits gestartet!");
|
|
- | 327 | }
|
|
- | 328 | return true; |
|
- | 329 | ||
- | 330 | case R.id.item_options_quit: |
|
- | 331 | if (this.updateThread != null) |
|
- | 332 | {
|
|
- | 333 | try
|
|
- | 334 | {
|
|
- | 335 | this.updateThread.join(); |
|
- | 336 | }
|
|
- | 337 | catch (InterruptedException e) |
|
- | 338 | {
|
|
- | 339 | // TODO Auto-generated catch block
|
|
- | 340 | }
|
|
- | 341 | ||
- | 342 | // this.editValue1.setText("Gestoppt -> Warten auf Start");
|
|
- | 343 | }
|
|
- | 344 | else
|
|
- | 345 | {
|
|
- | 346 | // this.editValue1.setText("Bereits gestoppt -> Warten auf Start");
|
|
- | 347 | }
|
|
291 | return true; |
348 | return true; |
292 | 349 | ||
293 | default:
|
350 | default:
|
294 | return super.onOptionsItemSelected(item); |
351 | return super.onOptionsItemSelected(item); |
295 | }
|
352 | }
|
296 | }
|
353 | }
|
297 | }
|
354 | }
|
298 | 355 |