Skip to content

Instantly share code, notes, and snippets.

@ipcjs
Created January 7, 2016 08:13
Show Gist options
  • Save ipcjs/39ac5fd2b4296aad85c5 to your computer and use it in GitHub Desktop.
Save ipcjs/39ac5fd2b4296aad85c5 to your computer and use it in GitHub Desktop.
打/接/挂电话
package com.ipcjs.musiccontroler;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.SystemClock;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.KeyEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class PhoneUtil {
public static String TAG = PhoneUtil.class.getSimpleName();
/**
* 挂断电话, ok
* @param context
*/
public static void endCall(Context context) {
try {
Object telephonyObject = getTelephonyObject(context);
if (null != telephonyObject) {
Class telephonyClass = telephonyObject.getClass();
Method endCallMethod = telephonyClass.getMethod("endCall");
endCallMethod.setAccessible(true);
endCallMethod.invoke(telephonyObject);
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
private static Object getTelephonyObject(Context context) {
Object telephonyObject = null;
try {
// 初始化iTelephony
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
// Will be used to invoke hidden methods with reflection
// Get the current object implementing ITelephony interface
Class telManager = telephonyManager.getClass();
Method getITelephony = telManager.getDeclaredMethod("getITelephony");
getITelephony.setAccessible(true);
telephonyObject = getITelephony.invoke(telephonyManager);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return telephonyObject;
}
/**
* 通过反射调用的方法,接听电话,该方法只在android 2.3之前的系统上有效。
* @param context
*/
private static void answerRingingCallWithReflect(Context context) {
try {
Object telephonyObject = getTelephonyObject(context);
if (null != telephonyObject) {
Class telephonyClass = telephonyObject.getClass();
Method endCallMethod = telephonyClass.getMethod("answerRingingCall");
endCallMethod.setAccessible(true);
endCallMethod.invoke(telephonyObject);
// ITelephony iTelephony = (ITelephony) telephonyObject;
// iTelephony.answerRingingCall();
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
/**
* 伪造一个有线耳机插入,并按接听键的广播,让系统开始接听电话。
* @param context
*/
private static void answerRingingCallWithBroadcast(Context context) {
AudioManager localAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
//判断是否插上了耳机
boolean isWiredHeadsetOn = localAudioManager.isWiredHeadsetOn();
if (!isWiredHeadsetOn) {
sendHeadsetPlugBroadcast(context, true);
sendHeadsetHookBroadcast(context);
sendHeadsetPlugBroadcast(context, false);
} else {
sendHeadsetHookBroadcast(context);
}
}
/**
* 4.4, 6.0报权限错误
* @param context
* @param state
*/
private static void sendHeadsetPlugBroadcast(Context context, boolean state) {
Intent intent = new Intent(Intent.ACTION_HEADSET_PLUG);
intent.putExtra("state", state ? 1 : 0);
intent.putExtra("microphone", 0);
intent.putExtra("name", "");
// String permission = "android.permission.CALL_PRIVILEGED";
// context.sendOrderedBroadcast(intent, permission);
context.sendBroadcast(intent);
}
/**
* 不报错,
* 华为4.4, 有效
* Nexus5 6.0, 无效
* @param v
*/
public static void sendHeadsetHookBroadcast(Context v) {
int keycode = KeyEvent.KEYCODE_HEADSETHOOK;
String permission = "android.permission.CALL_PRIVILEGED";
long downTime = SystemClock.uptimeMillis();
KeyEvent downKeyEvent = new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN, keycode, 0);
KeyEvent upKeyEvent = new KeyEvent(downTime, SystemClock.uptimeMillis(), KeyEvent.ACTION_UP, keycode, 0);
v.sendOrderedBroadcast(new Intent(Intent.ACTION_MEDIA_BUTTON).putExtra(Intent.EXTRA_KEY_EVENT, downKeyEvent), permission);
v.sendBroadcast(new Intent(Intent.ACTION_MEDIA_BUTTON).putExtra(Intent.EXTRA_KEY_EVENT, upKeyEvent), permission);
}
/**
* 接听电话
* @param context
*/
@Deprecated
public static void answerRingingCall(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { //2.3或2.3以上系统
answerRingingCallWithBroadcast(context);
} else {
answerRingingCallWithReflect(context);
}
}
/**
* 打电话, ok
* @param context
* @param phoneNumber
*/
public static void callPhone(Context context, String phoneNumber) {
if (!TextUtils.isEmpty(phoneNumber)) {
try {
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber));
context.startActivity(callIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 拨电话, ok
* @param context
* @param phoneNumber
*/
public static void dialPhone(Context context, String phoneNumber) {
if (!TextUtils.isEmpty(phoneNumber)) {
try {
Intent callIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber));
context.startActivity(callIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
@gzw13999
Copy link

新版APIgetITelephony 好像被限制了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment