草庐IT

android - 在 Android 上录制电话

coder 2023-12-28 原文

我正在尝试使用编写此代码的麦克风记录拨出电话,但无法正常工作,我测试了简单音频记录的代码它工作正常,我不确定何时开始媒体记录我在广播接收器中启动可能有问题在那里。

这里 Audiorecoder 是我在实现 MediaRecoder 的地方创建的另一个类

public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub

        audrec = new AudioRecorder("newcall");
        this.context = context;
        if (intent.getAction().equalsIgnoreCase(Intent.ACTION_DIAL)) 
        {
            try {
                audrec.start();
                recordstarted = 1;
                telManager= (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        final PhoneStateListener phoneListener = new PhoneStateListener()
        {
            @Override
            public void onCallStateChanged(final int state, final String incomingNumber)
            {
                getTelephonyOverview(telManager);
            }
        };

        telManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);

    }
    public void getTelephonyOverview(final TelephonyManager telManager)
    {
        int callState = telManager.getCallState();
        switch (callState)
        {
        case TelephonyManager.CALL_STATE_IDLE:
        {
            if (recordstarted==1)
            {
                try {
                    audrec.stop();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                recordstarted =0;
            }
            break;
        }
        case TelephonyManager.CALL_STATE_OFFHOOK:
        {
            try {
                audrec.start();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            recordstarted =1;
            break;
        }
        case TelephonyManager.CALL_STATE_RINGING:       
        {
            try {
                audrec.start();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            recordstarted =1;
            break;
        }
        }
    }   

我正在尝试创建 3Gp 文件但不播放的另一个代码

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class androidrec extends Activity
{
   Button btn_start;
   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) 
   {
      super.onCreate(savedInstanceState); setContentView(R.layout.main);
      btn_start = (Button) findViewById(R.id.btn_start);
      UpdateRecorderState();
      btn_start.setOnClickListener(new View.OnClickListener() 
      {
         public void onClick(View v) 
         {              
            //          Toast.makeText(getBaseContext(),"Please enter both phone number and message.", 
            //          Toast.LENGTH_SHORT).show();
            if(!SharedData._Started) { StartServicesAtStartUp.Start_CallRec(getBaseContext()); }
            else { StartServicesAtStartUp.Stop_CallRec(getBaseContext()); }
            UpdateRecorderState();
         }
      });        


   }

   private void UpdateRecorderState() 
   {
      if(SharedData._Started)
      {btn_start.setText("Stop Recording");}
      else
      {btn_start.setText("Start Recording");}
   }
}[/code]


import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.media.MediaRecorder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

//import com.lumitrend.netlogger.Logger;

public class CallStateListener extends PhoneStateListener {
   public void onCallStateChanged(int state, String incomingNumber)
   {
      super.onCallStateChanged(state, incomingNumber);
      switch(state)
      {
      case TelephonyManager.CALL_STATE_IDLE:
         if(SharedData._Recording) 
         { Recorders_Stop(); }
         break;
      case TelephonyManager.CALL_STATE_RINGING:
         break;
      case TelephonyManager.CALL_STATE_OFFHOOK:
         String CallDate = SanityDate();
         String CallNum = SanityNum(incomingNumber);
         String RootDir = SharedData._Path ;  
         String CallDir = SharedData._Path + CallNum + "/" ;
         String CallFile = SharedData._Path +  CallNum + "/" + CallNum + CallDate ;
         if(!SharedData._Recording)
         {
            SharedData._Recording = true;
            String med_state = android.os.Environment.getExternalStorageState();
            if(!med_state.equals(android.os.Environment.MEDIA_MOUNTED))
            { break; }

            File directory = null;
            directory = new File(RootDir + "text.txt" ).getParentFile();
            if (!directory.exists() && !directory.mkdirs())
            { break; }

            directory = new File(CallDir + "text.txt" ).getParentFile();
            if (!directory.exists() && !directory.mkdirs())
            { break; }

            Recoders_Init(CallFile);
            Recorder_Prepare();
         }
         Log.v("DEBUG", TelephonyManager.CALL_STATE_OFFHOOK + " ITS.CallRecorder - Recording Started " + state);
         break;
      }
   }

   private String SanityDate() {
      SimpleDateFormat formatter = new SimpleDateFormat("yyMMdd-HHmmss");
      Date currentTime_1 = new Date();
      return formatter.format(currentTime_1);
   }

   private void Recorders_Stop() {
      try { 
         SharedData._recorder.stop(); SharedData._recorder.reset();
         //SharedData._recorder_down.stop(); SharedData._recorder_down.reset();
         //SharedData._recorder_up.stop();       SharedData._recorder_up.reset(); 
      }
      catch (IllegalStateException e) {}
      SharedData._Recording = false;
   }

   private void Recorder_Prepare() {
      try {
         SharedData._recorder.prepare(); SharedData._recorder.start(); 
         //SharedData._recorder_down.prepare(); SharedData._recorder_down.start(); 
         //SharedData._recorder_up.prepare(); SharedData._recorder_up.start(); 
      }
      catch (IllegalStateException e) { e.printStackTrace(); }
      catch (IOException e) { e.printStackTrace(); }
   }

   private void Recoders_Init(String path) {
      String _ext = ".3gp";
      int out_format = MediaRecorder.OutputFormat.THREE_GPP;

      SharedData._recorder.setAudioSource(SharedData._Rec_Type);
      SharedData._recorder.setOutputFormat(out_format);
      SharedData._recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
      SharedData._recorder.setOutputFile(path + "both" + _ext);

      /*
                SharedData._recorder_down.setAudioSource(MediaRecorder.AudioSource.VOICE_DOWNLINK);
                SharedData._recorder_down.setOutputFormat(out_format);
                SharedData._recorder_down.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                SharedData._recorder_down.setOutputFile(path + "-down" + _ext);

                SharedData._recorder_up.setAudioSource(MediaRecorder.AudioSource.VOICE_UPLINK);
                SharedData._recorder_up.setOutputFormat(out_format);
                SharedData._recorder_up.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                SharedData._recorder_up.setOutputFile(path  + "-up" + _ext);
       */

   }
   private String SanityNum(String numstr)
   {
      String out = "";
      for(char ch : numstr.toCharArray())
      {
         switch(ch)
         {
         case ' ': 
            break;
         case '~': 
            break;
         case '!': 
            break;
         case '@': 
            break;
         case '#': 
            break;
         case '$': 
            break;
         case '%': 
            break;
         case '^': 
            break;
         case '&': 
            break;
         case '*': 
            break;
         case '(': 
            break;
         case ')': 
            break;
         case '-': 
            break;
         case '_': 
            break;
         case '=': 
            break;
         case '|': 
            break;
         default:
            out = out + ch;
         }
      }
      return out;
   }
} 


import android.media.MediaRecorder;

final public class SharedData
{

   static int _Rec_Type = android.media.MediaRecorder.AudioSource.VOICE_CALL;


   static String _Path = android.os.Environment.getExternalStorageDirectory().getAbsolutePath() + "/ITS-CallRecorder/";
   static boolean _Started = false;
   static boolean _AutoStart = true;
   static boolean _Recording = false;

   static MediaRecorder _recorder = new MediaRecorder();
   static MediaRecorder _recorder_down = new MediaRecorder();
   static MediaRecorder _recorder_up = new MediaRecorder();

   SharedData() {    }
}

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;



public class StartServicesAtStartUp extends BroadcastReceiver
{
   public static Intent phoneStateListener;
   public void onReceive(Context context, Intent intent)
   {
      Log.d("DEBUG", "com.its.CallRecorder Initiated ...");
      Start_CallRec(context);
   }

   public static void Start_CallRec(Context context)
   {
      if(!SharedData._Started )
      {
         if(SharedData._AutoStart)
         {
            phoneStateListener = new Intent(context, CallStateListener.class);
            phoneStateListener.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startService(phoneStateListener);
            Log.d("DEBUG", "com.its.CallRecorder Call Recorder Started ...");
            TelephonyManager tManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            CallStateListener callStateListener = new CallStateListener();
            tManager.listen(callStateListener,PhoneStateListener.LISTEN_CALL_STATE);
            SharedData._Started = true;
            Toast.makeText(context," Call Recording Started ... ", Toast.LENGTH_SHORT).show();
         }       
      }
      else
      {
         Toast.makeText(context," Call Recording Already Active.. ", Toast.LENGTH_SHORT).show();
      }
   }

   public static void Stop_CallRec(Context context)
   {
      if(SharedData._Started )
      {
         context.stopService(phoneStateListener);
         Toast.makeText(context," Call Recording Stopped  ... ", Toast.LENGTH_SHORT).show();
         SharedData._Started = false;                    
      }
      else
      {
         Toast.makeText(context," Call Recording Already Stopped  ... ",  Toast.LENGTH_SHORT).show();
      }
   }

}

最佳答案

您无法对通话进行录音,因为固件不支持它。在 xda-devs 有一个更好的答案,我从 android 的未解决问题列表中得到:

The voice streams were handled by the baseband processor baseband processor, it's that the baseband firmware aren't setup to offer the streams to the application processor that's limiting the ability to truly record a call. The Android system long has the API implemented, but it can do nothing in this case.

Since the baseband firmware is close sourced and available in binary only, I doubt if the brilliant hackers here can do anything about this.

someone found a "cure" for HD2 , just by editing the registry - xda-developers.com/windows-mobile/two-way-in-call-recording-on-hd2-fixed/wo-way-in-call-recording-on-hd2-fixed/

关于android - 在 Android 上录制电话,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3929984/

有关android - 在 Android 上录制电话的更多相关文章

  1. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  2. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  3. ruby-on-rails - 如何从服务器目录制作 Paperclip 进程文件? - 2

    我想对服务器目录中的所有文件运行Paperclip。基本上,我想允许用户将一些文件通过FTP传输到我的网络服务器,然后我可以手动运行rake任务让Paperclip处理所有文件(调整图像大小、更新数据库等)。我该怎么做? 最佳答案 我不确定我是否理解您的问题-您是在询问远程运行rake任务还是如何导入图像?在后一种情况下有一个答案。首先你需要一些模型来保存图像和一些其他数据,像这样:classPicture{:thumb=>"100x100>",:big=>"500x500>"}end您可以在lib/tasks文件夹中创建简单的ra

  4. ruby - 在 ruby​​ 中验证电话号码 - 2

    验证北美电话号码的规则是什么?另外,有没有我可以使用的regex?有gem可以做到这一点吗?这里有几条我想到的规则一个10位数字没有特殊字符正数 最佳答案 有很多gem可以为您做到这一点。看看:http://rubygems.org/search?utf8=%E2%9C%93&query=phone+number这个看起来会满足您的需要——它实际上实现了一个正则表达式来验证电话号码:http://rubygems.org/gems/validates_phone_number对于美国、加拿大(百慕大、巴哈马...等和所有+1号码),

  5. Android Studio开发之使用内容组件Content获取通讯信息讲解及实战(附源码 包括添加手机联系人和发短信) - 2

    运行有问题或需要源码请点赞关注收藏后评论区留言一、利用ContentResolver读写联系人在实际开发中,普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据,比如查看联系人,短信,通话记录等等,以及对这些通讯数据及逆行增删改查。首先要给AndroidMaifest.xml中添加响应的权限配置 下面是往手机通讯录添加联系人信息的例子效果如下分成三个步骤先查出联系人的基本信息,然后查询联系人号码,再查询联系人邮箱代码 ContactAddActivity类packagecom.example.chapter07;importandroid

  6. Android 10.0 设置默认launcher后安装另外launcher后默认Launcher失效的功能修复 - 2

    1.前言 在10.0的系统rom定制化开发中,在系统中有多个launcher的时候,会在开机进入launcher的时候弹窗launcher列表,让用户选择进入哪个launcher,这样显得特别的不方便所以产品开发中,要求用RoleManager的相关api来设置默认Launcher,但是在设置完默认Launcher以后,在安装一款Launcher的时候,默认Launcher就会失效,在系统设置的默认应用中Launcher选项就为空,点击home键的时候会弹出默认Launcher列表,让选择进入哪个默认Launcher.所以需要从安装Launcher的流程来分析相关的设置。来解决问题设置默认La

  7. AiBote 2022 新研发的自动化框架,支持 Android 和 Windows 系统。速度非常快 - 2

    Ai-Bot基于流行的Node.js和JavaScript语言的一款新自动化框架,支持Windows和Android自动化。1、Windowsxpath元素定位算法支持支持Windows应用、.NET、WPF、Qt、Java和Electron客户端程序和ie、edgechrome浏览器2、Android支持原生APP和H5界面,元素定位速度是appium十倍,无线远程自动化操作多台安卓设备3、基于opencv图色算法,支持找图和多点找色,1080*2340全分辨率找图50MS以内4、内置免费OCR人工智能技术,无限制获取图片文字和找字功能。5、框架协议开源,除官方node.jsSDK外,用户可

  8. Android Gradle 7.1+新版本依赖变化 - 2

    前一段时间由于工作需要把可爱的小雪狐舍弃了,找到了小蜜蜂。但是新版本的小蜜蜂出现了很多和旧版本不一样的位置。1.功能位置迁移,原来在工程build.gradle的buildscript和allprojects移动至setting.gradle并改名为pluginManagement和dependencyResolutionManagement。里面的东西依旧可以按照原来的copy过来。pluginManagement{repositories{gradlePluginPortal()google()mavenCentral()}}dependencyResolutionManagement{r

  9. ruby - Ruboto 的最佳教程(适用于 Android 的 ruby​​)? - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion我几乎用完了Ruby,但现在想试试Ruboto,android上的ruby​​。谷歌未能给我足够的(几乎没有结果)。所以任何人都可以分享一些关于Ruboto的教程。

  10. ruby-on-rails - 更改 faker gem 电话号码格式 - 2

    有没有办法控制faker生成的电话号码的格式?当我打电话时:Faker::PhoneNumber.cell_phone.to_i我最终得到了错误的值。我也不想有扩展。 最佳答案 您可以像这样即时设置自定义格式:Faker::Base.numerify('+90(###)#######')这将解决您的问题。 关于ruby-on-rails-更改fakergem电话号码格式,我们在StackOverflow上找到一个类似的问题: https://stackover

随机推荐