APK: 拨号、广播监听电话的状态
一、实现手机电话状态的监听,主要依靠两个类: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; } } }; }