Android Open Source - callerid-for-android Recent Calls Fragment






From Project

Back to project page callerid-for-android.

License

The source code is released under:

GNU General Public License

If you think the Android project callerid-for-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.integralblue.callerid;
/*from w  w w .jav  a  2s  .  c  om*/
import java.util.Locale;

import roboguice.fragment.RoboListFragment;
import roboguice.inject.InjectResource;
import roboguice.util.Ln;
import roboguice.util.RoboAsyncTask;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.CallLog.Calls;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.ResourceCursorAdapter;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

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.CallerIDLookup.NoResultException;
import com.integralblue.callerid.contacts.ContactsHelper;
import com.integralblue.callerid.inject.CountryDetector;

public class RecentCallsFragment extends RoboListFragment {
  @Inject ContactsHelper contactsHelper;
  @Inject CallerIDLookup callerIDLookup;
  @Inject
  CountryDetector countryDetector;
  
  @InjectResource(R.drawable.ic_call_log_list_incoming_call)
    Drawable drawableIncoming;
  @InjectResource(R.drawable.ic_call_log_list_outgoing_call)
    Drawable drawableOutgoing;
  @InjectResource(R.drawable.ic_call_log_list_missed_call)
    Drawable drawableMissed;
  

  @InjectResource(R.string.lookup_no_result)
  String lookupNoResult;
  @InjectResource(R.string.lookup_error)
  String lookupError;
  @InjectResource(R.string.lookup_in_progress)
  String lookupInProgress;
  @InjectResource(R.string.lookup_payphone)
  String lookupPayphone;
  @InjectResource(R.string.lookup_private)
  String lookupPrivate;
  @InjectResource(R.string.lookup_unknown)
  String lookupUnknown;
  
  private static final int CALL_LOG_LOADER = 1;
  
    static final int ID_COLUMN_INDEX = 0;
    static final int NUMBER_COLUMN_INDEX = 1;
    static final int DATE_COLUMN_INDEX = 2;
    static final int DURATION_COLUMN_INDEX = 3;
    static final int CALL_TYPE_COLUMN_INDEX = 4;
    static final int CALLER_NAME_COLUMN_INDEX = 5;
    static final int CALLER_NUMBERTYPE_COLUMN_INDEX = 6;
    static final int CALLER_NUMBERLABEL_COLUMN_INDEX = 7;
  
    static final String[] CALL_LOG_PROJECTION = new String[] {
        Calls._ID,
        Calls.NUMBER,
        Calls.DATE,
        Calls.DURATION,
        Calls.TYPE,
        Calls.CACHED_NAME,
        Calls.CACHED_NUMBER_TYPE,
        Calls.CACHED_NUMBER_LABEL
    };
    final String ORDER = android.provider.CallLog.Calls.DATE + " DESC";
  
  //keep track of if we've prompted them already. We only want to prompt the user once per run of the application.
  boolean promptedForNewVersion = false;
    
  class RecentCallsLookupAsyncTask extends RoboAsyncTask<CallerIDResult> {
    final String phoneNumber;
    final View view;
    final View callIcon;
    final ImageView callTypeIcon;
    final TextView dateView;
    final TextView labelView;
    final TextView numberView;
    final TextView line1View;
    final int callType;
    final long date;
    String offlineGeocoderResult = null;
    
