在安卓系统中录制电话为什么无法正常工作?

3
我正在MainActivity中启动一个服务,该服务无限期地运行以查找呼入和呼出电话进行记录。
为什么示例中的“switch-case”不起作用?
没有错误发生,但我只能记录每个呼入和呼出。
录音后服务将被杀死,它会重新创建START_STICKY,但永远不会开始。
请帮忙。提前感谢!
是否有其他代码可用于在Android中记录呼入和呼出电话?
package com.exampled.demoserv;

import java.io.File;
import java.io.IOException;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;


public class ParentalService extends Service 
{
    @Override
    public void onCreate()
    {
        //Toast.makeText(getApplicationContext(), "Service Created", Toast.LENGTH_SHORT).show();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        // TODO Auto-generated method stub
        //Toast.makeText(getApplicationContext(), "Subu's Monitoring sTARTED", Toast.LENGTH_SHORT).show();
        startMonitor();
        return START_STICKY_COMPATIBILITY;
    }

    @Override
    public IBinder onBind(Intent arg0)
    {
        // TODO Auto-generated method stub
        Toast.makeText(getApplicationContext(), "Service Binded", Toast.LENGTH_SHORT).show();
        return null;
    }

    @Override
    public void onDestroy()
    {
        // TODO Auto-generated method stub
        super.onDestroy();
        Toast.makeText(getApplicationContext(), "Destroyed", Toast.LENGTH_SHORT).show();
    }

    public void startMonitor() 
    {
        TelephonyManager mTelephonyMgr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
        mTelephonyMgr.listen(new TeleListener(), PhoneStateListener.LISTEN_CALL_STATE);
    }

    class TeleListener extends PhoneStateListener
    {
        boolean recording = false;
        final MediaRecorder recorder = new MediaRecorder();
        String inc_num="", fname;

        public void onCallStateChanged(int state, String incomingNumber) throws IllegalStateException
        {
            super.onCallStateChanged(state, incomingNumber);

            switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    //CALL_STATE_IDLE;
                    Toast.makeText(getApplicationContext(), "CALL_STATE_IDLE : "+Boolean.toString(recording), Toast.LENGTH_SHORT).show();

                    if(recording==true)
                    {
                        recorder.stop();
                        recorder.reset();
                        recorder.release();
                        Toast.makeText(getApplicationContext(), "Released_idle", Toast.LENGTH_SHORT).show();
                    }
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    Toast.makeText(getApplicationContext(), Boolean.toString(recording)+" : Offhook",Toast.LENGTH_SHORT).show();

                    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);   
                    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
                    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 

                    String file= Environment.getExternalStorageDirectory().toString();
                    String filepath= file+"/111111111111Aandroid_Subui";
                    File dir= new File(filepath);
                    dir.mkdirs();

                    if(inc_num.length()==0)
                    {
                        fname="outgoingNum";
                    }

                    filepath+="/"+fname+".3gp";
                    recorder.setOutputFile(filepath);

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

                    recorder.start();  
                    recording=true;
                    break;
                case TelephonyManager.CALL_STATE_RINGING:
                    //CALL_STATE_RINGING
                    inc_num = incomingNumber;
                    Toast.makeText(getApplicationContext(), "CALL_STATE_RINGING : "+incomingNumber, Toast.LENGTH_SHORT).show();
                    break;
                default:
                    Toast.makeText(getApplicationContext(), "Default reached", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }
}

1
ServiceCaller 的清单行在哪里?你能在 GitHub 上分享代码吗? - android developer
2个回答

10

终于得到结果了...现在我可以记录来电和去电 (2.2)。

改变了整个结构...

这是我的CallRecordingService.java文件。吐司将让您了解正在发生的事情... :)

package com.exampled.beta;

import java.io.File;
import java.io.IOException;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaRecorder;
import android.os.Environment;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.widget.Toast;

public class CallRecordingService extends Service
{
    final MediaRecorder recorder = new MediaRecorder();
    boolean recording = false;
    int i = 0;
    String fname;

