level 4
笑嘻嘻的Acº
楼主
如题,我想要做一个小案例:监听电话状态,当电话接通时开启MediaRecorder录音并保存文件,可是却报了空指针异常。
package com.example.cellphone;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
//四大组件记得在清单中配置
public class PhoneService extends Service {
// MediaRecorder recorder 定义在这里,方便取用
private MediaRecorder recorder;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
System.out.println("一!!!");
// 1、获取TelephoneManager实例
TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
// 2、注册电话监听
/*
* tm.listen(listener, events):Registers a listener object to receive
* notification of changes in specified telephony states.
* 注册一个监听器以获取当指定的电话发生状态改变时的通知。
* listener:PhoneStateListener类型:该类可以监视指定电话状态的改变
* events:监听的事件,这里使用PhoneStateListener.LISTEN_CALL_STATE:状态监听
*/
tm.listen(new MyPhoneStateListener(),
PhoneStateListener.LISTEN_CALL_STATE);
super.onCreate();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
class MyPhoneStateListener extends PhoneStateListener {
// 当电话状态改变时调用此方法
@Override
public void onCallStateChanged(int state, String incomingNumber) {
// 3、判断电话状态
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: // 空闲状态
System.out.println("二!!!");
if (recorder != null) {
// 停止录
recorder.stop();
// 重置录音机
recorder.reset(); // You can reuse the object by going back
// to setAudioSource() step
// 释放资源
recorder.release(); // Now the object cannot be reused
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK: // 摘机状态——即接听状态
// 3.7.开始录音
recorder.start(); // Recording is now started
break;
case TelephonyManager.CALL_STATE_RINGING: // 响铃状态
System.out.println("三!!!");
// 3.1创建录音机实例
recorder = new MediaRecorder();
// 3.2.设置音频来源:MIC为麦克风,还可以使用VOICE_CALL。MIC录单方通话,后者录双方通话。
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 3.3.设置录音文件格式,这里为THREE_GPP(其实为视频格式)
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
// 3.4.设置音频的编码格式:默认用AMR_NB
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
// 3.5.设置录音文件存放的路径:这里保存到sdcard/recond1.3gp
recorder.setOutputFile("/mnt/sdcard/recond1.3gp");
// 3.6.准备录
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
super.onCallStateChanged(state, incomingNumber);
}
}
}
代码格式有点乱。
报错图:

实在找不出原因,请求帮助。
使用ecplice,使用Genymotion 4.4.2的模拟器(也试了真机调试)。在模拟器上进行的是拨打电话而非接听电话操作,
一拨打就奔溃并报错,图中三处syso只能输出“一!!!”和“二!!!”,也就是能执行到onCreate()方法和
case TelephonyManager.CALL_STATE_IDLE: // 空闲状态 这段代码。
求助。
2017年05月18日 01点05分
1
package com.example.cellphone;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
//四大组件记得在清单中配置
public class PhoneService extends Service {
// MediaRecorder recorder 定义在这里,方便取用
private MediaRecorder recorder;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
System.out.println("一!!!");
// 1、获取TelephoneManager实例
TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
// 2、注册电话监听
/*
* tm.listen(listener, events):Registers a listener object to receive
* notification of changes in specified telephony states.
* 注册一个监听器以获取当指定的电话发生状态改变时的通知。
* listener:PhoneStateListener类型:该类可以监视指定电话状态的改变
* events:监听的事件,这里使用PhoneStateListener.LISTEN_CALL_STATE:状态监听
*/
tm.listen(new MyPhoneStateListener(),
PhoneStateListener.LISTEN_CALL_STATE);
super.onCreate();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
class MyPhoneStateListener extends PhoneStateListener {
// 当电话状态改变时调用此方法
@Override
public void onCallStateChanged(int state, String incomingNumber) {
// 3、判断电话状态
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: // 空闲状态
System.out.println("二!!!");
if (recorder != null) {
// 停止录
recorder.stop();
// 重置录音机
recorder.reset(); // You can reuse the object by going back
// to setAudioSource() step
// 释放资源
recorder.release(); // Now the object cannot be reused
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK: // 摘机状态——即接听状态
// 3.7.开始录音
recorder.start(); // Recording is now started
break;
case TelephonyManager.CALL_STATE_RINGING: // 响铃状态
System.out.println("三!!!");
// 3.1创建录音机实例
recorder = new MediaRecorder();
// 3.2.设置音频来源:MIC为麦克风,还可以使用VOICE_CALL。MIC录单方通话,后者录双方通话。
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 3.3.设置录音文件格式,这里为THREE_GPP(其实为视频格式)
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
// 3.4.设置音频的编码格式:默认用AMR_NB
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
// 3.5.设置录音文件存放的路径:这里保存到sdcard/recond1.3gp
recorder.setOutputFile("/mnt/sdcard/recond1.3gp");
// 3.6.准备录
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
super.onCallStateChanged(state, incomingNumber);
}
}
}
代码格式有点乱。
报错图:

实在找不出原因,请求帮助。使用ecplice,使用Genymotion 4.4.2的模拟器(也试了真机调试)。在模拟器上进行的是拨打电话而非接听电话操作,
一拨打就奔溃并报错,图中三处syso只能输出“一!!!”和“二!!!”,也就是能执行到onCreate()方法和
case TelephonyManager.CALL_STATE_IDLE: // 空闲状态 这段代码。
求助。