产品提了一个人让人头大的项目,让人很郁闷,让判断用户打电话是否打通,这让我好生郁闷,我记得Android里面好像有对来电有状态的判断,而对去电没有吧。还是说我孤陋寡闻了,赶紧上网找资料,找了好半天,终于找到了一些相关的资料。好了,废话不多说,直接来看看怎么实现的吧。
首先用广播监听,(这里补充一点,不会广播的孩子,可以看看广播的相关资料,这里不多说),具体的代码实现如下:
PhonecallReceiver.java文件
public abstract class PhonecallReceiver extends BroadcastReceiver {
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
private static Date callStartTime;
private static boolean isIncoming;
private static String savedNumber;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
Log.e("TAG","===savedNumber==="+savedNumber);
}
else{
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)){
state = TelephonyManager.CALL_STATE_IDLE;
}
else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
state = TelephonyManager.CALL_STATE_OFFHOOK;
}
else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){
state = TelephonyManager.CALL_STATE_RINGING;
}
onCallStateChanged(context, state, number);
}
}
protected abstract void onIncomingCallReceived(Context ctx, String number, Date start);
protected abstract void onIncomingCallAnswered(Context ctx, String number, Date start);
protected abstract void onIncomingCallEnded(Context ctx, String number, Date start, Date end);
protected abstract void onOutgoingCallStarted(Context ctx, String number, Date start);
protected abstract void onOutgoingCallEnded(Context ctx, String number, Date start, Date end);
protected abstract void onMissedCall(Context ctx, String number, Date start);
public void onCallStateChanged(Context context, int state, String number) {
if(lastState == state){
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
callStartTime = new Date();
savedNumber = number;
onIncomingCallReceived(context, number, callStartTime);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if(lastState != TelephonyManager.CALL_STATE_RINGING){
isIncoming = false;
callStartTime = new Date();
onOutgoingCallStarted(context, savedNumber, callStartTime);
}
else
{
isIncoming = true;
callStartTime = new Date();
onIncomingCallAnswered(context, savedNumber, callStartTime);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if(lastState == TelephonyManager.CALL_STATE_RINGING){
onMissedCall(context, savedNumber, callStartTime);
}
else if(isIncoming){
onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
}
else{
onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());
}
break;
}
lastState = state;
}
}
具体的的在开发中直接继承这个抽象类就OK,看看下面的具体实现。
CallReceiver.java 文件
public class CallReceiver extends PhonecallReceiver {
@Override
protected void onIncomingCallReceived(Context ctx, String number, Date start) {
}
@Override
protected void onIncomingCallAnswered(Context ctx, String number, Date start) {
}
@Override
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {
}
@Override
protected void onOutgoingCallStarted(Context ctx, String number, Date start) {
}
@Override
protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {
}
@Override
protected void onMissedCall(Context ctx, String number, Date start) {
}
}
如果,有的同学需要对,拨打电话的状态监听录音,可以根据自己的需求来实现录音功能,下面给出录音的代码。
public class CustomRecorder {
private String phoneNumber;
private MediaRecorder mrecorder;
private boolean started = false;
private boolean isCommingNumber = false;
private String TAG = "Recorder";
public CustomRecorder(String phoneNumber) {
this.setPhoneNumber(phoneNumber);
}
public CustomRecorder() {
}
public void start() {
started = true;
mrecorder = new MediaRecorder();
File recordPath = new File(
Environment.getExternalStorageDirectory()
, "/CustomRecorder");
if (!recordPath.exists()) {
recordPath.mkdirs();
Log.d("recorder", "创建目录");
}
String callDir = "呼出";
if (isCommingNumber) {
callDir = "呼入";
}
String fileName = callDir + "-" + phoneNumber + "-"
+ new SimpleDateFormat("yy-MM-dd_HH-mm-ss")
.format(new Date(System.currentTimeMillis())) + ".mp3";
File recordName = new File(recordPath, fileName);
try {
recordName.createNewFile();
Log.d("recorder", "创建文件" + recordName.getName());
} catch (IOException e) {
e.printStackTrace();
}
mrecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mrecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mrecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mrecorder.setOutputFile(recordName.getAbsolutePath());
try {
mrecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mrecorder.start();
started = true;
Log.d(TAG , "录音开始");
}
public void stop() {
try {
if (mrecorder!=null) {
mrecorder.stop();
mrecorder.release();
mrecorder = null;
}
started = false;
} catch (IllegalStateException e) {
e.printStackTrace();
}
Log.d(TAG , "录音结束");
}
public void pause() {
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public boolean isStarted() {
return started;
}
public void setStarted(boolean hasStarted) {
this.started = hasStarted;
}
public boolean isCommingNumber() {
return isCommingNumber;
}
public void setIsCommingNumber(boolean isCommingNumber) {
this.isCommingNumber = isCommingNumber;
}
}
下面主要的是权限问题,直接在AndroidManifest.xml文件中加入相关的代码。
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
前面说了一大堆东西,主要的还没有完成,是什么呢???
当然是广播的注册呀,主要的注册都没有,怎么监听啊,对吧,看下面吧。
<receiver android:name=".receiver.CallReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
intent-filter>
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
intent-filter>
receiver>
最后,需要在activity里面做相关的打电话操作,算了,也就这么几行代码,也弄出来吧,方便后面学习的人参考。
// 检查是否获得了权限(Android6.0运行时权限)
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
// 没有获得授权,申请授权
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.CALL_PHONE)) {
Toast.makeText(MainActivity.this, "请授权!", Toast.LENGTH_LONG).show()
// 帮跳转到该应用的设置界面,让用户手动授权
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
Uri uri = Uri.fromParts("package", getPackageName(), null)
intent.setData(uri)
startActivity(intent)
} else {
// 不需要解释为何需要该权限,直接请求授权
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE)
}
} else {
CallPhone()
Intent intent = new Intent()
intent.setAction(Intent.ACTION_CALL)
intent.setData(Uri.parse("tel:" + "你的电话号码"))
startActivity(intent)
}
好了,到此就算结束了,希望能帮到各位啊,
欢迎大家发表意见。