4.1版本以后,利用耳机按键广播实现自动接听电话

        今天,和朋友讨论了一下自动接听的需求,实现自动接听,肯定使用了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";


上面,我可以看到Intent中的Extra的数据的必要性了。


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");
		}

	}
}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值