Android 去电状态判断 录音

来源:互联网 发布:家电销售数据 编辑:程序博客网 时间:2024/06/01 10:38

产品提了一个人让人头大的项目,让人很郁闷,让判断用户打电话是否打通,这让我好生郁闷,我记得Android里面好像有对来电有状态的判断,而对去电没有吧。还是说我孤陋寡闻了,赶紧上网找资料,找了好半天,终于找到了一些相关的资料。好了,废话不多说,直接来看看怎么实现的吧。
首先用广播监听,(这里补充一点,不会广播的孩子,可以看看广播的相关资料,这里不多说),具体的代码实现如下:
PhonecallReceiver.java文件

public abstract class PhonecallReceiver extends BroadcastReceiver {    //The receiver will be recreated whenever android feels like it.  We need a static variable to remember data between instantiations    private static int lastState = TelephonyManager.CALL_STATE_IDLE;    private static Date callStartTime;    private static boolean isIncoming;    private static String savedNumber;  //because the passed incoming is only valid in ringing    @Override    public void onReceive(Context context, Intent intent) {        //We listen to two intents.  The new outgoing call only tells us of an outgoing call.  We use it to get the number.        if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {            savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");            Log.e("TAG","===savedNumber==="+savedNumber);        }        else{            String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);            String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);            int state = 0;            if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)){                state = TelephonyManager.CALL_STATE_IDLE;            }            else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){                state = TelephonyManager.CALL_STATE_OFFHOOK;            }            else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){                state = TelephonyManager.CALL_STATE_RINGING;            }            onCallStateChanged(context, state, number);        }    }    //Derived classes should override these to respond to specific events of interest    protected abstract void onIncomingCallReceived(Context ctx, String number, Date start);    protected abstract void onIncomingCallAnswered(Context ctx, String number, Date start);    protected abstract void onIncomingCallEnded(Context ctx, String number, Date start, Date end);    protected abstract void onOutgoingCallStarted(Context ctx, String number, Date start);    protected abstract void onOutgoingCallEnded(Context ctx, String number, Date start, Date end);    protected abstract void onMissedCall(Context ctx, String number, Date start);    //Deals with actual events    //Incoming call-  goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up    //Outgoing call-  goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up    public void onCallStateChanged(Context context, int state, String number) {        if(lastState == state){            //No change, debounce extras            return;        }        switch (state) {            case TelephonyManager.CALL_STATE_RINGING:                isIncoming = true;                callStartTime = new Date();                savedNumber = number;                onIncomingCallReceived(context, number, callStartTime);                break;            case TelephonyManager.CALL_STATE_OFFHOOK:                //Transition of ringing->offhook are pickups of incoming calls.  Nothing done on them                if(lastState != TelephonyManager.CALL_STATE_RINGING){                    isIncoming = false;                    callStartTime = new Date();                    onOutgoingCallStarted(context, savedNumber, callStartTime);                }                else                {                    isIncoming = true;                    callStartTime = new Date();                    onIncomingCallAnswered(context, savedNumber, callStartTime);                }                break;            case TelephonyManager.CALL_STATE_IDLE:                //Went to idle-  this is the end of a call.  What type depends on previous state(s)                if(lastState == TelephonyManager.CALL_STATE_RINGING){                    //Ring but no pickup-  a miss                    onMissedCall(context, savedNumber, callStartTime);                }                else if(isIncoming){                    onIncomingCallEnded(context, savedNumber, callStartTime, new Date());                }                else{                    onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());                }                break;        }        lastState = state;    }}

具体的的在开发中直接继承这个抽象类就OK,看看下面的具体实现。
CallReceiver.java 文件

public class CallReceiver extends PhonecallReceiver {    @Override    protected void onIncomingCallReceived(Context ctx, String number, Date start) {    }    @Override    protected void onIncomingCallAnswered(Context ctx, String number, Date start) {    }    @Override    protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {    }    @Override    protected void onOutgoingCallStarted(Context ctx, String number, Date start) {//        去电的时候调用这个方法,,打通的时候调用,具体的根据自己的项目需求来实现    }    @Override    protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {//        这里处理,挂断的相关操作,    }    @Override    protected void onMissedCall(Context ctx, String number, Date start) {    }}

如果,有的同学需要对,拨打电话的状态监听录音,可以根据自己的需求来实现录音功能,下面给出录音的代码。

public class CustomRecorder {    private String phoneNumber;    private MediaRecorder mrecorder;    private boolean started = false; //录音机是否已经启动    private boolean isCommingNumber = false;//是否是来电    private String TAG = "Recorder";    public CustomRecorder(String phoneNumber) {        this.setPhoneNumber(phoneNumber);    }    public CustomRecorder() {    }    public void start() {        started = true;        mrecorder = new MediaRecorder();        File recordPath = new File(                Environment.getExternalStorageDirectory()                , "/CustomRecorder");        if (!recordPath.exists()) {            recordPath.mkdirs();            Log.d("recorder", "创建目录");        }        String callDir = "呼出";        if (isCommingNumber) {            callDir = "呼入";        }        String fileName = callDir + "-" + phoneNumber + "-"                + new SimpleDateFormat("yy-MM-dd_HH-mm-ss")                .format(new Date(System.currentTimeMillis())) + ".mp3";//实际是3gp        File recordName = new File(recordPath, fileName);        try {            recordName.createNewFile();            Log.d("recorder", "创建文件" + recordName.getName());        } catch (IOException e) {            e.printStackTrace();        }        mrecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);        mrecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);        mrecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);        mrecorder.setOutputFile(recordName.getAbsolutePath());        try {            mrecorder.prepare();        } catch (IllegalStateException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        mrecorder.start();        started = true;        Log.d(TAG , "录音开始");    }    public void stop() {        try {            if (mrecorder!=null) {                mrecorder.stop();                mrecorder.release();                mrecorder = null;            }            started = false;        } catch (IllegalStateException e) {            e.printStackTrace();        }        Log.d(TAG , "录音结束");    }    public void pause() {    }    public String getPhoneNumber() {        return phoneNumber;    }    public void setPhoneNumber(String phoneNumber) {        this.phoneNumber = phoneNumber;    }    public boolean isStarted() {        return started;    }    public void setStarted(boolean hasStarted) {        this.started = hasStarted;    }    public boolean isCommingNumber() {        return isCommingNumber;    }    public void setIsCommingNumber(boolean isCommingNumber) {        this.isCommingNumber = isCommingNumber;    }}

下面主要的是权限问题,直接在AndroidManifest.xml文件中加入相关的代码。

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />    <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"/>    <!-- 要存储文件或者创建文件夹的话还需要以下两个权限 -->    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

前面说了一大堆东西,主要的还没有完成,是什么呢???
当然是广播的注册呀,主要的注册都没有,怎么监听啊,对吧,看下面吧。

<!--电话的广播-->        <!--This part is inside the application-->        <receiver android:name=".receiver.CallReceiver" >            <intent-filter>                <action android:name="android.intent.action.PHONE_STATE" />            </intent-filter>            <intent-filter>                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />            </intent-filter>        </receiver>

最后,需要在activity里面做相关的打电话操作,算了,也就这么几行代码,也弄出来吧,方便后面学习的人参考。

  // 检查是否获得了权限(Android6.0运行时权限)        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {            // 没有获得授权,申请授权            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.CALL_PHONE)) {                Toast.makeText(MainActivity.this, "请授权!", Toast.LENGTH_LONG).show();                // 帮跳转到该应用的设置界面,让用户手动授权                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);                Uri uri = Uri.fromParts("package", getPackageName(), null);                intent.setData(uri);                startActivity(intent);            } else {                // 不需要解释为何需要该权限,直接请求授权                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE);            }        } else {            CallPhone();            Intent intent = new Intent();            intent.setAction(Intent.ACTION_CALL);            intent.setData(Uri.parse("tel:" + "你的电话号码"));            startActivity(intent);        }

好了,到此就算结束了,希望能帮到各位啊,
欢迎大家发表意见。

阅读全文
1 0
原创粉丝点击