Subversion Repositories ES

Rev

Rev 18 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8 PointedEar 1
package de.pointedears.converter.app;
5 PointedEar 2
 
17 PointedEar 3
import java.text.DateFormat;
4
import java.util.Date;
7 PointedEar 5
import java.util.HashMap;
14 PointedEar 6
import java.util.Map.Entry;
7 PointedEar 7
 
5 PointedEar 8
import android.app.Activity;
17 PointedEar 9
import android.content.BroadcastReceiver;
10
import android.content.Context;
11
import android.content.Intent;
12
import android.content.IntentFilter;
5 PointedEar 13
import android.os.Bundle;
7 PointedEar 14
import android.text.Editable;
15
import android.view.KeyEvent;
8 PointedEar 16
import android.view.Menu;
17
import android.view.MenuInflater;
18
import android.view.MenuItem;
7 PointedEar 19
import android.view.View;
13 PointedEar 20
import android.view.View.OnClickListener;
7 PointedEar 21
import android.view.View.OnKeyListener;
22
import android.widget.AdapterView;
23
import android.widget.AdapterView.OnItemSelectedListener;
13 PointedEar 24
import android.widget.Button;
7 PointedEar 25
import android.widget.EditText;
26
import android.widget.Spinner;
14 PointedEar 27
import android.widget.TableLayout;
28
import android.widget.TableRow;
29
import android.widget.TextView;
8 PointedEar 30
import de.pointedears.converter.R;
17 PointedEar 31
import de.pointedears.converter.db.ConversionData;
11 PointedEar 32
import de.pointedears.converter.db.CurrenciesDatabase;
17 PointedEar 33
import de.pointedears.converter.helpers.Notifier;
34
import de.pointedears.converter.helpers.UpdateService;
5 PointedEar 35
 
36
/**
7 PointedEar 37
 * Activity that implements currency conversion
5 PointedEar 38
 *
7 PointedEar 39
 * @author pelinux
5 PointedEar 40
 */
