package com.integralblue.callerid; import java.util.Locale; import org.osmdroid.util.GeoPoint; import org.osmdroid.views.MapView; import roboguice.util.Ln; import roboguice.util.RoboAsyncTask; import android.content.Context; import android.content.SharedPreferences; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.blundell.tut.LoaderImageView; import com.google.i18n.phonenumbers.NumberParseException; import com.google.i18n.phonenumbers.PhoneNumberUtil; import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder; import com.google.inject.Inject; import com.integralblue.callerid.inject.CountryDetector; import com.integralblue.callerid.inject.VersionInformationHelper; public class LookupAsyncTask extends RoboAsyncTask<CallerIDResult> { String offlineGeocoderResult = null; @Inject CallerIDApplication callerIDApplication; @Inject SharedPreferences preferences; final CharSequence phoneNumber; final ViewGroup layout; final TextView text; final TextView address; final LoaderImageView image; final String lookupNoResult; final String lookupError; final String lookupInProgress; final boolean showMap; @Inject LayoutInflater layoutInflater; protected GeocoderAsyncTask geocoderAsyncTask = null; @Inject CallerIDLookup callerIDLookup; @Inject VersionInformationHelper versionInformationHelper; @Inject CountryDetector countryDetector; public LookupAsyncTask(Context context, CharSequence phoneNumber, ViewGroup layout, boolean showMap) { super(context); this.layout = layout; this.phoneNumber = phoneNumber; this.showMap = showMap; text = (TextView) layout.findViewById(R.id.text); address = (TextView) layout.findViewById(R.id.address); image = (LoaderImageView) layout.findViewById(R.id.image); lookupNoResult = context.getString(R.string.lookup_no_result); lookupError = context.getString(R.string.lookup_error); lookupInProgress = context.getString(R.string.lookup_in_progress); } public CallerIDResult call() throws Exception { CallerIDResult result = callerIDLookup.lookup(phoneNumber); if(result.getLatestAndroidVersionCode()!=null){ //got version info from the server versionInformationHelper.setLatestVersionCode(result.getLatestAndroidVersionCode()); } return result; } /** * Returns <tt>true</tt> if this task was cancelled before it completed * normally. * * Request to add this to Roboguice: https://code.google.com/p/roboguice/issues/detail?id=210 * * @return <tt>true</tt> if task was cancelled before it completed * * @see #cancel(boolean) */ public boolean isCancelled(){ return future == null ? false : future.isCancelled(); } @Override protected void onPreExecute() throws Exception { super.onPreExecute(); address.setVisibility(View.GONE); if(layout.findViewById(R.id.map_view)!=null) layout.findViewById(R.id.map_view).setVisibility(View.GONE); image.setVisibility(View.VISIBLE); text.setVisibility(View.VISIBLE); final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance(); try{ final PhoneNumber phoneNumberPhoneNumber = phoneNumberUtil.parse(phoneNumber.toString(), countryDetector.getCountry()); final PhoneNumberOfflineGeocoder phoneNumberOfflineGeocoder = PhoneNumberOfflineGeocoder.getInstance(); offlineGeocoderResult = phoneNumberOfflineGeocoder.getDescriptionForNumber(phoneNumberPhoneNumber, Locale.getDefault()); }catch(NumberParseException e){ //ignore this exception } if("".equals(offlineGeocoderResult)) offlineGeocoderResult = null; if(offlineGeocoderResult == null) text.setText(lookupInProgress); else text.setText(offlineGeocoderResult); image.spin(); } @Override protected void onSuccess(CallerIDResult result) throws Exception { super.onSuccess(result); // since we're about to start a new lookup, // we want to cancel any lookups in progress if (geocoderAsyncTask != null) geocoderAsyncTask.cancel(true); if(isCancelled()) return; //don't do any UI things if the task was cancelled if(result.getAddress()==null){ address.setVisibility(View.GONE); }else{ address.setText(result.getAddress()); if(result.getName().equals(result.getAddress())) //when the name and address are the same, there's no reason to say the same thing twice address.setVisibility(View.GONE); else address.setVisibility(View.VISIBLE); MapView mapView = (MapView) layout.findViewById(R.id.map_view); if(showMap){ if(result.getLatitude()!=null && result.getLongitude()!=null){ if(mapView == null){ LayoutInflater.from(getContext()).inflate(R.layout.map, layout, true); mapView = (MapView) layout.findViewById(R.id.map_view); mapView.setBuiltInZoomControls(true); } mapView.getController().setZoom(16); mapView.getController().setCenter(new GeoPoint(result.getLatitude(),result.getLongitude())); mapView.setVisibility(View.VISIBLE); }else{ geocoderAsyncTask = new GeocoderAsyncTask(getContext(),result.getAddress(),layout); geocoderAsyncTask.execute(); } } } image.setImageDrawable(null); text.setText(result.getName()); } @Override protected void onException(Exception e) throws RuntimeException { // since we're about to start a new lookup, // we want to cancel any lookups in progress if (geocoderAsyncTask != null) geocoderAsyncTask.cancel(true); if(isCancelled()) return; //don't do any UI things if the task was cancelled if (e instanceof CallerIDLookup.NoResultException) { if(offlineGeocoderResult == null){ text.setText(lookupNoResult); }else{ // We're already displaying the offline geolocation results... so just leave that there. if(showMap){ geocoderAsyncTask = new GeocoderAsyncTask(getContext(),offlineGeocoderResult,layout); geocoderAsyncTask.execute(); } } } else { Ln.e(e); if(offlineGeocoderResult == null){ text.setText(lookupError); }else{ // We're already displaying the offline geolocation results... so just leave that there. if(showMap){ geocoderAsyncTask = new GeocoderAsyncTask(getContext(),offlineGeocoderResult,layout); geocoderAsyncTask.execute(); } } } address.setVisibility(View.GONE); if(layout.findViewById(R.id.map_view)!=null) layout.findViewById(R.id.map_view).setVisibility(View.GONE); image.setImageDrawable(null); } @Override protected void onInterrupted(Exception e) { // intentionally not calling the super, as that calls onException(e), and that's not what we want // super.onInterrupted(e); // if there's a geocoder lookup in progress, we should cancel that, too if (geocoderAsyncTask != null) geocoderAsyncTask.cancel(true); address.setVisibility(View.GONE); if(layout.findViewById(R.id.map_view)!=null) layout.findViewById(R.id.map_view).setVisibility(View.GONE); image.setVisibility(View.GONE); text.setVisibility(View.GONE); } };