Android拨打电话并获取电话状态
需求
APP可以直接拨打设置的电话号码,并且程序中对电话的状态进行监听,最后在结束电话后在页面显示呼通时间和挂断时间。
代码介绍
代码链接:Gitee
AndroidManifest中添加权限
<!-- 拨打电话的权限 -->
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<!-- 获取电话状态的权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
MainActivity中申请权限
在数组中定义要申请的权限:
//要申请的权限
final String[] permissions = new String[]{
Manifest.permission.CALL_PHONE, Manifest.permission.READ_PHONE_STATE};
检查权限是否申请的方法:
private void checkPermission() {
boolean allPermissionsGranted = true;
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
allPermissionsGranted = false;
break;
}
}
if (!allPermissionsGranted) {
// 如果没有所有的权限,请求用户授予这些权限
ActivityCompat.requestPermissions(this, permissions, REQUEST_PHONE_PERMISSIONS);
} else {
// 已经有所有的权限
}
}
权限请求结果:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PHONE_PERMISSIONS) {
boolean allPermissionsGranted = true;
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
allPermissionsGranted = false;
break;
}
}
if (allPermissionsGranted) {
// 用户已经授予了所有的权限
} else {
// 用户没有授予所有的权限
Toast.makeText(this, "需要的权限不足", Toast.LENGTH_SHORT).show();
}
}
拨打电话
检查是否有电话卡,并拨打电话:
elephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
int simState = telephonyManager.getSimState();
if (simState == TelephonyManager.SIM_STATE_ABSENT) {
// 设备没有插入SIM卡
Toast.makeText(this, "设备没有电话卡!", Toast.LENGTH_SHORT).show();
return;
}
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + phoneNumber));
startActivity(intent);
电话状态的监听:
if (telephonyManager != null) {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
private PhoneStateListener phoneStateListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
Log.e("Call===", "state: " + state);
telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: //电话挂断,是拨打电话挂断,包括接通后挂断和未接通主动挂断
// 电话挂断,重新注册PhoneStateListener
if (telephonyManager != null && !isCalling && isListen) {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
} else {
endTime = System.currentTimeMillis();
Log.d("Call===", "endTime: " + endTime);
isCallEnded = true;
isListen = false;
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK: //电话接通
if (!isCalling) {
startTime = System.currentTimeMillis();
Log.d("Call===", "startTime: " + startTime);
isCalling = true;
}
if (telephonyManager != null) {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
break;
case TelephonyManager.CALL_STATE_RINGING: //电话响铃
if (telephonyManager != null) {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
break;
}
}
};
详细代码
MainActivity
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_PHONE_PERMISSIONS = 1;
String phoneNumber = "电话";
private long startTime;
private long endTime;
private boolean isCallEnded = false;
private TextView mTel, mTelConnection, mTelHangUp;
private Button mCallPhone;
private TelephonyManager telephonyManager;
private boolean isCalling = false;
private boolean isListen = false;
//要申请的权限
final String[] permissions = new String[]{
Manifest.permission.CALL_PHONE, Manifest.permission.READ_PHONE_STATE};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
checkPermission();
}
private void init() {
mTel = findViewById(R.id.tel);
mTel.setText(phoneNumber);
mTelConnection = findViewById(R.id.tel_connection);
mTelHangUp = findViewById(R.id.tel_hang_up);
mCallPhone = findViewById(R.id.call_phone);
mCallPhone.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
isCalling = false;
isListen = true;
callPhone();
}
});
}
@Override
protected void onStart() {
super.onStart();
if (isCallEnded) {
updateTelInfo();
isCallEnded = false;
}
}
@Override
protected void onResume() {
super.onResume();
isListen = !isListen;
}
private void updateTelInfo() {
Date date = new Date(startTime);
SimpleDateFormat startData = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String startTimeFormat = startData.format(date);
mTelConnection.setText("拨通时间:" + startTimeFormat);
date = new Date(endTime);
SimpleDateFormat endData = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String endTimeFormat = endData.format(date);
mTelHangUp.setText("挂断时间:" + endTimeFormat);
}
private void callPhone() {
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
int simState = telephonyManager.getSimState();
if (simState == TelephonyManager.SIM_STATE_ABSENT) {
// 设备没有插入SIM卡
Toast.makeText(this, "设备没有电话卡!", Toast.LENGTH_SHORT).show();
return;
}
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + phoneNumber));
startActivity(intent);
if (telephonyManager != null) {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
private PhoneStateListener phoneStateListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
Log.e("Call===", "state: " + state);
telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: //电话挂断,是拨打电话挂断,包括接通后挂断和未接通主动挂断
// 电话挂断,重新注册PhoneStateListener
if (telephonyManager != null && !isCalling && isListen) {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
} else {
endTime = System.currentTimeMillis();
Log.d("Call===", "endTime: " + endTime);
isCallEnded = true;
isListen = false;
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK: //电话接通
if (!isCalling) {
startTime = System.currentTimeMillis();
Log.d("Call===", "startTime: " + startTime);
isCalling = true;
}
if (telephonyManager != null) {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
break;
case TelephonyManager.CALL_STATE_RINGING: //电话响铃
if (telephonyManager != null) {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
break;
}
}
};
private void checkPermission() {
boolean allPermissionsGranted = true;
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
allPermissionsGranted = false;
break;
}
}
if (!allPermissionsGranted) {
// 如果没有所有的权限,请求用户授予这些权限
ActivityCompat.requestPermissions(this, permissions, REQUEST_PHONE_PERMISSIONS);
} else {
// 已经有所有的权限
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PHONE_PERMISSIONS) {
boolean allPermissionsGranted = true;
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
allPermissionsGranted = false;
break;
}
}
if (allPermissionsGranted) {
// 用户已经授予了所有的权限
} else {
// 用户没有授予所有的权限
Toast.makeText(this, "需要的权限不足", Toast.LENGTH_SHORT).show();
}
}
}
}
activity_main
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="电话号码:"
app:layout_constraintBottom_toTopOf="@+id/tel_connection"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tel_connection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拨通时间:"
app:layout_constraintBottom_toTopOf="@+id/tel_hang_up"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tel" />
<TextView
android:id="@+id/tel_hang_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="挂断时间:"
app:layout_constraintBottom_toTopOf="@+id/call_phone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tel_connection" />
<Button
android:id="@+id/call_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拨打电话"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tel_hang_up" />
</androidx.constraintlayout.widget.ConstraintLayout>