    public RecentCallsLookupAsyncTask(Context context, View view, String phoneNumber, long date, int callType) {
      super(context, new Handler(context.getMainLooper()));
      this.phoneNumber = phoneNumber;
      this.view = view;
      callIcon = (View) view.findViewById(R.id.call_icon);
      callTypeIcon = (ImageView) view.findViewById(R.id.call_type_icon);
      dateView = (TextView) view.findViewById(R.id.date);
      labelView = (TextView) view.findViewById(R.id.label);
      numberView = (TextView) view.findViewById(R.id.number);
      line1View = (TextView) view.findViewById(R.id.line1);
      this.date = date;
      this.callType = callType;
    }
    @Override
    protected void onSuccess(CallerIDResult result)
        throws Exception {
      super.onSuccess(result);
      
      line1View.setText(result.getName());
      labelView.setText("");
    }
    @Override
    public void execute() {
      // Overriding executive seems weird... here's why I do it:
      // The background task (and its related preExecute/success/... handlers)
      // should only be called when a background lookup is necessary.
      // In the case of "special" numbers (payphone, unknown, and private)
      // any further lookup is unnecessary and not desired, but other
      // setup (like displaying the right icon and right text) is.
      // By overriding execute() and only calling super.execute() when
      // a background lookup should be done, that goal can be achieved.
      
      // Set the date/time field by mixing relative and absolute times.
      dateView.setText(
          DateUtils.getRelativeTimeSpanString(
              date,
              System.currentTimeMillis(), 
              DateUtils.MINUTE_IN_MILLIS, 
              DateUtils.FORMAT_ABBREV_RELATIVE));
      
            // Set the icon
            switch (callType) {
                case Calls.INCOMING_TYPE:
                  callTypeIcon.setImageDrawable(drawableIncoming);
                    break;
                case Calls.OUTGOING_TYPE:
                  callTypeIcon.setImageDrawable(drawableOutgoing);
                    break;
                case Calls.MISSED_TYPE:
                  callTypeIcon.setImageDrawable(drawableMissed);
                    break;
            }
            
            if(TextUtils.isEmpty(phoneNumber) || SpecialPhoneNumbers.UNKNOWN_NUMBER.equals(phoneNumber)){
                callIcon.setOnClickListener(null);
                numberView.setText("");
                line1View.setText(lookupUnknown);
                labelView.setText("");
            }else if(SpecialPhoneNumbers.PRIVATE_NUMBER.equals(phoneNumber)){
                callIcon.setOnClickListener(null);
                numberView.setText("");
                line1View.setText(lookupPrivate);
                labelView.setText("");
            }else if(SpecialPhoneNumbers.PAYPHONE_NUMBER.equals(phoneNumber)){
                callIcon.setOnClickListener(null);
                numberView.setText("");
                line1View.setText(lookupPayphone);
                labelView.setText("");
            }else{
        numberView.setText(PhoneNumberUtils.formatNumber(phoneNumber));
        
        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){
          labelView.setText(lookupInProgress);
          line1View.setText("");
        }else{
          line1View.setText(offlineGeocoderResult);
          labelView.setText("");
        }
               
               callIcon.setOnClickListener(new View.OnClickListener() {
          public void onClick(View v) {
                     Uri callUri;
                     if (CallerIDApplication.isUriNumber(phoneNumber)) {
                         callUri = Uri.fromParts("sip", phoneNumber, null);
                     } else {
                         callUri = Uri.fromParts("tel", phoneNumber, null);
                     }
                     startActivity(new Intent(Intent.ACTION_CALL,callUri));
          }
        });
               
              super.execute();
            }
    }
    @Override
    protected void onException(Exception e) throws RuntimeException {
      if (e instanceof CallerIDLookup.NoResultException) {
        if(offlineGeocoderResult == null){
          line1View.setText(lookupNoResult);
        }else{
          // We're already displaying the offline geolocation results... so just leave that there.
        }
      } else {
        Ln.e(e);
        if(offlineGeocoderResult == null){
          line1View.setText(lookupError);
        }else{
          // We're already displaying the offline geolocation results... so just leave that there.
        }
      }
      labelView.setText("");
    }
    public CallerIDResult call() throws Exception {
      CallerIDResult result;
      try{
        result = contactsHelper.getContact(phoneNumber.toString());
      }catch(NoResultException e){
        // not a phone number in the local contacts database, so time to query the web service
        
        result = callerIDLookup.lookup(phoneNumber);
      }
      
      return result;
    }
  }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        
        
        final ResourceCursorAdapter adapter = new ResourceCursorAdapter(getActivity().getApplicationContext(),R.layout.recent_calls_list_item, null, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER) {
      @Override
      public void bindView(View view, Context context, Cursor cursor) {
        new RecentCallsLookupAsyncTask(
            getActivity(),
            view,
            cursor.getString(NUMBER_COLUMN_INDEX),
            cursor.getLong(DATE_COLUMN_INDEX),
            cursor.getInt(CALL_TYPE_COLUMN_INDEX)).execute();
      }
    };
    
    setListAdapter(adapter);
        
        getLoaderManager().initLoader(CALL_LOG_LOADER, null, new LoaderManager.LoaderCallbacks<Cursor>(){

      public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new CursorLoader(getActivity(),
            android.provider.CallLog.Calls.CONTENT_URI, CALL_LOG_PROJECTION, null, null, ORDER);
      }

      public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        adapter.swapCursor(data);
      }

      public void onLoaderReset(Loader<Cursor> loader) {
        adapter.swapCursor(null);
      }
          
        });
    }

  @Override
  public void onListItemClick(ListView l, View v, int position, long id) {
    // TODO Auto-generated method stub
    super.onListItemClick(l, v, position, id);
    
    final Cursor cursor = (Cursor) getListAdapter().getItem(position);
    final Intent lookupIntent = new Intent(getActivity().getApplicationContext(), MainActivity.class);
    lookupIntent.putExtra("phoneNumber", cursor.getString(NUMBER_COLUMN_INDEX));
    startActivity(lookupIntent);
  }
    
    
}




Java Source Code List

com.blundell.tut.LoaderImageView.java
com.integralblue.callerid.CallerIDApplication.java
com.integralblue.callerid.CallerIDBroadcastReceiver.java
com.integralblue.callerid.CallerIDLookup.java
com.integralblue.callerid.CallerIDResult.java
com.integralblue.callerid.CallerIDService.java
com.integralblue.callerid.GeocoderAsyncTask.java
com.integralblue.callerid.HttpCallerIDLookup.java
com.integralblue.callerid.LookupAsyncTask.java
com.integralblue.callerid.LookupFragment.java
com.integralblue.callerid.MainActivity.java
com.integralblue.callerid.PreferencesActivity.java
com.integralblue.callerid.RecentCallsFragment.java
com.integralblue.callerid.SpecialPhoneNumbers.java
com.integralblue.callerid.TabsAdapter.java
com.integralblue.callerid.contacts.ContactsHelper.java
com.integralblue.callerid.contacts.NewContactsHelper.java
com.integralblue.callerid.contacts.OldContactsHelper.java
com.integralblue.callerid.geocoder.AndroidGeocoder.java
com.integralblue.callerid.geocoder.Geocoder.java
com.integralblue.callerid.geocoder.NominatimGeocoder.java
com.integralblue.callerid.inject.CallerIDModule.java
com.integralblue.callerid.inject.ContactsHelperProvider.java
com.integralblue.callerid.inject.CountryDetector.java
com.integralblue.callerid.inject.GeocoderHelperProvider.java
com.integralblue.callerid.inject.PreferencesNameProvider.java
com.integralblue.callerid.inject.RestTemplateProvider.java
com.integralblue.callerid.inject.TextToSpeechHelper.java
com.integralblue.callerid.inject.VersionInformationHelper.java
com.integralblue.callerid.widget.DontPressWithParentImageView.java
com.squareup.okhttp.OkHttpURLStreamHandlerFactory.java
com.squareup.okhttp.internal.OkHttpClientHandler.java