现在的位置: 首页 > 综合 > 正文

14.探秘TelephonyManager

2017年12月05日 ⁄ 综合 ⁄ 共 8645字 ⁄ 字号 评论关闭

上次介绍了如何使用JAVA的反射机制来调用蓝牙的隐藏API,这次继续练习JAVA的反射机制,探秘TelephonyManager在Framework里包含却在SDK隐藏的几项功能。先来看看本文程序运行的效果图:

testTelephony

本文程序演示了以下功能:

1.所有来电自动接听;

2.所有来电自动挂断;

3.开启/关闭Radio;

4.开启/关闭数据连接(WAP or NET的连接)。

调用TelephonyManager的隐藏API是先参考Framework的/base/telephony/java/com/android/internal/telephony/ITelephony.aidl,然后自己实现一个ITelephony.aidl,最后在TelephonyManager中通过反射机制实例化自定义的ITelephony,实例化之后就可以调用ITelephony里面的函数了。

本文程序需要在AndroidManifest.xml添加以下两行代码,以获得权限:

?
1
2
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />

main.xml源码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
 
    <RadioGroup
        android:id="@+id/rGrpSelect"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
 
        <RadioButton
            android:id="@+id/rbtnAutoAccept"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="所有来电自动接听" >
        </RadioButton>
 
        <RadioButton
            android:id="@+id/rbtnAutoReject"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="所有来电自动挂断" >
        </RadioButton>
    </RadioGroup>
 
    <ToggleButton
        android:id="@+id/tbtnRadioSwitch"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textOff="Radio已经关闭"
        android:textOn="Radio已经启动"
        android:textSize="24dip"
        android:textStyle="normal" >
    </ToggleButton>
 
    <ToggleButton
        android:id="@+id/tbtnDataConn"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textOff="禁止数据连接"
        android:textOn="允许数据连接"
        android:textSize="24dip"
        android:textStyle="normal" >
    </ToggleButton>
 
</LinearLayout>

PhoneUtils.java是手机功能类,从TelephonyManager中实例化ITelephony并返回,源码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.testTelephony;
 
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.android.internal.telephony.ITelephony;
import android.telephony.TelephonyManager;
import android.util.Log;
 
public class PhoneUtils
{
    /**
     *
从TelephonyManager中实例化ITelephony,并返回
     */
    static public ITelephony
getITelephony(TelephonyManager telMgr)
            throws Exception
{
        Method
getITelephonyMethod = telMgr.getClass().getDeclaredMethod(
                "getITelephony");
        getITelephonyMethod.setAccessible(true);//
私有化函数也能使用
        return (ITelephony)
getITelephonyMethod.invoke(telMgr);
    }
 
