前文已经介绍了基本的android对系统事件的监听,假如对这些还不了解的请移步:Android监听器实现(一)Broadcast方式监听系统事件

因为目前我写的一个应用需要对通话挂断进行处理,经过对api和网上资料的查询,发现对通话状态的监听只有3种:

public static final int CALL_STATE_IDLE = 0 //无通话状态public static final int CALL_STATE_RINGING = 1 //响铃状态public static final int CALL_STATE_OFFHOOK = 2 //通话中

经过查资料发现官方没有提供对通话结束的api,但是通过对于通话状态改变的通知不能够满足我对于挂机的处理,那我们先分析一下如何能够更精细的获得当前通话状态(来电,通话,挂机)。

1、我们要取得当前通话状态

2、取得之前通话状态

3、对这两个状态进行对比

针对于这些分析过程,我们需要保存之前的通话状态,这个可以通过各种方式实现(文件流、sqiite等等),我是使用sqiite方式实现的,主要是因为我写的项目需要使用到sqlite,所以干脆直接拿来用了。对于不熟悉这些的童鞋可以使用文件流或者其他的方式。有些童鞋会问:“为什么不直接在Broadcast类中使用一个静态变量保留原通话状态?”。这是因为每次系统通话状态发生改变之后会调用broadcast类的onrecieve()方法,方法执行完就被系统回收了,每次都是重新创建出来的类,所以每次这个变量都是初始值。

好了,废话不多说了,我们直接上代码,本次我使用的依然是上次文章中的源码,所以我只写出本例中的关键部分,其他的请各位看下面下载链接中的源码。


package com.ls.broadcast;import com.ls.broadcast.util.SqliteUtil;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.telephony.PhoneStateListener;import android.telephony.TelephonyManager;/** * 系统事件监听器监听器 * * @author ls * @version 2013-07-29 8:18 * */public class MyPhoneBroadcastListener extends BroadcastReceiver {    /**     * 手机没有通话,在一般的状态值     */    public static final int CALL_TYPE_IDEL = 0;    /**     * 手机通话状态值     */    public static final int CALL_TYPE_CALLING = 1;    /**     * 手机响铃状态值     */    public static final int CALL_TYPE_RING = 2;                                                                                                                             /**     * 当前手机通话状态值     */    private int currentState = CALL_TYPE_IDEL ;    /**     * 手机原来的通话状态值     */    private int oldState = CALL_TYPE_IDEL ;                                                                                                                             /**     * 数据库Helper类,只是帮助我们存取状态值,可以改成用文件流实现     */    private SqliteUtil sqlUtil = null;    private MyPhoneListener listener;    @Override//当发生监听的事件,系统会调用这个方法    public void onReceive(Context context, Intent intent) {        //进行细节上的监控,我们需要操作TelephonyManager,为它设置监听器,他就给我们反馈        //拿到系统的TelephonyManager        TelephonyManager tpManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);        listener = new MyPhoneListener();//创建监听器        tpManager.listen( listener, PhoneStateListener.LISTEN_CALL_STATE);//设置监听器                                                                                                                                     sqlUtil = new SqliteUtil(context);    }    private class MyPhoneListener extends PhoneStateListener {        @Override//当电话状态发生改变的时候,系统会调用这个方法        public void onCallStateChanged(int state, String incomingNumber) {            //首先取得当前的状态值            oldState = sqlUtil.getOldState();                                                                                                                                             switch( state ){            case TelephonyManager.CALL_STATE_IDLE :                currentState = CALL_TYPE_IDEL;                break;            case TelephonyManager.CALL_STATE_OFFHOOK :                currentState = CALL_TYPE_CALLING;                break;            case TelephonyManager.CALL_STATE_RINGING :                currentState = CALL_TYPE_RING;                break;            }            //当通话状态发生改变            if( oldState == CALL_TYPE_RING && currentState == CALL_TYPE_CALLING ){                System.out.println( "接听" );            } else if( oldState == CALL_TYPE_CALLING && currentState == CALL_TYPE_IDEL ){                System.out.println( "挂断" );            } if( oldState == CALL_TYPE_IDEL && currentState == CALL_TYPE_CALLING ){                System.out.println( "拨号" );            }                                                                                                                                             sqlUtil.updateState( currentState);        }    }}


本例子中的sqlutil是专门对上次通话状态进行存储和读取的,为了与当前状态进行对比分析的,假如童鞋们对sqiite方面的处理不是很了解,请大家换成自己熟悉的实现方式。


2、SqliteUtil类


package com.ls.broadcast.util;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import com.ls.broadcast.MyPhoneBroadcastListener;/** * 数据库帮助类 * @author ls * @version 2013-08-02 9:07 */public class SqliteUtil extends SQLiteOpenHelper {                                                private static final String DB_NAME = "broadcast.db";    private static final String TABLE_NAME = "config";    private SQLiteDatabase db = null;                                                                                            public SqliteUtil(Context context ) {        super(context, DB_NAME, null, 1);        // TODO Auto-generated constructor stub    }    public int getOldState(){        int state = 0;        db = getReadableDatabase();        Cursor cursor = db.rawQuery("select * from " + TABLE_NAME , null);        if( cursor.moveToFirst() ){            state = cursor.getInt( cursor.getColumnIndex("flag") );        }        db.close();        return state;    }                                                public void updateState(int state ){        db = getWritableDatabase();        db.beginTransaction();        db.execSQL("update " + TABLE_NAME + " set flag=" + state);        db.setTransactionSuccessful();        db.endTransaction();        db.close();    }                                                /**     * 第一次创建数据库(即DB_NAME这个数据库在机器上面不存在)的时候调用     * <br>系统会帮你创建DB_NAME这个数据库文件,你只需用建表就行了。     */    @Override    public void onCreate(SQLiteDatabase db) {        // TODO Auto-generated method stub        this.db = db;        db.execSQL("create table " + TABLE_NAME + "(flag Integer)");        db.execSQL("insert into " + TABLE_NAME + " values(" + MyPhoneBroadcastListener.CALL_TYPE_IDEL + ")");    }    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {        // TODO Auto-generated method stub    }}

android通话状态监听源码

更多相关文章

  1. Android系统刷机常用名词解析
  2. Android 系统编译与调试
  3. 源码角度分析Android的事件输入系统(input system)及ANR原理分析
  4. android音频系统音量控制探讨
  5. Android系统级深入开发输入系统
  6. 如何设置Android 系统的属性,Build.prop, defualt.prop

随机推荐

  1. Android(安卓)Studio Build Output 汉字
  2. 模拟器上调试android launcher---android
  3. Android系统开篇
  4. Android(安卓)Edittext 手机号码格式输入
  5. Android源码(9) --- Binder(3) AIDL使用
  6. Android(安卓)Studio安装和虚拟机的安装
  7. Android(安卓)Media Framework(3): Stage
  8. Android事件传递
  9. 软键盘android:windowSoftInputMode属性
  10. (Android)react-native解决 ToastAndroid(