我已成功编写代码以结束调用programaticaly。但在呼叫结束之前,我想检索呼叫者的姓名以记录它。我该如何检索来电者的姓名?请注意,调用者被假定在联系人列表中。
我已经遇到过如何从来电号码中检索联系人姓名?我没有找到满意的答案。它没有上下文,信息也很少。
答案 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;
}
}
由于您对在呼叫结束前检索呼叫者姓名感兴趣,因此在呼入/呼出结束时检索该名称。您可以在启动或接听来电或启动拨出电话时检索来电者的姓名。我添加了评论作为指南。希望它有所帮助:)