【问题标题】:Outgoing calls not recording拨出电话不录音
【发布时间】:2017-03-09 04:31:11
【问题描述】:

我正在尝试在我的应用中添加一件事。我正在尝试的是每当用户接到电话或用户拨打电话时,同时应该开始录音,并且在切断通话后录音必须存储在 SD 卡中。

问题
1)来电记录有时工作

2)传出不工作

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_CODE = 0;
    private DevicePolicyManager mDPM;
    private ComponentName mAdminName;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PackageManager p = getPackageManager();
        p.setComponentEnabledSetting(getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

        try {
            // Initiate DevicePolicyManager.
            mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
            mAdminName = new ComponentName(this, DeviceAdminDemo.class);

            if (!mDPM.isAdminActive(mAdminName)) {
                Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
                intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminName);
                intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Click on Activate button to secure your application.");
                startActivityForResult(intent, REQUEST_CODE);
            } else {
                // mDPM.lockNow();
                // Intent intent = new Intent(MainActivity.this,
                // TrackDeviceService.class);
                // startService(intent);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (REQUEST_CODE == requestCode) {
            Intent intent = new Intent(MainActivity.this, TService.class);
            startService(intent);
        }
    }

}

T服务

public class TService extends Service {
    MediaRecorder recorder;
    File audiofile;
    String name, phonenumber;
    String audio_format;
    public String Audio_Type;
    int audioSource;
    Context context;

    Timer timer;
    Boolean offHook = false, ringing = false;
    Toast toast;
    Boolean isOffHook = false;
    private boolean recordstarted = false;

    private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
    private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
    private CallBr br_call;




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

    @Override
    public void onDestroy() {
        Log.d("service", "destroy");

        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // final String terminate =(String)
        // intent.getExtras().get("terminate");//
        // intent.getStringExtra("terminate");
        // Log.d("TAG", "service started");
        //
        // TelephonyManager telephony = (TelephonyManager)
        // getSystemService(Context.TELEPHONY_SERVICE); // TelephonyManager
        // // object
        // CustomPhoneStateListener customPhoneListener = new
        // CustomPhoneStateListener();
        // telephony.listen(customPhoneListener,
        // PhoneStateListener.LISTEN_CALL_STATE);
        // context = getApplicationContext();

        final IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_OUT);
        filter.addAction(ACTION_IN);
        this.br_call = new CallBr();
        this.registerReceiver(this.br_call, filter);

        // if(terminate != null) {
        // stopSelf();
        // }
        return START_NOT_STICKY;
    }

    public class CallBr extends BroadcastReceiver {
        Bundle bundle;
        String state;
        String inCall, outCall;
        public boolean wasRinging = false;

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(ACTION_IN)) {
                if ((bundle = intent.getExtras()) != null) {
                    state = bundle.getString(TelephonyManager.EXTRA_STATE);
                    if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                        inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
                        wasRinging = true;
                        Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
                    } else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
                        if (wasRinging == true) {

                            Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();

                            String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
                            File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa1");
                            if (!sampleDir.exists()) {
                                sampleDir.mkdirs();
                            }
                            String file_name = "Record";
                            try {
                                audiofile = File.createTempFile(file_name, ".amr", sampleDir);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            String path = Environment.getExternalStorageDirectory().getAbsolutePath();
                            System.out.println("PATH"+path);

                            recorder = new MediaRecorder();
//                          recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);

                            recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
                            recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
                            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                            recorder.setOutputFile(audiofile.getAbsolutePath());
                            try {
                                recorder.prepare();
                            } catch (IllegalStateException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            recorder.start();
                            recordstarted = true;
                        }
                    } else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                        wasRinging = false;
                        Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
                        if (recordstarted) {
                            recorder.stop();
                            recordstarted = false;
                        }
                    }
                }
            } else if (intent.getAction().equals(ACTION_OUT)) {
                if ((bundle = intent.getExtras()) != null) {
                    outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
                    Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();
                }
            }
        }
    }

}