41
public class CurrenciesActivity extends Activity
42
{
17 PointedEar 43
  /**
44
   * String to use to indicate that an exchange rate has never been updated
45
   */
20 PointedEar 46
  private String TEXT_NEVER;
17 PointedEar 47
 
7 PointedEar 48
  /*
8 PointedEar 49
   * Constants for mapping value strings
12 PointedEar 50
   *
51
   * @todo: Use resource IDs
7 PointedEar 52
   */
12 PointedEar 53
  /**
54
   * Database field/spinner value for Swiss Francs
55
   */
20 PointedEar 56
  public static String VALUE_CHF;
7 PointedEar 57
 
12 PointedEar 58
  /**
59
   * Database field/spinner value for Euros
60
   */
20 PointedEar 61
  public static String VALUE_EUR;
7 PointedEar 62
 
12 PointedEar 63
  /**
64
   * Database field/spinner value for US Dollars
65
   */
20 PointedEar 66
  public static String VALUE_USD;
12 PointedEar 67
 
7 PointedEar 68
  /* Unit spinners (dropdowns) */
69
  private Spinner spinnerUnit1;
70
  private Spinner spinnerUnit2;
20 PointedEar 71
  private static CurrenciesDatabase database;
7 PointedEar 72
 
20 PointedEar 73
  private static HashMap<String, ConversionData> conversionRates;
12 PointedEar 74
 
20 PointedEar 75
  private static String EXCHANGE_RATES_UPDATED_TO;
76
 
77
  private final static DateFormat dateFormatter = DateFormat
78
    .getDateInstance(DateFormat.SHORT);
79
 
17 PointedEar 80
  /**
81
   * Receiver for intent broadcasts, registered in
82
   * {@link CurrenciesActivity#onCreate(Bundle)}
83
   */
84
  public class UpdateBroadcastReceiver extends BroadcastReceiver
85
  {
86
    /**
87
     * Notification message template
88
     */
16 PointedEar 89
 
17 PointedEar 90
    /*
91
     * (non-Javadoc)
92
     *
93
     * @see android.content.BroadcastReceiver#onReceive(android.content.Context,
94
     * android.content.Intent)
95
     */
96
    @Override
97
    public void onReceive(Context context, Intent intent)
98
    {
99
      if (intent.getAction().equals(UpdateService.ACTION_UPDATE))
100
      {
18 PointedEar 101
        CurrenciesActivity.this.fillTableRates();
102
 
17 PointedEar 103
        Bundle extras = intent.getExtras();
20 PointedEar 104
        Notifier.sendMessage(
105
          CurrenciesActivity.this,
17 PointedEar 106
          extras.get(UpdateService.EXTRA_NUM_RATES)
20 PointedEar 107
            + CurrenciesActivity.EXCHANGE_RATES_UPDATED_TO
108
            + CurrenciesActivity.dateFormatter.format(extras
109
              .get(UpdateService.EXTRA_DATE)));
17 PointedEar 110
      }
111
    }
112
  }
113
 
7 PointedEar 114
  /** Called when the activity is first created. */
5 PointedEar 115
  @Override
7 PointedEar 116
  public void onCreate(Bundle savedInstanceState)
5 PointedEar 117
  {
118
    super.onCreate(savedInstanceState);
7 PointedEar 119
    this.setContentView(R.layout.activity_currencies);
5 PointedEar 120
 
20 PointedEar 121
    this.TEXT_NEVER =
122
      this.getString(R.string.currencies_never_updated);
123
 
124
    CurrenciesActivity.VALUE_CHF = this.getString(R.string.currencies_CHF);
125
    CurrenciesActivity.VALUE_EUR = this.getString(R.string.currencies_EUR);
126
    CurrenciesActivity.VALUE_USD = this.getString(R.string.currencies_USD);
127
 
128
    CurrenciesActivity.EXCHANGE_RATES_UPDATED_TO =
129
      this.getString(R.string.currencies_notification);
130
 
17 PointedEar 131
    UpdateBroadcastReceiver br = new UpdateBroadcastReceiver();
132
    this.registerReceiver(br, new IntentFilter(UpdateService.ACTION_UPDATE));
133
 
12 PointedEar 134
    /* Set up currency database, and retrieve conversion rates */
20 PointedEar 135
    CurrenciesActivity.database = new CurrenciesDatabase(this);
136
    this.setConversionRates(CurrenciesActivity.database
137
      .getConversionRates());
14 PointedEar 138
    this.fillTableRates();
8 PointedEar 139
 
7 PointedEar 140
    final EditText editValue1 =
141
      (EditText) this.findViewById(R.id.currencies_edit_value1);
142
    final EditText editValue2 =
143
      (EditText) this.findViewById(R.id.currencies_edit_value2);
144
 
145
    final OnKeyListener editValue1OnKey = new OnKeyListener() {
146
      @Override
147
      public boolean onKey(View v, int keyCode, KeyEvent event)
148
      {
149
        Editable editable1 = ((EditText) v).getText();
150
 
151
        Double value1;
152
        try
153
        {
154
          value1 = Double.parseDouble(editable1.toString());
155
        }
156
        catch (NumberFormatException e)
157
        {
158
          value1 = null;
159
        }
160
 
161
        String string2 = ""; //$NON-NLS-1$
162
        if (value1 != null)
163
        {
164
          string2 = CurrenciesActivity.this.getConvertedValue(value1, false);
165
        }
166
 
167
        editValue2.setText(string2);
168
 
169
        return false;
170
      }
171
    };
172
    editValue1.setOnKeyListener(editValue1OnKey);
173
 
174
    final OnKeyListener editValue2OnKey = new OnKeyListener() {
175
      @Override
176
      public boolean onKey(View v, int keyCode, KeyEvent event)
177
      {
178
        Editable editable2 = ((EditText) v).getText();
179
 
180
        Double value2;
181
        try
182
        {
183
          value2 = Double.parseDouble(editable2.toString());
184
        }
185
        catch (NumberFormatException e)
186
        {
187
          value2 = null;
188
        }
189
 
190
        String string1 = ""; //$NON-NLS-1$
191
        if (value2 != null)
192
        {
193
          string1 = CurrenciesActivity.this.getConvertedValue(value2, true);
194
        }
195
 
196
        editValue1.setText(string1);
197
 
198
        return false;
199
      }
200
    };
201
    editValue2.setOnKeyListener(editValue2OnKey);
202
 
203
    this.spinnerUnit1 =
204
      (Spinner) this.findViewById(R.id.currencies_spinner_unit1);
205
    this.spinnerUnit2 =
206
      (Spinner) this.findViewById(R.id.currencies_spinner_unit2);
207
 
208
    this.spinnerUnit1.setOnItemSelectedListener(new OnItemSelectedListener() {
209
      @Override
210
      public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
211
        long arg3)
212
      {
213
        /* Simulate input in second EditText so that first EditText is updated */
214
        editValue2OnKey.onKey(editValue2, 0, null);
215
      }
216
 
217
      @Override
218
      public void onNothingSelected(AdapterView<?> arg0)
219
      {
220
        /* no-op */
221
      }
222
    });
223
 
224
    this.spinnerUnit2.setSelection(1);
225
    this.spinnerUnit2.setOnItemSelectedListener(new OnItemSelectedListener() {
226
      @Override
227
      public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
228
        long arg3)
229
      {
230
        /* Simulate input in first EditText so that second EditText is updated */
231
        editValue1OnKey.onKey(editValue1, 0, null);
232
      }
233
 
234
      @Override
235
      public void onNothingSelected(AdapterView<?> arg0)
236
      {
237
        /* no-op */
238
      }
239
    });
13 PointedEar 240
 
241
    Button buttonClear =
242
      (Button) this.findViewById(R.id.currencies_button_clear);
243
    buttonClear.setOnClickListener(new OnClickListener() {
244
 
245
      @SuppressWarnings("nls")
246
      @Override
247
      public void onClick(View v)
248
      {
249
        editValue1.setText("");
250
        editValue2.setText("");
251
      }
252
    });
5 PointedEar 253
  }
7 PointedEar 254
 
255
  /**
14 PointedEar 256
   * Fills the table with currency conversion rates
257
   */
17 PointedEar 258
  public void fillTableRates()
14 PointedEar 259
  {
260
    TableLayout tableRates =
261
      (TableLayout) this.findViewById(R.id.currencies_table_rates);
262
 
17 PointedEar 263
    /* Remove any pre-existing currency rows */
264
    while (tableRates.getChildCount() > 3)
14 PointedEar 265
    {
17 PointedEar 266
      tableRates.removeViewAt(3);
267
    }
268
 
20 PointedEar 269
    for (Entry<String, ConversionData> factorEntry : CurrenciesActivity
270
      .getConversionRates()
17 PointedEar 271
      .entrySet())
272
    {
16 PointedEar 273
      TableRow row = new TableRow(this);
14 PointedEar 274
 
16 PointedEar 275
      TextView columnCurrency1 = new TextView(this);
276
      columnCurrency1.setText(factorEntry.getKey());
277
      row.addView(columnCurrency1);
14 PointedEar 278
 
16 PointedEar 279
      TextView columnRate = new TextView(this);
17 PointedEar 280
      final ConversionData conversionData = factorEntry.getValue();
281
      columnRate.setText(conversionData.getRate().toString());
16 PointedEar 282
      row.addView(columnRate);
14 PointedEar 283
 
17 PointedEar 284
      TextView columnUpdated = new TextView(this);
285
      Date updated = conversionData.getUpdated();
286
      if (updated.getTime() > 0)
287
      {
20 PointedEar 288
        columnUpdated.setText(CurrenciesActivity.dateFormatter.format(updated));
17 PointedEar 289
      }
290
      else
291
      {
20 PointedEar 292
        columnUpdated.setText(this.TEXT_NEVER);
17 PointedEar 293
      }
294
 
295
      row.addView(columnUpdated);
296
 
16 PointedEar 297
      tableRates.addView(row);
14 PointedEar 298
    }
299
  }
300
 
301
  /**
7 PointedEar 302
   * @param value
303
   * @return
304
   */
305
  private String getConvertedValue(double value, boolean reverse)
