android 5.0 6.0系统实现app自动接听电话功能
1.前言:
最近公司有个需求,需要在app某个指定页面实现自动接听电话功能。当时我在想啊,这应该是一个黑科技功能吧,于是我网上找了好长时间,发现网上那些方法4.4以上系统不支持啊,当时我也是一脸懵逼啊,不过没事,我还是找到了解决办法,但是….(别急慢慢往下看哈)……,咱们先来看下4.4以下系统是如何实现自动接听功能的。
第一步:准备应用环境需要的系统包和aidl文件。
(1)在应用中创建包:android.telephony
将android系统框架下的\framework\telephony\java\android\telephony目录中的NeighboringCellInfo.aidl文件复制到上面创建的包(android.telephony )中;
(2)在应用中创建包:com.android.internal.telephony
将android系统框架下的\framework\telephony\java\com\android\internal\telephony目录中的ITelephony.aidl文件复制到上面创建的包(com.android.internal.telephony )中;
第二步:新建一个广播PhoneReceiver类
package com.newshangman.org.Receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.KeyEvent;
import com.android.internal.telephony.ITelephony;
import com.newshangman.org.xutils.PhoneUtils;
import java.io.IOException;
import java.lang.reflect.Method;
import static android.R.attr.version;
import static android.content.Context.TELEPHONY_SERVICE;
public class PhoneReceiver extends BroadcastReceiver {
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
try {
if (count == 0) {
// PhoneUtils.autoAnswerPhone(mContext, mIntent);
autoAnswerPhone(mContext, mIntent);
// autoAnswerPhone1(mContext, mIntent);
// autoAnswerPhone2(mContext, mIntent);
// autoAnswerPhone3(mContext, mIntent);
// autoAnswerPhone4(mContext, mIntent);
// autoAnswerPhone5(mContext, mIntent);
count++;
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
};
private Context mContext = null;
private TelephonyManager mIntent = null;
private int count = 0;
@Override
public void onReceive(Context context, Intent intent) {
mContext = context;
TelephonyManager tm = (TelephonyManager) context
.getSystemService(TELEPHONY_SERVICE);
mIntent = tm;
switch (tm.getCallState()) {
case TelephonyManager.CALL_STATE_OFFHOOK:
break;
case TelephonyManager.CALL_STATE_RINGING:
Message message = handler.obtainMessage();
message.obj = "33";
handler.sendMessage(message);
break;
case TelephonyManager.CALL_STATE_IDLE:
break;
}
}
public void setStopCALLPhone() {
PhoneUtils.endPhone(mContext, mIntent);
}
// 自动接听4.1以下
private static final void autoAnswerPhone(Context c, TelephonyManager tm) {
try {
java.lang.reflect.Method declaredMethod = tm.getClass()
.getDeclaredMethod("getITelephony");
declaredMethod.setAccessible(true);
ITelephony itelephony = (ITelephony) declaredMethod.invoke(tm);
if (itelephony != null) {
itelephony.answerRingingCall();
}
} catch (Exception e) {
try {
Intent intent = new Intent("android.intent.action.MEDIA_BUTTON");
KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_HEADSETHOOK);
intent.putExtra("android.intent.extra.KEY_EVENT", keyEvent);
c.sendOrderedBroadcast(intent,
"android.permission.CALL_PRIVILEGED");
intent = new Intent("android.intent.action.MEDIA_BUTTON");
keyEvent = new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK);
intent.putExtra("android.intent.extra.KEY_EVENT", keyEvent);
c.sendOrderedBroadcast(intent,
"android.permission.CALL_PRIVILEGED");
e.printStackTrace();
} catch (Exception e3) {
try {
Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG);
localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
localIntent4.putExtra("state", 0);
localIntent4.putExtra("microphone", 1);
localIntent4.putExtra("name", "Headset");
c.sendOrderedBroadcast(localIntent4,
"android.permission.CALL_PRIVILEGED");
e3.printStackTrace();
} catch (Exception e4) {
try {
Intent localIntent3 = new Intent(
Intent.ACTION_MEDIA_BUTTON);
KeyEvent localKeyEvent2 = new KeyEvent(
KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK);
localIntent3.putExtra("android.intent.extra.KEY_EVENT",
localKeyEvent2);
c.sendOrderedBroadcast(localIntent3,
"android.permission.CALL_PRIVILEGED");
e4.printStackTrace();
} catch (Exception e5) {
try {
Intent localIntent1 = new Intent(
Intent.ACTION_HEADSET_PLUG);
localIntent1
.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
localIntent1.putExtra("state", 1);
localIntent1.putExtra("microphone", 1);
localIntent1.putExtra("name", "Headset");
c.sendOrderedBroadcast(localIntent1,
"android.permission.CALL_PRIVILEGED");
e5.printStackTrace();
} catch (Exception e6) {
try {
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);
c.sendOrderedBroadcast(localIntent2,
"android.permission.CALL_PRIVILEGED");
e6.printStackTrace();
} catch (Exception e7) {
try {
Intent meidaButtonIntent = new Intent(
Intent.ACTION_MEDIA_BUTTON);
KeyEvent keyEvent = new KeyEvent(
KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK);
meidaButtonIntent.putExtra(
Intent.EXTRA_KEY_EVENT, keyEvent);
c.sendOrderedBroadcast(meidaButtonIntent,
null);
e7.printStackTrace();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
}
}
}
}
// // 自动接听
// private static final void autoAnswerPhone(Context c, TelephonyManager tm)
// {
// try {
// java.lang.reflect.Method declaredMethod = tm.getClass()
// .getDeclaredMethod("getITelephony");
// declaredMethod.setAccessible(true);
// ITelephony itelephony = (ITelephony) declaredMethod.invoke(tm);
// if (itelephony != null) {
// itelephony.answerRingingCall();
// }
// } catch (Exception e) {
// try {
// Intent intent = new Intent("android.intent.action.MEDIA_BUTTON");
// KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_DOWN,
// KeyEvent.KEYCODE_HEADSETHOOK);
// intent.putExtra("android.intent.extra.KEY_EVENT", keyEvent);
// c.sendOrderedBroadcast(intent,
// "android.permission.CALL_PRIVILEGED");
// intent = new Intent("android.intent.action.MEDIA_BUTTON");
// keyEvent = new KeyEvent(KeyEvent.ACTION_UP,
// KeyEvent.KEYCODE_HEADSETHOOK);
// intent.putExtra("android.intent.extra.KEY_EVENT", keyEvent);
// c.sendOrderedBroadcast(intent,
// "android.permission.CALL_PRIVILEGED");
// } catch (Exception e2) {
// }
// }
// }
// 自动接听
private static final void autoAnswerPhone1(Context c, TelephonyManager tm) {
try {
java.lang.reflect.Method declaredMethod = tm.getClass()
.getDeclaredMethod("getITelephony");
declaredMethod.setAccessible(true);
ITelephony itelephony = (ITelephony) declaredMethod.invoke(tm);
if (itelephony != null) {
itelephony.answerRingingCall();
}
} catch (Exception e) {
try {
Intent localIntent4 = new Intent(Intent.ACTION_HEADSET_PLUG);
localIntent4.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
localIntent4.putExtra("state", 0);
localIntent4.putExtra("microphone", 1);
localIntent4.putExtra("name", "Headset");
c.sendOrderedBroadcast(localIntent4,
"android.permission.CALL_PRIVILEGED");
} catch (Exception e2) {
}
}
}
/**
* 自动接听电话
*/
// private void autoAnswercall(){
// Intent meidaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
// KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK);
// meidaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT,keyEvent);
// TApplication.nowApplication.sendOrderedBroadcast(meidaButtonIntent, null);
// }
// 自动接听
private static final void autoAnswerPhone2(Context c, TelephonyManager tm) {
try {
java.lang.reflect.Method declaredMethod = tm.getClass()
.getDeclaredMethod("getITelephony");
declaredMethod.setAccessible(true);
ITelephony itelephony = (ITelephony) declaredMethod.invoke(tm);
if (itelephony != null) {
itelephony.answerRingingCall();
}
} catch (Exception e) {
try {
Intent localIntent3 = new Intent(Intent.ACTION_MEDIA_BUTTON);
KeyEvent localKeyEvent2 = new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK);
localIntent3.putExtra("android.intent.extra.KEY_EVENT",
localKeyEvent2);
c.sendOrderedBroadcast(localIntent3,
"android.permission.CALL_PRIVILEGED");
} catch (Exception e2) {
}
}
}
// //高版本自动接听电话
// private static final void autoAnswerPhonenew(Context c, TelephonyManager tm) {
//
// try {
// Method method = Class.forName("android.os.ServiceManager").getMethod("getService",
// String.class);
//
// IBinder binder = (IBinder) method.invoke(null, new Object[]{TELEPHONY_SERVICE});
//
// ITelephony telephony = ITelephony.Stub.asInterface(binder);
//
// telephony.answerRingingCall();
//
// } catch (NoSuchMethodException e)
//
// {
// Log.d("Sandy", "", e);
//
// } catch (
// ClassNotFoundException e) {
// Log.d("Sandy", "", e);
//
// } catch (
// Exception e)
// {
// Log.d("Sandy", "", e);
// try {
//
// Log.e("Sandy", "for version 4.1 or larger ");
//
// Intent intent = new Intent("android.intent.action.MEDIA_BUTTON");
//
// KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK);
//
// intent.putExtra("android.intent.extra.KEY_EVENT", keyEvent);
//
// sendOrderedBroadcast(intent, "android.permission.CALL_PRIVILEGED");
//
// } catch (Exception e2) {
//
// Log.d("Sandy", "", e2);
//
// Intent meidaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
//
// KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK);
//
// meidaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
// sendOrderedBroadcast(meidaButtonIntent, null);
// }
// }
// }
//
// 自动接听
private static final void autoAnswerPhone3(Context c, TelephonyManager tm) {
try {
java.lang.reflect.Method declaredMethod = tm.getClass()
.getDeclaredMethod("getITelephony");
declaredMethod.setAccessible(true);
ITelephony itelephony = (ITelephony) declaredMethod.invoke(tm);
if (itelephony != null) {
itelephony.answerRingingCall();
}
} catch (Exception e) {
try {
Intent localIntent1 = new Intent(Intent.ACTION_HEADSET_PLUG);
localIntent1.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
localIntent1.putExtra("state", 1);
localIntent1.putExtra("microphone", 1);
localIntent1.putExtra("name", "Headset");
c.sendOrderedBroadcast(localIntent1,
"android.permission.CALL_PRIVILEGED");
} catch (Exception e2) {
}
}
}
// 自动接听
private static final void autoAnswerPhone4(Context c, TelephonyManager tm) {
try {
java.lang.reflect.Method declaredMethod = tm.getClass()
.getDeclaredMethod("getITelephony");
declaredMethod.setAccessible(true);
ITelephony itelephony = (ITelephony) declaredMethod.invoke(tm);
if (itelephony != null) {
itelephony.answerRingingCall();
}
} catch (Exception e) {
try {
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);
c.sendOrderedBroadcast(localIntent2,
"android.permission.CALL_PRIVILEGED");
} catch (Exception e2) {
}
}
}
// 自动接听
private static final void autoAnswerPhone5(Context c, TelephonyManager tm) {
try {
java.lang.reflect.Method declaredMethod = tm.getClass()
.getDeclaredMethod("getITelephony");
declaredMethod.setAccessible(true);
ITelephony itelephony = (ITelephony) declaredMethod.invoke(tm);
if (itelephony != null) {
itelephony.answerRingingCall();
}
} catch (Exception e) {
try {
Intent meidaButtonIntent = new Intent(
Intent.ACTION_MEDIA_BUTTON);
KeyEvent keyEvent = new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK);
meidaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
c.sendOrderedBroadcast(meidaButtonIntent, null);
} catch (Exception e2) {
}
}
}
}
第三步:咱们看下调用的地方
其实调用很简单:随便新建一个类:比如DialBackActivity.java类(我自己项目定义的,你们可以随意的定义)
上面就是调用的地方,是不是很简单。
最后一步: 配置应用程序权限(这步别忘记了哦)
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
注意:以上代码仅限4.4以下手机系统调用 ,但在5.0系统以上调用以上方法会报一个异常:
其实网上好多博客上说,对高版本手机处理的方法。(但我都试过了,没用的。)因为啊。去年10,11月份左右。好多手机修复了这个漏洞,所以这些方法在高版本的手机上几乎是不支持的。之前做这个功能,也是利用了广播漏洞去是实现的(废话不多说咱们看下5.0 6.0系统如何实现自动接听的尼)。
第一步:在之前的那个Mainactivity(自己新建一个类),写一个监听方法:(如下)
/*
* 监听
* */
class MyPhoneStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
//响铃:
case TelephonyManager.CALL_STATE_RINGING://自动接听
autoPhone();//5.0手机自动接听
break;
//挂断电话
case TelephonyManager.CALL_STATE_IDLE:
break;
//接听电话
case TelephonyManager.CALL_STATE_OFFHOOK:
break;
}
super.onCallStateChanged(state, incomingNumber);
}
}
/*
* 5.0以上接听方法 **主要手这个方法(**部分不支持不行)
* */
private void autoPhone() {
try {
if (android.os.Build.VERSION.SDK_INT >= 19) {
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
long eventtime = SystemClock.uptimeMillis() - 1;
KeyEvent var6 = new KeyEvent(/*eventtime, 1L + eventtime, */0, 79/*, 0, 0, 0, 0, 128*/);
KeyEvent var7 = new KeyEvent(1, 79);
am.dispatchMediaKeyEvent(var6);
am.dispatchMediaKeyEvent(var7);
} else {
Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK));
}
} catch (IOException e) {
}
}
/*
*
*/
private void getCallphone() {
try {
//String phoneNamea = android.os.Build.MODEL;//手机型号
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);
} catch (Exception e) {
e.printStackTrace();
}
}
最后一步:只需要在初始化地方调用getCallphone()这个方法就行.是不是发现好简单啊.
这里我给你们解释下autoPhone()这个方法的作用,其实就是模拟了耳机按钮按下接听电话的,其实我感觉用.利用AccessibilityService辅助服务也可以实现这个功能,但没亲自实现过….你们可以尝试下。
但是啊,虽然5.0 6.0系统上可以支持自动接听功能,但是还是有些手机不支持,(暂时无解,据说7.0以上系统都GG了)。