Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在以编程方式结束调用之前获取传入调用方的名称_Java_Android_Android Intent - Fatal编程技术网

Java 在以编程方式结束调用之前获取传入调用方的名称

Java 在以编程方式结束调用之前获取传入调用方的名称,java,android,android-intent,Java,Android,Android Intent,我已经成功地以编程方式编写了结束调用的代码。但是在调用结束之前,我想检索调用方的名称以记录它。我如何检索来电者的姓名?注意,来电者被假定在联系人列表中 我已经遇到过了,我没有找到令人满意的答案。它没有上下文,信息也很少。您需要呼入/呼出的电话号码来从设备的联系人列表中检索联系人姓名。 在应用程序清单中定义以下权限和接收者: <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-p

我已经成功地以编程方式编写了结束调用的代码。但是在调用结束之前,我想检索调用方的名称以记录它。我如何检索来电者的姓名?注意,来电者被假定在联系人列表中


我已经遇到过了,我没有找到令人满意的答案。它没有上下文,信息也很少。

您需要呼入/呼出的电话号码来从设备的联系人列表中检索联系人姓名。 在应用程序清单中定义以下权限和接收者:

<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>
因为您感兴趣的是在通话结束前检索呼叫者的姓名,所以我在呼入/呼出通话结束时检索呼叫者的姓名。您可以在启动或接听来电或启动拨出电话时检索呼叫者的姓名。我添加了一些评论作为指导。希望有帮助:)

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;

    }

}