经过大量研究,我发现不使用反射没有任何方法可以实现此功能。
首先,您需要插入耳机插孔,然后使用合适的参数调用 setWiredDeviceConnectionState() 方法,然后它的行为就像耳机断开连接但单击仍然有效。
所以这是一个黑客,但根据我的要求,它不是一个万无一失的解决方案,但现在可以工作。
这是我的代码,
private void sendIntent(Intent i) {
Method m;
Log.i(TAG, "Device sdk = " + Build.VERSION.SDK_INT);
try {
if (Build.VERSION.SDK_INT < 16) {
Class<?> clazz = Class.forName("android.app.ActivityManagerNative");
m = clazz.getMethod("broadcastStickyIntent", Intent.class, String.class);
m.setAccessible(true);
m.invoke(clazz, i, null);
return;
} else if (Build.VERSION.SDK_INT < 23) {
//int type, int state, String address, String name
m = am.getClass().getMethod("setWiredDeviceConnectionState", Integer.TYPE, Integer.TYPE, String.class);
m.setAccessible(true);
Object[] objArr = new Object[3];
objArr[0] = (i.getIntExtra("microphone", 0) == 0) ? 8 : 4;
objArr[1] = i.getIntExtra("state", 0);
objArr[2] = i.getStringExtra("name");
m.invoke(am, objArr);
} else {
//int type, int state, String address, String name
m = am.getClass().getMethod("setWiredDeviceConnectionState", Integer.TYPE, Integer.TYPE, String.class, String.class);
m.setAccessible(true);
Object[] objArr = new Object[4];
objArr[0] = (i.getIntExtra("microphone", 0) == 0) ? 8 : 4;
objArr[1] = i.getIntExtra("state", 0);
objArr[2] = i.getStringExtra("address");
objArr[3] = i.getStringExtra("name");
m.invoke(am, objArr);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
发送意图:
@TargetApi(Build.VERSION_CODES.M)
public class HeadSetJackReciever extends AudioDeviceCallback {
public static boolean isAudioChecked;
public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
if (addedDevices.length != 0) {
for (int i = 0; i < addedDevices.length; i++) {
if (addedDevices[i].getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET) {
AudioDeviceInfo audioDeviceInfo = addedDevices[i];
int microphone = audioDeviceInfo.getType();
String headsetName = "DCS";
String headsetAddress = "";
try {
Method method = audioDeviceInfo.getClass().getMethod("getAddress");
method.setAccessible(true);
headsetAddress = (String) method.invoke(audioDeviceInfo);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Log.e("TEST", "microphone:"+microphone);
Log.e("TEST", "headsetName:"+headsetName);
Log.e("TEST", "headsetAddress:"+headsetAddress );
Intent intent = new Intent(ForegroundService.context, SelectAudioOutput.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("microphone",microphone);
intent.putExtra("headsetName",headsetName);
intent.putExtra("headsetAddress",headsetAddress);
ForegroundService.context.startActivity(intent);
}
}
}
}
public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
if (removedDevices.length != 0) {
Log.e("TEST", "Audio deinserted");
if (SplashScreen.preferences.getBoolean("isKey", false)) {
Intent startIntent = new Intent(ForegroundService.context, ForegroundService.class);
startIntent.setAction(Constants.ACTION.STARTNOTIFICATION_ACTION);
ForegroundService.context.startService(startIntent);
} else {
Intent startIntent = new Intent(ForegroundService.context, ForegroundService.class);
startIntent.setAction(Constants.ACTION.STOPNOTIFICATION_ACTION);
ForegroundService.context.startService(startIntent);
}
ForegroundService.audioManager.setMode(AudioManager.MODE_IN_CALL);
ForegroundService.audioManager.setSpeakerphoneOn(false);
}
}
}
对于 Lollipop 及更低版本:
if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
headsetName = intent.getStringExtra("name");
microphone = intent.getIntExtra("microphone", 0);
int state = intent.getIntExtra("state", -1);
switch (state) {
case 0:
Log.d("onReceive", "Headset unplugged");
Log.e("TEST", "Audio deinserted");
if (SplashScreen.preferences.getBoolean("isKey", false)) {
Intent startIntent = new Intent(ForegroundService.context, ForegroundService.class);
startIntent.setAction(Constants.ACTION.STARTNOTIFICATION_ACTION);
context.startService(startIntent);
} else {
Intent startIntent = new Intent(ForegroundService.context, ForegroundService.class);
startIntent.setAction(Constants.ACTION.STOPNOTIFICATION_ACTION);
context.startService(startIntent);
}
ForegroundService.audioManager.setMode(AudioManager.MODE_IN_CALL);
ForegroundService.audioManager.setSpeakerphoneOn(false);
break;
case 1:
Log.d("onReceive", "Headset plugged");
Log.e("TEST", "microphone:"+microphone);
Log.e("TEST", "headsetName:"+headsetName);
Log.e("TEST", "headsetAddress:"+headsetAddress );
Intent intentone = new Intent(ForegroundService.context, SelectAudioOutput.class);
intentone.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intentone.putExtra("microphone",microphone);
intentone.putExtra("headsetName",headsetName);
intentone.putExtra("headsetAddress",headsetAddress);
context.startActivity(intentone);
break;
}
}
如果我错过了什么,请告诉我。
谢谢。