    BroadcastReceiver CallRecorder = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context arg0, Intent intent)
        {
            // TODO Auto-generated method stub
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            i++;

            if(TelephonyManager.EXTRA_STATE_OFFHOOK.equals(state))
            {
                Toast.makeText(getApplicationContext(), state, Toast.LENGTH_LONG).show();

                Toast.makeText(arg0, "Start CaLLED "+recording+fname, Toast.LENGTH_LONG).show();

                startRecording();
            }

            if(TelephonyManager.EXTRA_STATE_IDLE.equals(state) && recording == true)
            {
                Toast.makeText(getApplicationContext(), state, Toast.LENGTH_LONG).show();

                Toast.makeText(arg0, "STOP CaLLED :"+recording, Toast.LENGTH_LONG).show();
                stopRecording();
            }

            if(TelephonyManager.EXTRA_STATE_RINGING.equals(state))
            {
                fname = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
                Toast.makeText(getApplicationContext(), state+" : "+fname, Toast.LENGTH_LONG).show();
            }
        }
    };

    BroadcastReceiver OutGoingNumDetector = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            // TODO Auto-generated method stub
            fname=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
        }
    };

    @Override
    public void onCreate()
    {
        // TODO Auto-generated method stub
        super.onCreate();
        Toast.makeText(getApplicationContext(), "Service Created", Toast.LENGTH_LONG).show();

        IntentFilter RecFilter = new IntentFilter();
        RecFilter.addAction("android.intent.action.PHONE_STATE");
        registerReceiver(CallRecorder, RecFilter);
        IntentFilter OutGoingNumFilter=new IntentFilter();
        OutGoingNumFilter.addAction("android.intent.action.NEW_OUTGOING_CALL");
        registerReceiver(OutGoingNumDetector, OutGoingNumFilter);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        // TODO Auto-generated method stub
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent arg0)
    {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onDestroy()
    {
        // TODO Auto-generated method stub
        super.onDestroy();
        unregisterReceiver(CallRecorder);
        unregisterReceiver(OutGoingNumDetector);
        Toast.makeText(getApplicationContext(), "Destroyed", Toast.LENGTH_SHORT).show();
    }

    public void startRecording()
    {
        if(recording==false)
        {
            Toast.makeText(getApplicationContext(), "Recorder_Sarted"+fname, Toast.LENGTH_LONG).show();
            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);   
            recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
            String file= Environment.getExternalStorageDirectory().toString();
            String filepath= file+"/11111111111111";
            File dir= new File(filepath);
            dir.mkdirs();

            filepath+="/"+fname+".3gp";
            recorder.setOutputFile(filepath);

            try {
                recorder.prepare();
            } catch (IllegalStateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            recorder.start(); 
            recording=true;
        }
    }

    public void stopRecording()
    {
        if(recording==true)
        {
            Toast.makeText(getApplicationContext(), "Recorder_Relesed from "+recording, Toast.LENGTH_LONG).show();

            recorder.stop();
            recorder.reset();
            recorder.release();
            recording=false;
            broadcastIntent();
        }
    }

    public void broadcastIntent()
    {
       Intent intent = new Intent();
       intent.setAction("com.exampled.beta.CUSTOM_INTENT");
       sendBroadcast(intent);
       Toast.makeText(getApplicationContext(), "BroadCaste", Toast.LENGTH_LONG).show();
    }
}

ServiceCaller.java

package com.exampled.beta;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class ServiceCaller extends BroadcastReceiver
{
    @Override
    public void onReceive(Context arg0, Intent arg1)
    {
        // TODO Auto-generated method stub
        arg0.stopService(new Intent(arg0,CallRecordingService.class));
        Intent intent=new Intent(arg0, CallRecordingService.class);
        arg0.startService(intent);
        Toast.makeText(arg0, "Service Explicitely", Toast.LENGTH_SHORT).show();
    }
}

MainActivity.java

package com.exampled.beta;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;

public class MainActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this,CallRecordingService.class);

        startService(intent);
        finish();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is
        // present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}

权限

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

1
这个能录制双方的声音吗?但我认为不行,因为你已经将麦克风设置为音频源,它只会记录安装在手机上的那一端的声音,另一端的声音会比较不清晰。我已经尝试过并发现了同样的问题。 - Saty
你能分享一下在Github上的项目吗? - android developer
谁将调用ServiceCaller? - Midhun Vijayakumar
第一次它可以工作,但在接收第二个调用时崩溃了。你能分享清单文件吗? - Sachin Varma
嗨,当应用程序被杀死或从后台中移除时,它无法工作。 - Shubham Narkhede

1

不要使用myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

使用myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);

这个选项的描述在这里> http://developer.android.com/reference/android/media/MediaRecorder.AudioSource.html 语音呼叫上行+下行音频源,这意味着录音将包含两个声音。

开始录制时要小心。当通话被发起或对方接听通话时。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接