今天,和朋友讨论了一下自动接听的需求,实现自动接听,肯定使用了TelephonyManager的监听,但是发现并没有对应的方法实现接听动作。
然后上网寻找思路,感谢点击打开链接,这篇blog里面提供了TelephonyManager和ITelephony类的方法,ITelephony的answerRingingCall()方法可以实现接听功能,但是测试在4.1以后,无法使用。因为在较高版本,google对<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"></uses-permission> 权限的获取做出了限制。
所以,只能另辟蹊径--欺骗系统,模拟耳机接听。
核心思路:模拟动作
1,插入耳机动作(拨出耳机同理)
<span style="white-space:pre"> </span> Intent pushIntent = new Intent(Intent.ACTION_HEADSET_PLUG);
pushIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
pushIntent.putExtra("state", 1);
pushIntent.putExtra("microphone", 1);
pushIntent.putExtra("name", "Headset");
sendOrderedBroadcast(pushIntent,"android.permission.CALL_PRIVILEGED");
上面这段实现了,耳机的插入动作,我们看一下framework里面 ACTION_HEADSET_PLUG的解释
/**
* Broadcast Action: Wired Headset plugged in or unplugged.
*
* <p>The intent will have the following extra values:
* <ul>
* <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
* <li><em>name</em> - Headset type, human readable string </li>
* <li><em>microphone</em> - 1 if headset has a microphone, 0 otherwise </li>
* </ul>
* </ul>
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_HEADSET_PLUG =
"android.intent.action.HEADSET_PLUG";
2,按下耳机接听键位的动作(松开按键同理)
<span style="font-size:14px;"> Intent downIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
KeyEvent keyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_HEADSETHOOK);
downIntent.putExtra("android.intent.extra.KEY_EVENT",keyEvent1);
sendOrderedBroadcast(downlIntent,"android.permission.CALL_PRIVILEGED");</span>
KeyEvent.KEYCODE_HEADSETHOOK的键位:耳机单按键的按键或三按键耳机的中间按键。与上面的按键可能是相同的,具体得看驱动定义。
Intent.ACTION_MEDIA_BUTTON的接受在哪里?
packages/apps/Phone/src/com/android/phone/xxx.java中定义了对于按键动作的响应。我手头没有源码,但是记得应该在这里。响应耳机的接听电话事件。
那么我们只要实现一个service就可以完全实现了自动接听,目前测试都OK,主要可能不同厂商对于耳机中具体对应接听的键位驱动不同会有所区别!
完整的service代码如下:
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.KeyEvent;
public class PhoneService extends Service {
private TelephonyManager tManager;
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
tManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
tManager.listen(new CallPhoneStateListener(), // 注册手机电话监听
CallPhoneStateListener.LISTEN_CALL_STATE);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
class CallPhoneStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
// TODO Auto-generated method stub
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:// 空闲
break;
case TelephonyManager.CALL_STATE_OFFHOOK:// 接听
break;
case TelephonyManager.CALL_STATE_RINGING:// 来电
try {
answerRingingCall();// 自动接听
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
default:
break;
}
}
private void answerRingingCall() {
// TODO Auto-generated method stub
// 放开耳机按钮 ,使用有序广播
Intent upIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
KeyEvent keyEvent2 = new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK);
upIntent.putExtra("android.intent.extra.KEY_EVENT", keyEvent2);
sendOrderedBroadcast(upIntent, "android.permission.CALL_PRIVILEGED");
// 插耳机
Intent pushIntent = new Intent(Intent.ACTION_HEADSET_PLUG);
pushIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
pushIntent.putExtra("state", 1);
pushIntent.putExtra("microphone", 1);
pushIntent.putExtra("name", "Headset");
sendOrderedBroadcast(pushIntent,"android.permission.CALL_PRIVILEGED");
// 按下耳机按钮
Intent localIntent2 = new Intent(Intent.ACTION_MEDIA_BUTTON);
KeyEvent localKeyEvent1 = new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_HEADSETHOOK);
localIntent2.putExtra("android.intent.extra.KEY_EVENT",
localKeyEvent1);
sendOrderedBroadcast(localIntent2,
"android.permission.CALL_PRIVILEGED");
// 放开耳机按钮
upIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
keyEvent2 = new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK);
upIntent.putExtra("android.intent.extra.KEY_EVENT", keyEvent2);
sendOrderedBroadcast(upIntent, "android.permission.CALL_PRIVILEGED");
// 拔出耳机 ,不然手机就一直保持插入耳机状态
Intent pullIntent = new Intent(Intent.ACTION_HEADSET_PLUG);
pullIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
pullIntent.putExtra("state", 0);
pullIntent.putExtra("microphone", 1);
pullIntent.putExtra("name", "Headset");
sendOrderedBroadcast(pullIntent,
"android.permission.CALL_PRIVILEGED");
}
}
}