    static public void printAllInform(Class
clsShow) {
        try {
            //
取得所有方法
            Method[]
hideMethod = clsShow.getDeclaredMethods();
            int i
0;
            for (;
i < hideMethod.length; i++) {
                Log.e("method
name"
,
hideMethod[i].getName());
            }
            //
取得所有常量
            Field[]
allFields = clsShow.getFields();
            for (i
0;
i < allFields.length; i++) {
                Log.e("Field
name"
,
allFields[i].getName());
            }
        catch (SecurityException
e) {
            //
throw new RuntimeException(e.getMessage());
            e.printStackTrace();
        catch (IllegalArgumentException
e) {
            //
throw new RuntimeException(e.getMessage());
            e.printStackTrace();
        catch (Exception
e) {
            //
TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

testTelephony.java是主类,使用PhoneStateListener监听通话状态,以及实现上述4种电话控制功能,源码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package com.testTelephony;
 
import android.app.Activity;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.widget.RadioGroup;
import android.widget.ToggleButton;
 
public class testTelephony extends Activity
{
    /**
Called when the activity is first created. */
    RadioGroup
rg;
//
来电操作单选框
    ToggleButton
tbtnRadioSwitch;
//
Radio开关
    ToggleButton
tbtnDataConn;
//
数据连接的开关
    TelephonyManager
telMgr;
    CallStateListener
stateListner;
    int checkedId
0;
 
    @Override
    public void onCreate(Bundle
savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        telMgr
= (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        telMgr.listen(new CallStateListener(),
                CallStateListener.LISTEN_CALL_STATE);
 
        PhoneUtils.printAllInform(TelephonyManager.class);
 
        rg
= (RadioGroup) findViewById(R.id.rGrpSelect);
        rg.setOnCheckedChangeListener(new CheckEvent());
        tbtnRadioSwitch
= (ToggleButton) 
this
                .findViewById(R.id.tbtnRadioSwitch);
        tbtnRadioSwitch.setOnClickListener(new ClickEvent());
        try {
            tbtnRadioSwitch.setChecked(PhoneUtils.getITelephony(telMgr)
                    .isRadioOn());
        catch (Exception
e) {
            Log.e("error",
e.getMessage());
        }
        tbtnDataConn
= (ToggleButton) 
this.findViewById(R.id.tbtnDataConn);
        tbtnDataConn.setOnClickListener(new ClickEvent());
        try {
            tbtnDataConn.setChecked(PhoneUtils.getITelephony(telMgr)
                    .isDataConnectivityPossible());
        catch (Exception
e) {
            Log.e("error",
e.getMessage());
        }
    }
 
    /**
     *
来电时的操作
     *
     *
@author GV
     *
     */
    public class CheckEvent implements RadioGroup.OnCheckedChangeListener
{
 
        @Override
        public void onCheckedChanged(RadioGroup
group, 
int checkedId)
{
            testTelephony.this.checkedId
= checkedId;
        }
    }
 
    /**
     *
Radio和数据连接的开关
     *
     *
@author GV
     *
     */
    public class ClickEvent implements View.OnClickListener
{
 
        @Override
        public void onClick(View
v) {
            if (v
== tbtnRadioSwitch) {
                try {
                    PhoneUtils.getITelephony(telMgr).setRadio(
                            tbtnRadioSwitch.isChecked());
                catch (Exception
e) {
                    Log.e("error",
e.getMessage());
                }
            else if (v
== tbtnDataConn) {
                try {
                    if (tbtnDataConn.isChecked())
                        PhoneUtils.getITelephony(telMgr)
                                .enableDataConnectivity();
                    else if (!tbtnDataConn.isChecked())
                        PhoneUtils.getITelephony(telMgr)
                                .disableDataConnectivity();
                catch (Exception
e) {
                    Log.e("error",
e.getMessage());
                }
            }
        }
    }
 
    /**
     *
监视电话状态
     *
     *
@author GV
     *
     */
    public class CallStateListener extends PhoneStateListener
{
        @Override
        public void onCallStateChanged(int state,
String incomingNumber) {
            if (state
== TelephonyManager.CALL_STATE_IDLE)
//
挂断
            {
                Log.e("IDLE",
incomingNumber);
            else if (state
== TelephonyManager.CALL_STATE_OFFHOOK)
//
接听
            {
                Log.e("OFFHOOK",
incomingNumber);
            else if (state
== TelephonyManager.CALL_STATE_RINGING)
//
来电
            {
                if (testTelephony.this.checkedId
== R.id.rbtnAutoAccept) {
                    try {
                        //
需要<uses-permission
                        //
android:name="android.permission.MODIFY_PHONE_STATE"
                        //
/>
                        PhoneUtils.getITelephony(telMgr).silenceRinger();//
静铃
                        PhoneUtils.getITelephony(telMgr).answerRingingCall();//
自动接听
 
                    catch (Exception
e) {
                        Log.e("error",
e.getMessage());
                    }
                else if (testTelephony.this.checkedId
== R.id.rbtnAutoReject) {
                    try {
                        PhoneUtils.getITelephony(telMgr).endCall();//
挂断
                        PhoneUtils.getITelephony(telMgr)
                                .cancelMissedCallsNotification();//
取消未接显示
                    catch (Exception
e) {
                        Log.e("error",
e.getMessage());
                    }
                }
            }
            super.onCallStateChanged(state,
incomingNumber);
        }
    }
}

抱歉!评论已关闭.