【问题讨论】:

    标签: android android-service telephonymanager android-mediarecorder android-broadcastreceiver


    【解决方案1】:

    从 TService 中删除这个if (wasRinging == true),这个是Rining 布尔值检查电话是否在某个时间之前响铃,即当电话接到电话时,如果拨出电话它保持为假,所以跳过录音部分。只需更改它,它应该可以工作。

    只需用这个替换您的 TService 代码..

        public class TService extends Service {
        MediaRecorder recorder;
        File audiofile;
        String name, phonenumber;
        String audio_format;
        public String Audio_Type;
        int audioSource;
        Context context;
    
        Timer timer;
        Boolean offHook = false, ringing = false;
        Toast toast;
        Boolean isOffHook = false;
        private boolean recordstarted = false;
    
        private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
        private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
        private CallBr br_call;
    
    
    
    
        @Override
        public IBinder onBind(Intent arg0) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void onDestroy() {
            Log.d("service", "destroy");
    
            super.onDestroy();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // final String terminate =(String)
            // intent.getExtras().get("terminate");//
            // intent.getStringExtra("terminate");
            // Log.d("TAG", "service started");
            //
            // TelephonyManager telephony = (TelephonyManager)
            // getSystemService(Context.TELEPHONY_SERVICE); // TelephonyManager
            // // object
            // CustomPhoneStateListener customPhoneListener = new
            // CustomPhoneStateListener();
            // telephony.listen(customPhoneListener,
            // PhoneStateListener.LISTEN_CALL_STATE);
            // context = getApplicationContext();
    
            final IntentFilter filter = new IntentFilter();
            filter.addAction(ACTION_OUT);
            filter.addAction(ACTION_IN);
            this.br_call = new CallBr();
            this.registerReceiver(this.br_call, filter);
    
            // if(terminate != null) {
            // stopSelf();
            // }
            return START_NOT_STICKY;
        }
    
        public class CallBr extends BroadcastReceiver {
            Bundle bundle;
            String state;
            String inCall, outCall;
            public boolean wasRinging = false;
            public boolean didMakeACall = false;
    
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent.getAction().equals(ACTION_IN)) {
                    if ((bundle = intent.getExtras()) != null) {
                        state = bundle.getString(TelephonyManager.EXTRA_STATE);
                        if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                            inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
                            wasRinging = true;
                            Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
                        } else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
                            if (wasRinging || didMakeACall) {
    
                                Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();
    
                                String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
                                File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa1");
                                if (!sampleDir.exists()) {
                                    sampleDir.mkdirs();
                                }
                                String file_name = "Record";
                                try {
                                    audiofile = File.createTempFile(file_name, ".amr", sampleDir);
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                                String path = Environment.getExternalStorageDirectory().getAbsolutePath();
                                System.out.println("PATH"+path);
    
                                recorder = new MediaRecorder();
    
    
                                recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
                                recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
                                recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                                recorder.setOutputFile(audiofile.getAbsolutePath());
                                try {
                                    recorder.prepare();
                                } catch (IllegalStateException e) {
                                    e.printStackTrace();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                                recorder.start();
                                recordstarted = true;
                            }
                        } else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                            wasRinging = false;
                            Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
                            if (recordstarted) {
                                recorder.stop();
                                recordstarted = false;
                            }
                        }
                    }
                } else if (intent.getAction().equals(ACTION_OUT)) {
                    if ((bundle = intent.getExtras()) != null) {
                        didMakeACall = true;
                        outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
                        Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();
                    }
                }
            }
        }
    
    }
    

    【讨论】:

    • 我听不懂你说什么......对不起英语
    • 我已经编辑了我的答案,只需将您的 TService 代码替换为我的即可。
    • 是的!我有,在 kitkat 上它工作正常,但我还没有在新版本上测试过。
    • 我也有 kitkat..我什至没有敬酒..传入传出没有任何效果..你能上传演示吗?
    • 文件夹也没有创建..你能帮忙吗?
    【解决方案2】:

    我担心社区不喜欢这里的外部链接,所以我在这里发布我的快速演示项目......

    AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <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"/>
    
    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    
        <service android:name=".TService"/>
    </application>
    

    MainActivity.java

    我在其 onCreate 方法中启动 TService,请注意,这可能是您项目中的任何活动,或者您可以从中启动服务的任何上下文。

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            startService(new Intent(this, TService.class));
        }
    }
    

    现在终于, TService.java 我已经在 Kitkat 和 Lollipop 中对此进行了测试,并且可以正常工作,对于较新的版本,您需要在运行时明确要求 Manifest 权限,它应该可以正常工作。

    public class TService extends Service {
        MediaRecorder recorder;
        File audiofile;
        String name, phonenumber;
        String audio_format;
        public String Audio_Type;
        int audioSource;
        Context context;
    
        Timer timer;
        Boolean offHook = false, ringing = false;
        Toast toast;
        Boolean isOffHook = false;
        private boolean recordstarted = false;
    
        private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
        private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
        private CallBr br_call;
    
    
    
    
        @Override
        public IBinder onBind(Intent arg0) {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public void onDestroy() {
            Log.d("service", "destroy");
    
            super.onDestroy();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // final String terminate =(String)
            // intent.getExtras().get("terminate");//
            // intent.getStringExtra("terminate");
            // Log.d("TAG", "service started");
            //
            // TelephonyManager telephony = (TelephonyManager)
            // getSystemService(Context.TELEPHONY_SERVICE); // TelephonyManager
            // // object
            // CustomPhoneStateListener customPhoneListener = new
            // CustomPhoneStateListener();
            // telephony.listen(customPhoneListener,
            // PhoneStateListener.LISTEN_CALL_STATE);
            // context = getApplicationContext();
    
            final IntentFilter filter = new IntentFilter();
            filter.addAction(ACTION_OUT);
            filter.addAction(ACTION_IN);
            this.br_call = new CallBr();
            this.registerReceiver(this.br_call, filter);
    
            // if(terminate != null) {
            // stopSelf();
            // }
            return START_NOT_STICKY;
        }
    
        public class CallBr extends BroadcastReceiver {
            Bundle bundle;
            String state;
            String inCall, outCall;
            public boolean wasRinging = false;
            boolean didMakeACall = false;
    
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent.getAction().equals(ACTION_IN)) {
                    if ((bundle = intent.getExtras()) != null) {
                        state = bundle.getString(TelephonyManager.EXTRA_STATE);
                        if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                            inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
                            wasRinging = true;
                            Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
                        } else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
                            if (wasRinging || didMakeACall) {
    
                                Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();
    
                                String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
                                File sampleDir = new File(Environment.getExternalStorageDirectory(), "/MyRecorder");
                                if (!sampleDir.exists()) {
                                    sampleDir.mkdirs();
                                }
                                String file_name = "Record";
                                try {
                                    audiofile = File.createTempFile(file_name, ".amr", sampleDir);
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                                String path = Environment.getExternalStorageDirectory().getAbsolutePath();
                                System.out.println("PATH"+path);
    
                                recorder = new MediaRecorder();
    //                          recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
    
                                recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
                                recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
                                recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                                recorder.setOutputFile(audiofile.getAbsolutePath());
                                try {
                                    recorder.prepare();
                                } catch (IllegalStateException e) {
                                    e.printStackTrace();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                                recorder.start();
                                recordstarted = true;
                            }
                        } else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                            wasRinging = false;
                            Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
                            if (recordstarted) {
                                recorder.stop();
                                recordstarted = false;
                            }
                        }
                    }
                } else if (intent.getAction().equals(ACTION_OUT)) {
                    if ((bundle = intent.getExtras()) != null) {
                        didMakeACall = true;
                        outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
                        Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();
                    }
                }
            }
        }
    
    }
    

    【讨论】:

    • 你用的是什么设备?
    • htc 渴望 820g 运行 kitkat 和模拟器运行棒棒糖,如果你有问题我可以做一个 github 项目并与你分享
    • 我正在使用模拟器 kitkat..google nexus 7 api 级别 4.4.4。在这它不起作用
    • 如果我没记错的话,Nexus 7 没有蜂窝网络连接,那么你是怎么打电话的?尝试使用其他模拟器,我相信它会工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多