Android 获取来电号码和去电号码

版权声明:本文为 like_program 原创文章,未经博主允许不得转载。 https://blog.csdn.net/like_program/article/details/52662942

转载请注明出处: http://blog.csdn.net/like_program/article/details/52662942

这篇博客将讲解 Android 如何获取来电号码和去电号码。

打开 Android Studio,新建 PhoneNumberTest 项目。

我们先实现 获取来电号码。

先修改下布局文件, activity_main.xml 代码如下:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.phonenumbertest.MainActivity">

    <Button
        android:id="@+id/btn_incoming_call"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="获取来电号码"/>

    <Button
        android:id="@+id/btn_incoming_call_cancel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="不获取来电号码"/>
</LinearLayout>

布局文件很简单,就是定义了两个按钮,分别用来 获取来电号码不获取来电号码

然后,我们在 MainActivity 中实例化这两个按钮,并为它们设置按键监听。MainActivty.java 代码如下:

package com.example.phonenumbertest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    /**
     * 获取来电号码
     */
    private Button btnIncomingCall;

    /**
     * 不获取来电号码
     */
    private Button btnIncomingCallCancel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 实例化控件
        btnIncomingCall = (Button) findViewById(R.id.btn_incoming_call);
        btnIncomingCallCancel = (Button) findViewById(R.id.btn_incoming_call_cancel);

        // 设置按键监听
        btnIncomingCall.setOnClickListener(this);
        btnIncomingCallCancel.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_incoming_call:
                Intent startIncomingService = new Intent(this, IncomingCallService.class);
                startService(startIncomingService);
                Toast.makeText(this, "获取来电号码", Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_incoming_call_cancel:
                Intent stopIncomingService = new Intent(this, IncomingCallService.class);
                stopService(stopIncomingService);
                Toast.makeText(this, "不获取来电号码", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

然后我们新建一个 IncomingCallService.java ,继承自 Service。在这个 Service 中,我们将实现获取来电号码的逻辑。IncomingCallService.java 代码如下:

package com.example.phonenumbertest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;

/**
 * 获取来电号码服务
 */
public class IncomingCallService extends Service {

    /**
     * 电话服务管理器
     */
    private TelephonyManager telephonyManager;

    /**
     * 电话状态监听器
     */
    private MyPhoneStateListener myPhoneStateListener;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        // 获取来电号码
        getIncomingCall();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 不获取来电号码
        getIncomingCallCancel();
    }

    /**
     * 获取来电号码
     */
    private void getIncomingCall() {
        // 获取电话系统服务
        telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        myPhoneStateListener = new MyPhoneStateListener();
        telephonyManager.listen(myPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    /**
     * 不获取来电号码
     */
    private void getIncomingCallCancel() {
        telephonyManager.listen(myPhoneStateListener, PhoneStateListener.LISTEN_NONE);
    }

    /**
     * 电话状态监听器
     */
    class MyPhoneStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
            switch (state) {
                // 如果电话铃响
                case TelephonyManager.CALL_STATE_RINGING:
                    Toast.makeText(IncomingCallService.this, "来电号码是:" + incomingNumber, Toast
                            .LENGTH_LONG).show();
            }
        }
    }
}

我们可以看到,实现获取来电号码的逻辑并不复杂,在 onCreate() 方法中,我们调用了 getIncomingCall() 来获取来电号码,我们再到 getIncomingCall() 方法里看看,在 getIncomingCall() 中,我们先获取了电话系统服务(TelephonyManager),然后给电话系统服务(TelephonyManager)设置了一个监听器,这里我们设置的监听器是我们自定义的监听器,继承自 PhoneStateListener ,并且我们重写了 onCallStateChanged() 这个方法,当电话状态发生变化的时候就会回调这个方法。

注意:onCallStateChanged() 方法里有一个参数:incomingNumber 这个参数就是 来电号码,知道了这个,就好办了。

在 onCallStateChanged() 方法里,我们对当前的电话状态进行判断,如果当前的电话状态是 电话铃响 ,就弹出 Toast 提示,并把 来电号码(incomingNumber)显示出来。

还要注意一点,获取来电号码需要 READ_PHONE_STATE 权限:

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

以上就是获取来电号码的逻辑,我们再看下 不获取来电号码 的逻辑。在 onDestroy() 方法中,我们调用了 getIncomingCallCancel() 来 不获取来电号码,这个方法里只有一句代码,telephonyManager.listen(myPhoneStateListener, PhoneStateListener.LISTEN_NONE) ,这句代码的作用是 取消注册监听器,也就是把我们刚刚设置的电话状态监听器取消掉。这样,自然就获取不到来电号码了。

运行一下程序:

获取来电号码

不获取来电号码

实现了获取来电号码后,我们再来实现获取去电号码。

先修改布局文件,activity_main.xml 代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.phonenumbertest.MainActivity">

    ......

    <Button
        android:id="@+id/btn_outgoing_call"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="获取去电号码"/>

    <Button
        android:id="@+id/btn_outgoing_call_cancel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="不获取去电号码"/>
</LinearLayout>

在布局里,我们新增了两个按钮,分别是 获取去电号码不获取去电号码

然后,我们在 MainActivity 中实例化新增的两个按钮,并为它们设置按键监听。MainActivty.java 代码如下:

package com.example.phonenumbertest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    ......

    /**
     * 获取去电号码
     */
    private Button btnOutgoingcall;

    /**
     * 不获取去电号码
     */
    private Button btnOutgoingCallCancel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 实例化控件
        ......
        btnOutgoingcall = (Button) findViewById(R.id.btn_outgoing_call);
        btnOutgoingCallCancel = (Button) findViewById(R.id.btn_outgoing_call_cancel);

        // 设置按键监听
        ......
        btnOutgoingcall.setOnClickListener(this);
        btnOutgoingCallCancel.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_incoming_call:
                ......
                break;
            case R.id.btn_incoming_call_cancel:
                ......
                break;
            case R.id.btn_outgoing_call:
                Intent startOutgoingService = new Intent(this, OutgoingCallService.class);
                startService(startOutgoingService);
                Toast.makeText(this, "获取去电号码", Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_outgoing_call_cancel:
                Intent stopOutgoingService = new Intent(this, OutgoingCallService.class);
                stopService(stopOutgoingService);
                Toast.makeText(this, "不获取去电号码", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

然后我们新建一个 OutgoingCallService.java ,继承自 Service。在这个 Service 中,我们将实现获取去电号码的逻辑。OutgoingCallService.java 代码如下:

package com.example.phonenumbertest;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.widget.Toast;

/**
 * 获取去电号码服务
 */
public class OutgoingCallService extends Service {

    /**
     * 去电 Action
     */
    private static final String OUTGOING_ACTION = "android.intent.action.NEW_OUTGOING_CALL";

    /**
     * 去电广播接收器
     */
    private MyPhoneStateReceiver myPhoneStateReceiver;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        // 获取去电号码
        getOutgoingCall();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 不获取去电号码
        getOutgoingCallCancel();
    }

    /**
     * 获取去电号码
     */
    private void getOutgoingCall() {
        IntentFilter intentFilter = new IntentFilter();
        // 监听去电广播
        intentFilter.addAction(OUTGOING_ACTION);
        myPhoneStateReceiver = new MyPhoneStateReceiver();
        // 动态注册去电广播接收器
        registerReceiver(myPhoneStateReceiver, intentFilter);
    }

    /**
     * 不获取去电号码
     */
    private void getOutgoingCallCancel() {
        // 取消注册去电广播接收器
        unregisterReceiver(myPhoneStateReceiver);
    }

    /**
     * 监听去电广播
     */
    class MyPhoneStateReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // 获取去电号码
            String outgoingNumber = getResultData();
            Toast.makeText(context, "去电号码是:" + outgoingNumber, Toast.LENGTH_LONG).show();
        }
    }
}

在 onCreate() 方法中,我们调用 getOutgoingCall() 来获取去电号码,我们再到 getOutgoingCall() 方法里看看,在这个方法里,我们动态注册了 去电广播接收器 ,我们注册的广播接收器 MyPhoneStateReceiver 是我们自定义的广播接收器,在 MyPhoneStateReceiver 的 onReceive() 方法中,调用了 getResultData() 方法,这个方法返回的就是 去电号码。在 intentFilter 中,添加了一个值为 android.intent.action.NEW_OUTGOING_CALL 的 Action,表示我们的 去电广播接收器 想要接收去电广播。

获取来电号码需要权限,获取去电号码也需要权限:

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

这样,获取去电号码的逻辑就完成了。我们再看下 不获取去电号码。在 onDestroy() 方法中,调用了 getOutgoingCallCancel() 来 不获取去电号码,再到 getOutgoingCallCancel() 方法里看看,只有一句代码,unregisterReceiver(myPhoneStateReceiver),这句代码的作用是 取消注册去电广播接收器,取消注册了之后,自然也就获取不到去电号码了

再运行一下程序:

获取去电号码

不获取去电号码

源码下载

猜你喜欢

转载自blog.csdn.net/like_program/article/details/52662942