苹果手机通话怎么录音(苹果x手机通话怎么录音在哪)
- 时间:
- 浏览:83
- 来源:奥一装修网
苹果手机接电话是怎么录音
要求:①:自动录音; ②:没有接口,只是一种服务; ③:自动压缩和上传录音; ④:用户清理后台时,不能终止该服务; ⑤:稳定性:1,无网络情况; 2,上传失败; 3,服务报告错误。解决方案:①:自动记录呼叫会启动一项服务来监视用户的手机呼叫状态。在通话状态下检测到用户时,会立即开始录音。通话结束后,停止录音并保存文件。该功能的前提条件:1。录音权限,存储空间读写权限,通话状态读取权限。 2。无法停止服务,否则无法执行记录。 3。启动(您不能让用户每次启动时都主动打开服务)②:没有界面,只有服务解决方案①普通服务,监视启动广播,并在用户启动时启动服务。但是,发现该服务未启动。要启动服务,即使没有打开活动,也必须具有活动。在实际执行项目时,PM会提出您无法理解的各种要求。例如,对于该系统,PM要求此应用程序仅是一个录制服务,必须没有界面,并且手机桌面上不能出现任何应用程序图标。因此,解决方案①不可行。解决方法②Android手机在设置中具有辅助功能(某些手机也称为辅助功能)。这样,只要用户打开我们的辅助功能,并且使用该辅助功能即可实现红包软件,我们就可以实现一些强大的功能。
免费iphone通话录音
在此处写图片说明③:自动压缩并上传记录我们只需要在上传之前先压缩文件,然后再上传即可。 ④:当用户清理后台时,要求服务不能被杀死,服务也不能被杀死,可能仅仅是系统服务。当然,也可以使用类似于QQ和微信制作的家庭用桶。大公司可以与供应商合作,其应用程序不易被杀死。当然,不建议这样做。这是垃圾软件,破坏了Android开发的优美环境。实际上,如果可以将服务设置为系统服务,只要用户没有在可访问性页面上主动关闭服务,则后台将无法清理和更改服务。将其设置为系统级服务后,清理后台时,即使该服务被终止,它也会非常快速地重新启动。 (感兴趣的学生可以尝试)⑤:稳定性:1。在没有网络的情况下; 2。上传失败; 3。服务错误提示:在没有网络的情况下,保存记录文件的地址(保存的方法有很多:Sqlite,Sharedpreferences等)。上传失败是相同的。失败的原因可能有很多:网络断开,接口报告错误等。恢复网络后,您可以重新上传,以免丢失录制文件。代码非常简单,注释也非常详细:项目结构:在此处写图片描述
苹果x手机通话怎么录音在哪
/ ** *电话自动录音服务(去电,自动录音和上载来电)。 *由wang。ao在2017/2/24中创建。 * /公共类RecorderService扩展了AccessibilityService {私有静态最终String TAG =“ RecorderService”;私有静态最终字符串TAG1 =“移动电话状态”; / ** *录音* /私人MediaRecorder录音机;私人SimpleDateFormat dateFormat = new SimpleDateFormat(“ yyyy-MM-dd HH:mm:ss”); / ** *收听拨号广播以获取用户拨打的电话号码* /私有OutCallReceiver outCallReceiver;私有IntentFilter intentFilter; / ** *网络状态更改广播。解除网络阻塞后,用户上传所有未录制的录制文件。专用NetworkConnectChangedReceiver networkConnectChangedReceiver;私有IntentFilter intentFilter2; / ** *当前呼叫对象的电话号码* /私有字符串currentCallNum =“”; / ** *区分呼入和呼出* / private int previousStats = 0; / ** *当前正在记录的文件* /私有字符串currentFile =“”; / ** *保存未上传的录制文件* /私有SharedPreferences unUploadFile; private String dirPath =“”; private boolean isRecording = false; @Override protected void onServiceConnected(){Log 。i(TAG,“ onServiceConnected”)); Toast。makeText(getApplicationContext(),“自动录制服务已启动”,Toast。LENGTH_LONG)。show();} @Override public void onAccessibilityEvent(AccessibilityEvent事件){// TODO自动生成的方法存根} @Override public void onInterrupt(){// TODO自动生成的方法存根Log。i(TAG,“ onServiceConnected”);} @ Override public boolean onUnbind(Intent intent){返回super。onUnbind(intent);} @Override公共无效onCreate(){super。onCreate(); TelephonyManager tm =(TelephonyManager)getSystemService(TELEPHONY_SERVICE); //监视电话状态tm。listen(new MyListener(),PhoneStateListener。LISTEN_CALL_STATE); outCallReceiver = new OutCallReceiver(); intentFilter = new IntentFilter(); //设置拨号广播过滤器intentFilter。addAction(“ android。intent。action。NEW_OUTGOING_CALL”); registerReceiver(outCallReceiver,intentFilter); //注册拨号广播接收器intentFilter2 = new IntentFilter(); //设置网络状态更改广播过滤器intentFilter2。addAction(“ android。net。conn。CONNECTIVITY_CHANGE”); intentFilter2。addAction(“ android。net。wifi。WIFI_STATE_CHANGED”); intentFilter2。addAction(“ android。net。wifi。STATE_CHANGE”); //注册网络状态更改广播接收器registerReceiver(networkConnectChangedReceiver,intentFilter2); unUploadFile = getSharedPreferences(“ un_upload_file”,0); unUploadFile。edit()。 putString(“ description”,“未上传记录文件的存储路径”)。提交(); dirPath = Environment。getExternalStorageDirectory()。 GetAbsolutePath()+“ /com。ct。phonerecorder/”;} @Override public void onDestroy(){super。onDestroy(); Toast。makeText(getApplicationContext(),“进程已关闭,无法继续记录,请打开记录服务”,Toast。LENGTH_LONG)。unregisterReceiver(outCallReceiver);}如果(networkConnectChangedReceiver!= null){unregisterReceiver(networkConnectChangedReceiver);}}类MyListener扩展了PhoneStateListener {@Override public void onCallStateChanged(int状态,字符串incomingNumber){// TODO自动生成的方法存根Log。d (TAG1,“空闲状态” +来电号码);开关(状态){case TelephonyManager。CALL_STATE_IDLE:Log。d(TAG1,“空闲”);如果(recorder!= Null && isRecording){recorder。stop(); //停止记录recorder。release();记录器= null; Log。d(“电话”,“结束通话,停止录音”);} isRecording = false;打破;案例TelephonyManager。CALL_STATE_RINGING:Log。d(TAG1,“来话铃声” +来电号码); //初始化中断; case TelephonyManager。CALL_STATE_OFFHOOK:Log。d(TAG1,“摘机” +(!communityNumber。equals(“”)?incomingNumber:currentCallNum)); initRecord(!incomingNumber。equals(“”?incomingNumber:currentCallNum); //开始录制if(recorder!= null){recorder。start(); isRecording = true;}默认值:break;}}} / ** *录制结束后,自动上传录制文件。 *①网络可用:直接上传; *②网络不可用:保存文件路径并在网络可用时上传; *③如果文件上传失败,请保存文件路径或重新上传。 * / public void uploadFile(字符串文件){ZipUtils。zipFile(dirPath +文件,dirPath +文件+“ 。zip”);如果(NetWorkUtils。isNetworkConnected(getApplicationContext())){//上传文件// OkHttpUtils。postFile()}否则{saveUnUploadFIles(dirPath + file +“ 。zip”);}} / ** *保存未上传的录制文件* * @param文件未上传的记录文件路径* /私有void saveUnUploadFIles(字符串文件){字符串文件= unUploadFile。getString(“ unUploadFile”,“”); if(files。equals(“”)){files = file;} else {StringBuilder sb =新的StringBuilder(文件);} unUploadFile。edit()。 putString(“ unUploadFile”文件)。commit();} / ** *由于网络或其他原因,尚未上传或上传失败的文件。重新上传{//获取尚未上传的文件并上传。字符串文件= unUploadFile。getString(“ unUploadFile”,“”); unUploadFile。edit()。 PutString(“ unUploadFile”,“”)。commit(); if(files。equals(“”)){返回;}字符串【】 fileArry = files。split(“;”); int len = fileArry。length;对于(字符串文件:fileArry){上传(文件);}} / ** *文件上传* * @param文件要上传的文件* /公共无效文件上传(最终字符串文件){文件file1 =新文件(文件); if(file1 == null ||!File1。exists()){//文件不存在返回;}saveUnUploadFIles(文件); return;} Map map = new HashMap(); map。put(“ type”,“ 1”); final String url =“ http://192。168。1。158:8082/uploader”; OkHttpUtils。post()// 。addFile(“ mFile”,file1。getName(),file1)// 。url(url)// 。params(map)。build()// 。execute(new StringCallback(){ @Override public void onResponse(字符串响应,整数ID){Log。e(TAG,“成功响应= +响应”);} @Override public void onError(呼叫,异常e,int ID){Log。e(TAG ,“失败的响应=” + e。toString()); saveUnUploadFIles(文件);});} / ** *初始化记录器,并重命名记录文件* * @param entryNumber呼叫号码* /私有void initRecord(字符串入场号码){previousStats = TelephonyManager。CALL_STATE_RINGING;记录器=新的MediaRecorder(); records。setAudioSource(MediaRecorder。AudioSource。MIC); //麦克风录音机。setOutputFormat(MediaRecorder。OutputFormat。RAW_AMR); //设置输出3gp格式File out = new File(dirPath); if(!Out。exists()){out。mkdirs();} recorder。setOutputFile(dirPath + getFileName((previousStats == TelephonyManager。CALL_STATE_RINGING?incomingNumber:currentCallNum))); records。setAudioEncoder(MediaRecorder。AudioEncoder。AMR_NB); //设置音频编码格式try {} catch(Exception e){// TODO自动生成的catch块e。printStackTrace();}} / ** *获取记录文件的名称* * @param来电号码呼叫号码* @return获取记录的名称文件* /私有字符串getFileName(字符串传入编号){日期=新日期(System。currentTimeMillis()); currentFile = entryNumber +“” + dateFormat。format(日期)+“ 。mp3”; return currentFile;} / ** *拨打广播接收并获得拨号号码* /公共类OutCallReceiver扩展了BroadcastReceiver {@Override public void onReceive(上下文上下文,意图){Log。d(TAG1,“当前的手机通话:“ + currentCallNum); if(intent。getAction()。equals(Intent。ACTION_NEW_OUTGOING_CALL)){Log。d(TAG1,“当前电话已拨出:” + currentCallNum);}否则{Log。d(TAG1,“有电话,快速接听电话”);}}} / ** *网络状态更改广播接收器* /公共类NetworkConnectChangedReceiver扩展了BroadcastReceiver {private static final String TAG =“ network status”; @Override public void onReceive(上下文上下文,意图){/ ** *这将侦听网络连接设置,包括wifi和移动数据的打开和关闭。 *最好使用此显示器。如果wifi打开,关闭,则将监视该连接上的所有可用连接。请参阅日志*此广播的最大缺点是响应速度比上述两个广播慢。如果您只想监视wifi,我认为使用以上两种方法更为合适。 )){ConnectivityManager管理器=(ConnectivityManager)上下文Log。i(TAG,“ CONNECTIVITY_ACTION”); NetworkInfo activeNetwork = manager。getActiveNetworkInfo(); if(activeNetwork!= Null){//已连接到互联网if(activeNetwork。isConnected()){//当前可用的网络,如果(activeNetwork。getType()== ConnectivityManager。TYPE_WIFI){//已连接到wifi Log。e (TAG,“当前WiFi连接可用”);}否则,如果(activeNetwork。getType()== ConnectivityManager。TYPE_MOBILE){//已连接到移动提供商的数据计划Log。e(TAG,“当前移动网络连接可用“);} uploadUnUploadedFiles();}其他{请确保您具有互联网“);}}}其他{//没有连接到Internet Log。e(TAG,”目前没有互联网连接,请确保您具有互联网“” ;;}}}}} / ** *获取网络连接状态工具类*由wang。ao在2017/2/24中创建* /公共类NetWorkUtils {/ ** *确定是否存在网络连接* @param上下文* @return * / public静态布尔值isNetworkConnected(上下文上下文){if(context!= null){ConnectivityManager mConnectivityManager =(ConnectivityManager)context 。getSystemService(Context。CONNECTIVITY_SERVICE); NetworkInfo mNetworkInfo = mConnectivityManager。getActiveNetworkInfo();如果(mNetworkInfo!= null){返回mNetworkInfo 。isAvailable();}}} / ** *确定WIFI网络是否可用* @param context * @return * / public static boolean isWifiConnected(Context context){if(context!= Null){ConnectivityManager mConnectivityManager =(ConnectivityManager)context 。getSystemService(Context。 CONNECTIVITY_SERVICE); NetworkInfo mWiFiNetworkInfo = mConnectivityManager 。getNetworkInfo(ConnectivityManager。TYPE_WIFI); if(mWiFiNetworkInfo!= Null){返回mWiFiNetworkInfo。isAvailable();}}返回false;} / ** *确定移动网络是否可用* @param context * @return * / public static boolean isMobileConnected(Context context){ if(context!= null){。getSystemService(Context。CONNECTIVITY_SERVICE); NetworkInfo mMobileNetworkInfo = mConnectivityManager 。getNetworkInfo(ConnectivityManager。TYPE_MOBILE); if(mMobileNetworkInfo!= null){返回mMobileNetworkInfo。isAvailable();}}返回false;} / ** *获取当前网络连接类型信息* @param上下文* @return * / public static int getConnectedType(上下文上下文){ if(context!= Null){ConnectivityManager mConnectivityManager =(ConnectivityManager)上下文。getSystemService(Context。CONNECTIVITY_SERVICE); NetworkInfo mNetworkInfo = mConnectivityManager。getActiveNetworkInfo();return mNetworkInfo。getType();}}返回-1;} / ** *获取当前网络状态:无网络0:WIFI网络1:3G网络2:2G网络3 * * @param context * @return * / public static int getAPNType(上下文上下文){int netType = 0; ConnectivityManager connMgr =(ConnectivityManager)上下文。getSystemService(Context。CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr。getActiveNetworkInfo(); if(networkInfo == null){返回netType;} int nType = networkInfo。getType();如果(nType == ConnectivityManager。TYPE_WIFI){netType = 1; // wifi}否则,如果(nType == ConnectivityManager。TYPE_MOBILE){int nSubType = networkInfo。getSubtype();。getSystemService(Context。TELEPHONY_SERVICE);如果(nSubType == TelephonyManager。NETWORK_TYPE_UMTS &&!mTelephony。isNetworkRoaming()){netType = 2; // 3G} else {netType = 3; // 2G}} return netType;}}公共类ZipUtils {private static final int BUFF_SIZE = 1024; / ** * @param zos压缩流* @param parentDirName父目录* @param文件待处理文件* @param缓冲区* URL:http://www。bianceng。 zh / OS /额外//。 htm * @return每当目录中的文件未能压缩时停止并返回* /私有静态布尔zipFile(ZipOutputStream zos,字符串parentDirName,文件文件,字节【】缓冲区){String zipFilePath = parentDirName + file。getName();zipFilePath + = File。separator; for(文件f:file。listFiles()){if(!zipFile(zos,zipFilePath,f,buffer)){返回false;}}返回true;} )); ZipEntry zipEntry =新的ZipEntry(zipFilePath); zipEntry。setSize(file。length()); zos。putNextEntry(zipEntry); while(bis。read(buffer)!= -1){zos。write(buffer);} bis。close(); return true;} catch(FileNotFoundException ex){ex。printStackTrace();} catch(IOException ex){} return false;}} / ** * @param srcPath待压缩的文件或目录* @param dstPath压缩的zip文件* @return停止压缩并返回,只要有待压缩文件的压缩失败(相当于Windows直接压缩)* /公共静态布尔zipFile(字符串srcPath,字符串dstPath){File srcFile = new File(srcPath); if(!SrcFile。exists()){返回false;}字节【】缓冲区=新字节【BUFF_SIZE】;尝试{ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dstPath));布尔结果= zipFile(zos,“”,srcFile,缓冲区); zos。close();返回结果;} catch(FileNotFoundException ex){ex 。printStackTrace();} catch(IOException ex){ex。printStackTrace();} return false;}*要解压缩的@param srcPath zip文件*要解压缩的@param dstPath zip目录* @return在解压缩期间发生错误时,立即停止并返回(相当于直接在Windows上解压缩)* / public static boolean unzipFile(String srcPath,字符串dstPath){if(TextUtils。isEmpty(srcPath)|| TextUtils。isEmpty(dstPath)){返回false;}文件srcFile =新文件(srcPath); if(!srcFile。exists()||!srcFile。getName()。toLowerCase(Locale。getDefault())。EndsWith(“ zip”)){返回false;}文件dstFile =新文件(dstPath); if(!dstFile。exists()||!dstFile。isDirectory()){dstFile。mkdirs();}尝试{ZipInputStream zis = new ZipInputStream(new FileInputStream(srcFile)); BufferedInputStream bis =新的BufferedInputStream(zis);字节【】缓冲区=新字节【BUFF_SIZE】; if(!dstPath。endsWith(File。separator)){dstPath + = File。separator;} while((zipEntry = zis。getNextEntry())!= null){字符串fileName = dstPath + zipEntry。getName();文件文件=新文件(fileName);文件parentDir = file。getParentFile(); if(!parentDir。exists()){parentDir。mkdirs();} FileOutputStream fos = new FileOutputStream(file); while(bis。read(buffer)!= -1){fos。write(buffer);} fos。close();} bis。close(); zis。close();返回true;ex。printStackTrace();}捕获(IOException ex){ex。printStackTrace();}返回false;}}