2014-10-04 41 views
0

我已成功編寫了結束通話的代碼。但通話結束之前,我要檢索的呼叫者的姓名記錄它。我將如何檢索來電者的姓名?請注意,主叫方被認爲是在聯繫人列表中。在結束通話之前獲取來電者的姓名

我已經遇到過如何從來電號碼中檢索聯繫人姓名?,我沒有找到滿意的答案。它沒有上下文,信息也很少。

回答

0

您需要傳入/傳出呼叫號碼才能從設備的聯繫人列表中檢索聯繫人姓名。 定義應用程序的清單內的下列權限和接收器:

<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> 

<receiver android:name=".CallReceiver" > 
      <intent-filter android:priority="999" > 
       <action android:name="android.intent.action.PHONE_STATE" /> 
      </intent-filter> 
      <intent-filter> 
       <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> 
      </intent-filter> 
     </receiver> 

然後CallReciever類中:

public class CallReceiver extends BroadcastReceiver { 

    // The receiver will be recreated whenever android feels like it. We need a 
    // static variable to remember data between instantiations 
    static PhonecallStartEndDetector listener; 
    string contactName; 
    Context context; 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     this.context = context; 
     if (listener == null) { 
      listener = new PhonecallStartEndDetector(); 

     } 

     // We listen to two intents. The new outgoing call only tells us of an 
     // outgoing call. We use it to get the number. 
     if (intent.getAction() 
       .equals("android.intent.action.NEW_OUTGOING_CALL")) { 
      listener.setOutgoingNumber(intent.getExtras().getString(
        "android.intent.extra.PHONE_NUMBER")); 
      return; 
     } 

     // The other intent tells us the phone state changed. Here we set a 
     // listener to deal with it 
     TelephonyManager telephony = (TelephonyManager) context 
       .getSystemService(Context.TELEPHONY_SERVICE); 
     telephony.listen(listener, PhoneStateListener.LISTEN_CALL_STATE); 

    } 


    // Deals with actual events 
    public class PhonecallStartEndDetector extends PhoneStateListener { 
     int lastState = TelephonyManager.CALL_STATE_IDLE; 
     boolean isIncoming; 
     boolean isIncomingPicked; 
     boolean isOutgoingStarted; 
     String savedNumber; // because the passed incoming is only valid in ringing 

     public PhonecallStartEndDetector() { 

     } 

     // The outgoing number is only sent via a separate intent, so we need to 
     // store it out of band 
     public void setOutgoingNumber(String number) { 
      savedNumber = number; 
     } 

     // Incoming call- goes from IDLE to RINGING when it rings, to OFFHOOK 
     // when it's answered, to IDLE when its hung up 
     // Outgoing call- goes from IDLE to OFFHOOK when it dials out, to IDLE 
     // when hung up 
     @Override 
     public void onCallStateChanged(int state, String incomingNumber) { 
      super.onCallStateChanged(state, incomingNumber); 
               // state is changed 
      if (lastState == state) { 
       return; 
      } 

      switch (state) { 
      case TelephonyManager.CALL_STATE_RINGING: 
      //an incoming call has been started 

       isIncoming = true; 
       savedNumber = incomingNumber; 

      break; 
      case TelephonyManager.CALL_STATE_OFFHOOK: 

       // Transition of ringing->offhook are pickups of incoming calls. 
       // Nothing down on them 
       if (lastState != TelephonyManager.CALL_STATE_RINGING) { 
                     //if pickup but device didn't ring..it means was an outgoing call 
        isIncoming = false; 
        isIncomingPicked = false; 
        isOutgoingStarted = true; 

       } else if (lastState == TelephonyManager.CALL_STATE_RINGING) { 
                       // if pickup and device rang..it means an incoming call has been picked 

        isIncoming = true; 
        isIncomingPicked = true; 
        isOutgoingStarted = false; 

       break; 
      case TelephonyManager.CALL_STATE_IDLE: 

       // Went to idle- this is the end of a call. What type depends on 
       // previous state(s) 
       if (lastState == TelephonyManager.CALL_STATE_RINGING) { 
        // Ring but no pickup- a miss 


       }else if (isOutgoingStarted) { 
       //outgoing call ended 
       contactName = getContactName(savedNumber, context); 

       } else if (isIncoming || isIncomingPicked) { 
        //incoming call ended 
      contactName = getContactName(savedNumber, context); 

      } 
       break; 
      } 

     } 

     //method to retrieve contact name 

private String getContactName(String number, Context context) { 
     String contactNumber = ""; 

     // // define the columns I want the query to return 
     String[] projection = new String[] { 
       ContactsContract.PhoneLookup.DISPLAY_NAME, 
       ContactsContract.PhoneLookup.NUMBER, 
       ContactsContract.PhoneLookup.HAS_PHONE_NUMBER }; 

     // encode the phone number and build the filter URI 
     Uri contactUri = Uri.withAppendedPath(
       ContactsContract.PhoneLookup.CONTENT_FILTER_URI, 
       Uri.encode(number)); 

     // query time 
     Cursor cursor = context.getContentResolver().query(contactUri, 
       projection, null, null, null); 
     // querying all contacts = Cursor cursor = 
     // context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, 
     // projection, null, null, null); 

     if (cursor.moveToFirst()) { 
      contactName = cursor.getString(cursor 
        .getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME)); 
     } 
     cursor.close(); 
     return contactNumber.equals("") ? number : contactName; 

    } 

} 

既然你有興趣,當通話結束前取回來電者的姓名,我當呼入/呼出結束時檢索姓名。當來電開始或摘機或開始撥出電話時,您可以檢索來電者的姓名。我已經添加了評論作爲指導。希望它有助於:)

相關問題