在结束通话之前获取来电者的姓名

问题描述:

我已成功编写了结束通话的代码。但通话结束之前,我要检索的呼叫者的姓名记录它。我将如何检索来电者的姓名?请注意,主叫方被认为是在联系人列表中。在结束通话之前获取来电者的姓名

我已经遇到过如何从来电号码中检索联系人姓名?,我没有找到满意的答案。它没有上下文,信息也很少。

您需要传入/传出呼叫号码才能从设备的联系人列表中检索联系人姓名。 定义应用程序的清单内的下列权限和接收器:

<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; 

    } 

} 

既然你有兴趣,当通话结束前取回来电者的姓名,我当呼入/呼出结束时检索姓名。当来电开始或摘机或开始拨出电话时,您可以检索来电者的姓名。我已经添加了评论作为指导。希望它有助于:)