簡體   English   中英

在以編程方式結束通話之前獲取來電者的姓名

[英]Get the name of the incoming caller before programmatically ending the call

我已經成功編寫了以編程方式結束調用的代碼。 但是在通話結束之前,我想檢索來電者的姓名以進行記錄。 我將如何檢索來電者的姓名? 請注意,假定呼叫者在聯系人列表中。

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

您需要撥入/撥出電話號碼才能從設備的聯系人列表中檢索聯系人姓名。 在應用程序的清單中定義以下權限和接收器:

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

    }

}

由於您有興趣在通話結束前檢索來電者的姓名,因此我會在來電/去電結束時檢索姓名。 您可以在來電或接聽來電或撥出電話時檢索來電者姓名。 我添加了評論作為指導。 希望能幫助到你 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM