Android电话录音文件
本人最近开发电话软件,大概是通过pc分发指令,实现电话拨打,挂机,录音文件上传功能,说起来是和简单,实际还是遇到很多问题,现在贴出来,与猿友一起共勉。
问题一:实现自动拨打电话,有人认为只能最多实现跳转到拨号界面,这是不可能的,现在跳转到拨号界面,并自动拨号的方式,前提要动态申请权限哦
/**
* 拨打电话(直接拨打电话
*
* @param context
* @param phoneNum 电话号码
*/
public void callPhone(Context context, String phoneNum) {
Intent intent = new Intent(Intent.ACTION_CALL);
Uri data = Uri.parse("tel:" + phoneNum);
intent.setData(data);
context.startActivity(intent);
}
问题二:自动挂断电话,这个东西由于Android系统设有安全权限,只能通过aidl拿到权限,新建aidl文件,此时要注意路径,
package com.android.internal.telephony;
/**
* Interface used to interact with the phone. Mostly this is used by the
* TelephonyManager class. A few places are still using this directly.
* Please clean them up if possible and use TelephonyManager instead.
* {@hide}
*/
interface ITelephony {
/**
* End call or go to the Home screen
* @return whether it hung up
*/
boolean endCall();
}
public void endCallnew() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, RemoteException {
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Class clazz = Class.forName(telephonyManager.getClass().getName());
Method method = clazz.getDeclaredMethod("getITelephony");
method.setAccessible(true);
ITelephony telephonyService = (ITelephony) method.invoke(telephonyManager);
telephonyService.endCall();
}
如果你这样写可能就是没有办法适配9.0,这个9.0适配也是找了很久,有个哥们说看到谷歌说是这样解决的。完整的解决方案应该是这样的
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private boolean cutTheCall() {
TelecomManager telecomManager = (TelecomManager) getApplicationContext().getSystemService(TELECOM_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED || telecomManager == null) {
return false;
}
if (telecomManager.isInCall()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
telecomManager.endCall();
} else {
try {
endCallnew();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
return true;
}
问题四:获取录音文件,这个可是要剑走偏锋了,因为开始Android录音功能,这样只能听到我方的录音,听不到对方录音,但是用户开启自动录音功能(每个手机都有录音功能),或者手动打开录用功能,通过获取手机型号就能拿到指定路径下的录音文件,比如你录音完成时候,系统会提醒你录音文件保存的位置,找文件,上传肯定没问题了。
public String getPath() {
s.clear();
Path.clear();
File parent = Environment.getExternalStorageDirectory();
File child;
switch (getDeviceBrand().toUpperCase()) {
case "HUAWEI":
// child = new File(parent, "record");
child = new File(parent, "Sounds/CallRecord/");
break;
case "XIAOMI":
child = new File(parent, "MIUI/sound_recorder/call_rec");
// child = new File(parent, "MIUI/sound_recorder");
break;
case "MEIZU":
child = new File(parent, "Recorder");
break;
case "OPPO":
child = new File(parent, "Recordings/Call Recordings");
break;
case "VIVO":
child = new File(parent, "Record/Call");
break;
case "SAMSUNG":
child = new File(parent, "Sounds");
break;
default:
child = new File(parent, "");
break;
}
return child.getPath();
}
问题五:监听电话状态,比如来电,去电,常用的方式是通过server开启广播,通过继承PhoneStateListener,复写onCallStateChanged函数,根据 super.onCallStateChanged(state, phoneNumber);状态来判定电话状态
public class CallListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String phoneNumber) {
super.onCallStateChanged(state, phoneNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE://通话状态空闲
break;
case TelephonyManager.CALL_STATE_OFFHOOK://通话状态摘机
break;
case TelephonyManager.CALL_STATE_RINGING://呼叫状态振铃
break;
}
}
}
但是这种方案一般是完全没问题,如果对方是没有开启来电显示呢,onCallStateChanged这个函数中的来电号码就会报空指针异常了,鄙人采用这种方式监听来电,也不用server,节省资源,不容被系统杀死,这样绕过了获取来电导致的异常,一举两得
package com.example.phoneproject.common.phoneing;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;
import com.example.phoneproject.common.EventPhone;
import com.example.phoneproject.common.GetMessagePhone;
import org.greenrobot.eventbus.EventBus;
/**
* author : Liuyh
* date : 2020/9/7 13:49
* description :
* ************************************************
* Update author :
* Update time :
* Update description :
*/
public class PhoneReceiver extends BroadcastReceiver {
private Context mContext;
public static boolean isZhujiaoTonghua = false;//主叫通话
@Override
public void onReceive(Context context, Intent intent) {
// System.out.println("actionSSSSS" + intent.getAction());
String action = intent.getAction();
this.mContext = context;
if (action.equalsIgnoreCase(Intent.ACTION_NEW_OUTGOING_CALL)) {//判断来电还是去电
//获得相应的系统服务
TelephonyManager tm = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
/**
* 返回电话状态
*
* CALL_STATE_IDLE 无任何状态时
* CALL_STATE_OFFHOOK 接起电话时
* CALL_STATE_RINGING 电话进来时
*/
// tm.getCallState();
if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
// Log.d("test", "call state idle...");
isZhujiaoTonghua = true;
} else if (tm.getCallState() == TelephonyManager.CALL_STATE_OFFHOOK) {
//Log.e("start","end");
isZhujiaoTonghua = true;
}
// else if (tm.getCallState() == TelephonyManager.CALL_STATE_RINGING) {
// Log.d("test", "call state ringing...");
// }
// isZhujiaoTonghua=true;
} else {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
// if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)) {// 电话正在响铃
// if (isZhujiaoTonghua) {
// System.out.println("CallA" + intent.getAction());
// }
// } else
if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_IDLE)) {// 挂断
if (isZhujiaoTonghua) {
isZhujiaoTonghua = false;
}
}
// else if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_OFFHOOK)) {// 摘机,通话状态
// if (isZhujiaoTonghua) {
// System.out.println("CallB" + intent.getAction());
// }
// }
}
}
}
还要加上清单文件监听呢
<service
android:name=".CallServer"
android:enabled="true"
android:priority = "1000"
android:exported="true" /> <!-- 挂断电话 -->
鄙人只用到去电,嗯,目前就用到这些。
问题六:实现程序长期后台驻留,嗯,,,这个是个伪命题,没有象苹果那样的方式,Android系统真是英雄为难英雄,解决方案还是有的,公司不差钱,可以做一些定制机,华为,小米都有类似服务,剩下只能安装一些做些设置喽,即便如此,也不能保证就是没有问题
1.确保本软件获取本机通话,录音等权限;
2.设置手机通话为自动录音;
3.请将手机来连接WIFI,保持WIFI信号良好;
4.允许本APP后台运行;
5.取消省电模式,进入省电模式接入充电器;
6.设置休眠状态下保持WLAN连接;
剩下的就是用到长链接与心跳机制,这里就看下一篇吧