APK: 拨号、广播监听电话的状态

hqulyc 2020-05-30

 一、实现手机电话状态的监听,主要依靠两个类:TelephoneManger和PhoneStateListener

1.1、TelephonseManger提供了取得手机基本服务的信息的一种方式。因此应用程序可以使用TelephonyManager来探测手机基本服务的情况。
应用程序可以注册listener来监听电话状态的改变。我们不能对TelephonyManager进行实例化,只能通过获取服务的形式:
Context.getSystemService(Context.TELEPHONY_SERVICE);
注意:对手机的某些信息进行读取是需要一定许可(permission)的。
1.2、主要静态成员常量:(它们对应PhoneStateListener.LISTEN_CALL_STATE所监听到的内容)
通过PhoneStateListener的回调方法onCallStateChanged(int state, String incomingNumber) 实现来电的监听
int CALL_STATE_IDLE 空闲状态,没有任何活动。
int CALL_STATE_OFFHOOK 摘机状态,至少有个电话活动。该活动或是拨打(dialing)或是通话,或是 on hold。并且没有电话是ringing or waiting
int CALL_STATE_RINGING 来电状态,电话铃声响起的那段时间或正在通话又来新电,新来电话不得不等待的那段时间。

二、监听来电去电能干什么?
2.1、能够对监听到的电话做个标识,告诉用户这个电话是诈骗、推销、广告什么的
2.2、能够针对那些特殊的电话进行自动挂断,避免打扰到用户

三、刀剑神域

3.1、AndroidMainfest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.gatsby.xhringupphone">

    <!--CONTACTS 联系人-->
    <!--允许程序从非系统拨号器里输入电话号码-->
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <!--允许读取手机状态的权限-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <!-- 允许程序读取用户联系人数据 -->
    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".PhoneReceiver">
            <!--android中的级别-1000~1000-->
            <intent-filter android:priority="1000">
                <action android:name="android.intent.action.PHONE_STATE" />
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

3.2、activity_main.xml

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

    <Button
        android:id="@+id/btn1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="btn1->跳转拨号应用"
        android:textSize="32sp" />

    <Button
        android:id="@+id/btn2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="btn2->直接拨号"
        android:textSize="32sp" />

</LinearLayout>

3.3、MainActivity.java 拨号

package com.gatsby.xhringupphone;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import java.io.DataInputStream;
import java.io.DataOutputStream;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    Button btn1, btn2, btn3, btn4;

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

    public void initView() {

        btn1 = (Button) findViewById(R.id.btn1);
        btn2 = (Button) findViewById(R.id.btn2);

        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.btn1:
                //跳转到拨号应用
                Uri uri = Uri.parse("tel:10086");
                Intent intent1 = new Intent(Intent.ACTION_DIAL, uri);
                startActivity(intent1);
                break;
            case R.id.btn2:
                call("10086");
                break;
        }
    }

    public void call(String number) {
        Intent intent = new Intent(Intent.ACTION_CALL);
        intent.setData(Uri.parse("tel:" + number));

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        startActivity(intent);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //RootCommand("pm clear com.android.dialer ");
    }

    private void RootCommand(String cmd) {
        Process process = null;
        DataOutputStream os = null;
        DataInputStream is = null;
        try {
            process = Runtime.getRuntime().exec("su");
            os = new DataOutputStream(process.getOutputStream());
            os.writeBytes(cmd + "\n");
            os.writeBytes("exit\n");
            os.flush();

            int aa = process.waitFor();
            is = new DataInputStream(process.getInputStream());

            byte[] buffer = new byte[is.available()];
            is.read(buffer);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (is != null) {
                    is.close();
                }
                process.destroy();
            } catch (Exception e) {
            }
        }
    }
}

3.4、PhoneReceiver.java  电话监听广播

package com.gatsby.xhringupphone;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

public class PhoneReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
            String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
            Log.d("gatsby", "call OUT:" + phoneNumber);
        } else {
            TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
            tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
        }
    }

    PhoneStateListener listener = new PhoneStateListener() {

        @Override
        public void onCallStateChanged(int state, String incomingNumber) {

            super.onCallStateChanged(state, incomingNumber);
            switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    //挂断 空闲   无任何状态时
                    Log.d("gatsby", "aaaa");
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    //接听 通话    接起电话时
                    Log.d("gatsby", "bbbb");
                    break;
                case TelephonyManager.CALL_STATE_RINGING:
                    //响铃:来电号码
                    //输出来电号码  电话进来时
                    Log.d("gatsby", "cccc");
                    break;
            }
        }
    };

}

相关推荐