Created
January 7, 2016 08:13
-
-
Save ipcjs/39ac5fd2b4296aad85c5 to your computer and use it in GitHub Desktop.
打/接/挂电话
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
新版APIgetITelephony 好像被限制了