Android中自动接听电话的功能

最近,需要完成一个自动化测试工具,来测试一些模块的功能,其中有些功能需要接通电话后才可以使用,因为这个工具是完全自动化的,所以需要处理自动接听电话


在4.1以前Android是提供了接口可以直接调用接听电话的,而4.1以后google增加了访问控制,普通应用通过正常手段是无法实现该功能,因此,我们通过以下方法实现,比较简单。但注意,此方法编译的apk需要系统签名。


自动接听电话的接口answerRingingCall()定义在ITelephony.aidl之中,ITelephony.aidl为隐藏接口。本来TelephonyManager类中有方法getITelephony()可以或得到ITelephony的实例,但getITelephony()同样是隐藏方法,由于我们想直接在Eclipse编译apk,而不是在源码中编译,所以,我们将ITelephony.aidl拷贝到我们工程,进行改造后使用反射机制来调用answerRingingCall()方法。


首先,在工程中创建package,注意,目录必须和ITelephony.aidl所在源码路径一致,即com.android.internal.telephony,将ITelephony.aidl放在该目录下,去掉隐藏标签,提取需要使用的方法,类似如下代码:


package com.android.internal.telephony; 

import android.os.Bundle; 
interface ITelephony { 
    boolean endCall(); 
    void dial(String number); 
    void answerRingingCall(); 
}

接着在AndroidManifest.xml中添加权限:


    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

以上权限的意思,一目了然,因为“android.permission.MODIFY_PHONE_STATE"  权限是系统权限,所以apk才需要系统签名。


准备工作完成后,就可以编写代码了:


public class MainActivity extends Activity {

    private static final String LOG_TAG = MainActivity.class.getName();
    private ITelephony mTelephonyService;

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

        try {
            TelephonyManager telephony = (TelephonyManager) getApplication()
                    .getSystemService(Context.TELEPHONY_SERVICE);
            telephony.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
            Class<?> c = Class.forName(telephony.getClass().getName());

            Method m = c.getDeclaredMethod("getITelephony");
            m.setAccessible(true);

            mTelephonyService = (ITelephony) m.invoke(telephony);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    class MyPhoneStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            switch (state) {
            case TelephonyManager.CALL_STATE_RINGING:
                Log.i(LOG_TAG, "[Listener] Ringing State:" + incomingNumber);
                if (mTelephonyService != null) {
                    try {
                        mTelephonyService.answerRingingCall();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case TelephonyManager.CALL_STATE_IDLE:
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                break;
            }
            super.onCallStateChanged(state, incomingNumber);
        }
    }

代码比较简单,首先获取TelephonyManager对象,向该对象中注册监听电话状态的listener,然后就用反射获取ITelephony对象。接下来实现listener的onCallStateChanged() 回调方法处理不同电话状态,在响铃状态调用answerRingingCall()方法就可以了。

对于电话的各种状态,android对普通应用提供的比较粗略,需要查看更详细的状态的话需要查看PreciseCallState类,但很不幸,这个类也是隐藏的。


另外,也可以通过receiver代替注册listener进行以上处理,整个实现代码的地址为:http://download.csdn.net/detail/u010538765/9743406


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值