This app supports geolocation to calculate your current tax automatically (California ONLY). It also can split your bill between any number of people.
package com.dhd.tipcalculator; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.text.NumberFormat; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import android.os.Bundle; import android.os.Environment; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; import android.widget.RadioGroup; import android.widget.RadioButton; import android.widget.RadioGroup.OnCheckedChangeListener; import android.widget.EditText; import android.widget.Toast; import android.text.TextWatcher; import android.text.Editable; import android.view.View.OnFocusChangeListener; import android.view.inputmethod.EditorInfo; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Point; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.location.Address; import android.location.Criteria; import android.location.Geocoder; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; public class MainActivity extends Activity { private RadioGroup mRadioGroup; private SeekBar mSeekBar; private TextView mTextView_mSplitNumber; TextView mTextView_City; private EditText mEdit_TipPercentage; private EditText mEdit_PreTax; private EditText mEdit_TaxPercentage; private EditText mEdit_TotalTax; private EditText mEdit_Bill_No_Tip; private EditText mEdit_TipAmount; private EditText mEdit_TotalAmount; private EditText mEdit_PerPerson; private int iPersonNum; private double dPreTax; private double dTaxPercentage; private double dTotalTax; private double dTotalBill_No_Tip; private double dTipPercentage; private double dTipAmount; private double dTotalAmount; private double dPerPersonAmount; LocationManager locationManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSeekBar = (SeekBar)this.findViewById(R.id.seekBar_Split); mRadioGroup = (RadioGroup) findViewById(R.id.radioGroup_Tip); mTextView_mSplitNumber = (TextView)this.findViewById(R.id.textView_SplitNumber); mTextView_City = (TextView)this.findViewById(R.id.textView_City); mEdit_TipPercentage = (EditText)this.findViewById(R.id.editText_TipPercentage); mEdit_PreTax = (EditText)this.findViewById(R.id.editText_PreTax); mEdit_TaxPercentage = (EditText)this.findViewById(R.id.editText_TaxPercentage); mEdit_TotalTax = (EditText)this.findViewById(R.id.editText_TotalTax); mEdit_Bill_No_Tip = (EditText)this.findViewById(R.id.editText_Bill_No_Tip); mEdit_TipAmount = (EditText)this.findViewById(R.id.editText_TipAmount); mEdit_TotalAmount = (EditText)this.findViewById(R.id.editText_TotalAmount); mEdit_PerPerson = (EditText)this.findViewById(R.id.editText_PerPerson); //initial data mEdit_TipPercentage.setText("10"); dTipPercentage = 0.1; mEdit_TaxPercentage.setText("8.75"); dTaxPercentage = 0.0875; iPersonNum = 1; //Geolocation String serviceName = Context.LOCATION_SERVICE; locationManager = (LocationManager) getSystemService(serviceName); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(false); criteria.setBearingRequired(false); criteria.setCostAllowed(true); criteria.setPowerRequirement(Criteria.POWER_LOW); String provider = locationManager.getBestProvider(criteria, true); Location location = locationManager.getLastKnownLocation(provider); updateWithNewLocation(location); locationManager.requestLocationUpdates(provider, 2000, 10, locationListener); findViews(); } private final LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { updateWithNewLocation(location); } public void onProviderDisabled(String provider) { updateWithNewLocation(null); } public void onProviderEnabled(String provider) {} public void onStatusChanged(String provider, int status, Bundle extras) {} }; protected void onStop() { super.onStop(); locationManager.removeUpdates(locationListener); } private void readCSVfile(String city, String county) { String sdcardDir = Environment.getExternalStorageDirectory().toString(); String csvfile = sdcardDir+"/Sales Rate/SalesRate_CA.csv"; try { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(csvfile))); StringBuilder sb = new StringBuilder(""); String data = ""; while ((data = br.readLine()) != null) { String[] sarray = data.split(","); if( (sarray[0].indexOf(city) != -1) && (sarray[2].indexOf(county) != -1) ) { String strTipPercentage = sarray[1]; strTipPercentage = strTipPercentage.substring(0, strTipPercentage.length()-1); mEdit_TipPercentage.setText(strTipPercentage); } } } catch (IOException e) { e.printStackTrace(); } } private void updateWithNewLocation(Location location) { String latLongString; Locale.setDefault(Locale.ENGLISH); if (location != null) { double lat = location.getLatitude(); double lng = location.getLongitude(); Geocoder geocoder=new Geocoder(this); List places = null; try { places = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 5); } catch (Exception e) { e.printStackTrace(); } String state = ""; String city = ""; String county = ""; if (places != null && places.size() > 0) { state = ((Address) places.get(0)).getAdminArea(); city = ((Address) places.get(0)).getLocality(); county = ((Address) places.get(0)).getSubAdminArea(); mTextView_City.setText("("+county+")"); readCSVfile(city, county); } } else { mTextView_City.setText(" "); } onStop(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } private void findViews() { mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if(progress > 1) { mTextView_mSplitNumber.setText(String.valueOf(progress)); iPersonNum = progress; } else if(progress == 1) { mTextView_mSplitNumber.setText("No Split"); iPersonNum = 1; } if(progress == 0) { mSeekBar.setProgress(1); mTextView_mSplitNumber.setText("No Split"); iPersonNum = 1; } if( (mEdit_PreTax.getText().toString().length()>0 ) && (mEdit_TaxPercentage.getText().toString().length()>0) && (mEdit_TipPercentage.getText().toString().length()>0) ) { dPerPersonAmount = dTotalAmount / iPersonNum; NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumFractionDigits(2); mEdit_PerPerson.setText(String.valueOf(nf.format(dPerPersonAmount))); } } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }); mEdit_PreTax.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if(!hasFocus) { if( (mEdit_PreTax.getText().toString().length()>0 ) && (mEdit_TaxPercentage.getText().toString().length()>0) ) { dPreTax = Double.parseDouble(mEdit_PreTax.getText().toString()); dTaxPercentage = Double.parseDouble(mEdit_TaxPercentage.getText().toString())/100; NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumFractionDigits(2); dTotalTax = dPreTax * dTaxPercentage; mEdit_TotalTax.setText(String.valueOf(nf.format(dTotalTax))); dTotalBill_No_Tip = dPreTax + dTotalTax; mEdit_Bill_No_Tip.setText(String.valueOf(nf.format(dTotalBill_No_Tip))); if(mEdit_TipPercentage.getText().toString().length()>0) { dTipPercentage = Double.parseDouble(mEdit_TipPercentage.getText().toString())/100; if(dTipPercentage == 0.1) mRadioGroup.check(R.id.radio10); else if(dTipPercentage == 0.15) mRadioGroup.check(R.id.radio15); else if(dTipPercentage == 0.18) mRadioGroup.check(R.id.radio18); else if(dTipPercentage == 0.2) mRadioGroup.check(R.id.radio20); dTipAmount = dTipPercentage * dPreTax; mEdit_TipAmount.setText(String.valueOf(nf.format(dTipAmount))); dTotalAmount = dTotalBill_No_Tip + dTipAmount; mEdit_TotalAmount.setText(String.valueOf(nf.format(dTotalAmount))); dPerPersonAmount = dTotalAmount / iPersonNum; mEdit_PerPerson.setText(String.valueOf(nf.format(dPerPersonAmount))); } } } } }); mEdit_TaxPercentage.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if( (mEdit_PreTax.getText().toString().length()>0 ) && (mEdit_TaxPercentage.getText().toString().length()>0) ) { dPreTax = Double.parseDouble(mEdit_PreTax.getText().toString()); dTaxPercentage = Double.parseDouble(mEdit_TaxPercentage.getText().toString())/100; dTotalTax = dPreTax * dTaxPercentage; mEdit_TotalTax.setText(String.valueOf(dTotalTax)); dTotalBill_No_Tip = dPreTax + dTotalTax; mEdit_Bill_No_Tip.setText(String.valueOf(dTotalBill_No_Tip)); if(mEdit_TipPercentage.getText().toString().length()>0) { dTipPercentage = Double.parseDouble(mEdit_TipPercentage.getText().toString())/100; if(dTipPercentage == 0.1) mRadioGroup.check(R.id.radio10); else if(dTipPercentage == 0.15) mRadioGroup.check(R.id.radio15); else if(dTipPercentage == 0.18) mRadioGroup.check(R.id.radio18); else if(dTipPercentage == 0.2) mRadioGroup.check(R.id.radio20); dTipAmount = dTipPercentage * dPreTax; NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumFractionDigits(2); mEdit_TipAmount.setText(String.valueOf(nf.format(dTipAmount))); dTotalAmount = dTotalBill_No_Tip + dTipAmount; mEdit_TotalAmount.setText(String.valueOf(nf.format(dTotalAmount))); dPerPersonAmount = dTotalAmount / iPersonNum; mEdit_PerPerson.setText(String.valueOf(nf.format(dPerPersonAmount))); } } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void afterTextChanged(Editable s) {} }); mEdit_Bill_No_Tip.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if( (mEdit_Bill_No_Tip.getText().toString().length()>0 ) && (mEdit_TaxPercentage.getText().toString().length()>0) ) { dTaxPercentage = Double.parseDouble(mEdit_TaxPercentage.getText().toString())/100; dTotalBill_No_Tip = Double.parseDouble(mEdit_Bill_No_Tip.getText().toString()); dPreTax = dTotalBill_No_Tip / (1 + dTaxPercentage); NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumFractionDigits(2); mEdit_PreTax.setText(String.valueOf(nf.format(dPreTax))); dTotalTax = dPreTax * dTaxPercentage; mEdit_TotalTax.setText(String.valueOf(nf.format(dTotalTax))); if(mEdit_TipPercentage.getText().toString().length()>0) { dTipPercentage = Double.parseDouble(mEdit_TipPercentage.getText().toString())/100; if(dTipPercentage == 0.1) mRadioGroup.check(R.id.radio10); else if(dTipPercentage == 0.15) mRadioGroup.check(R.id.radio15); else if(dTipPercentage == 0.18) mRadioGroup.check(R.id.radio18); else if(dTipPercentage == 0.2) mRadioGroup.check(R.id.radio20); dTipAmount = dTipPercentage * dPreTax; mEdit_TipAmount.setText(String.valueOf(nf.format(dTipAmount))); dTotalAmount = dTotalBill_No_Tip + dTipAmount; mEdit_TotalAmount.setText(String.valueOf(nf.format(dTotalAmount))); dPerPersonAmount = dTotalAmount / iPersonNum; mEdit_PerPerson.setText(String.valueOf(nf.format(dPerPersonAmount))); } } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void afterTextChanged(Editable s) {} }); mEdit_TipPercentage.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if(mEdit_TipPercentage.getText().toString().length()>0) { dTipPercentage = Double.parseDouble(mEdit_TipPercentage.getText().toString())/100; if(dTipPercentage == 0.1) mRadioGroup.check(R.id.radio10); else if(dTipPercentage == 0.15) mRadioGroup.check(R.id.radio15); else if(dTipPercentage == 0.18) mRadioGroup.check(R.id.radio18); else if(dTipPercentage == 0.2) mRadioGroup.check(R.id.radio20); dTipAmount = dTipPercentage * dPreTax; NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumFractionDigits(2); mEdit_TipAmount.setText(String.valueOf(nf.format(dTipAmount))); dTotalAmount = dTotalBill_No_Tip + dTipAmount; mEdit_TotalAmount.setText(String.valueOf(nf.format(dTotalAmount))); dPerPersonAmount = dTotalAmount / iPersonNum; mEdit_PerPerson.setText(String.valueOf(nf.format(dPerPersonAmount))); } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override public void afterTextChanged(Editable s) {} }); mRadioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.radio10: mEdit_TipPercentage.setText("10"); dTipPercentage = 0.1; break; case R.id.radio15: mEdit_TipPercentage.setText("15"); dTipPercentage = 0.15; break; case R.id.radio18: mEdit_TipPercentage.setText("18"); dTipPercentage = 0.18; break; case R.id.radio20: mEdit_TipPercentage.setText("20"); dTipPercentage = 0.20; break; default: break; } } }); } //end findViews } //end MainActivity