306
  {
307
    int selectedItemPosition1 = this.spinnerUnit1.getSelectedItemPosition();
308
    int selectedItemPosition2 = this.spinnerUnit2.getSelectedItemPosition();
8 PointedEar 309
    String[] items =
7 PointedEar 310
      this.getResources().getStringArray(R.array.currency_units_values);
8 PointedEar 311
    String selectedItemValue1 = items[selectedItemPosition1];
312
    String selectedItemValue2 = items[selectedItemPosition2];
7 PointedEar 313
 
314
    if (reverse)
315
    {
316
      String tmp = selectedItemValue1;
317
      selectedItemValue1 = selectedItemValue2;
318
      selectedItemValue2 = tmp;
319
    }
320
 
321
    Double newValue = value;
322
 
16 PointedEar 323
    /*
324
     * NOTE: Had to do it the complicated way because somehow the Android SDK
325
     * won't get it another way
326
     */
17 PointedEar 327
    ConversionData conversionData1 = null;
328
    Double factorToEuro = 1.0;
16 PointedEar 329
    if (selectedItemValue1 != null)
7 PointedEar 330
    {
20 PointedEar 331
      conversionData1 =
332
        CurrenciesActivity.getConversionRates().get(selectedItemValue1);
17 PointedEar 333
      if (conversionData1 != null)
334
      {
335
        factorToEuro = conversionData1.getRate();
336
      }
7 PointedEar 337
    }
338
 
17 PointedEar 339
    ConversionData conversionData2 = null;
340
    Double factorFromEuro = 1.0;
16 PointedEar 341
    if (selectedItemValue2 != null)
342
    {
20 PointedEar 343
      conversionData2 =
344
        CurrenciesActivity.getConversionRates().get(selectedItemValue2);
17 PointedEar 345
      if (conversionData2 != null)
346
      {
347
        factorFromEuro = conversionData2.getRate();
348
      }
16 PointedEar 349
    }
350
 
351
    newValue = newValue / factorToEuro * factorFromEuro;
352
 
7 PointedEar 353
    return newValue.toString();
354
  }
8 PointedEar 355
 
356
  /*
357
   * (non-Javadoc)
358
   *
359
   * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
360
   */
12 PointedEar 361
  /*
362
   * (non-Javadoc)
363
   *
364
   * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
365
   */
8 PointedEar 366
  @Override
367
  public boolean onCreateOptionsMenu(Menu menu)
368
  {
369
    MenuInflater inflater = this.getMenuInflater();
370
    inflater.inflate(R.menu.options, menu);
371
    return true;
372
  }
373
 
374
  /*
375
   * (non-Javadoc)
376
   *
377
   * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
378
   */
379
  @Override
380
  public boolean onOptionsItemSelected(MenuItem item)
381
  {
17 PointedEar 382
    /* Handle item selection */
15 PointedEar 383
    switch (item.getItemId())
384
    {
385
      case R.id.item_options_update:
17 PointedEar 386
        /*
387
         * Request the update service to run a thread to fetch the rates from
388
         * the Web (project requirement)
389
         */
390
        Intent intent = new Intent(this, UpdateService.class);
391
        intent.setAction(UpdateService.ACTION_UPDATE);
392
        this.startService(intent);
16 PointedEar 393
        return true;
394
 
15 PointedEar 395
      default:
396
        return super.onOptionsItemSelected(item);
397
    }
8 PointedEar 398
  }
17 PointedEar 399
 
400
  /**
401
   * @return the conversionRates
402
   */
20 PointedEar 403
  public static HashMap<String, ConversionData> getConversionRates()
17 PointedEar 404
  {
20 PointedEar 405
    return CurrenciesActivity.conversionRates;
17 PointedEar 406
  }
407
 
408
  /**
409
   * @param conversionRates
410
   *          the conversionRates to set
411
   */
412
  public void setConversionRates(HashMap<String, ConversionData> conversionRates)
413
  {
20 PointedEar 414
    CurrenciesActivity.conversionRates = conversionRates;
17 PointedEar 415
  }
416
 
417
  /**
418
   * @return the database
419
   */
20 PointedEar 420
  public static CurrenciesDatabase getDatabase()
17 PointedEar 421
  {
20 PointedEar 422
    return CurrenciesActivity.database;
17 PointedEar 423
  }
5 PointedEar 424
}