如何在 Android L 中以编程方式打开来电扬声器?
How to turn on speaker for incoming call programmatically in Android L?
我想在 Android 5.0 中使用接听我的 phone 的 phone 的 GUI(Phone 的 GUI)来接听来电。我找到了一种需要制作 activity 的方法,它用于发送一些操作来打开 Phone 的 GUI。我成功地为来电打开了 Phone 的 GUI。问题是如何为 Phone 的 GUI 打开扬声器。我尝试了代码,但它没有打开。你能帮我解决 Android L
中的那个问题吗
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_IN_CALL);
if (!audioManager.isSpeakerphoneOn())
audioManager.setSpeakerphoneOn(true);
audioManager.setMode(AudioManager.MODE_NORMAL);
清单
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
此外,我们是否有更快捷的方式来使用应答 phone 的意图来打开接听来电。我的方法很长,因为它使用了 Activity。
这是我的完整 class 代码
public class AcceptCallActivity extends Activity {
private static final String MANUFACTURER_HTC = "HTC";
private KeyguardManager keyguardManager;
private AudioManager audioManager;
private CallStateReceiver callStateReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
registerCallStateReceiver();
updateWindowFlags();
acceptCall();
}
@Override
protected void onPause() {
super.onPause();
if (callStateReceiver != null) {
unregisterReceiver(callStateReceiver);
callStateReceiver = null;
}
}
private void registerCallStateReceiver() {
callStateReceiver = new CallStateReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(callStateReceiver, intentFilter);
}
private void updateWindowFlags() {
if (keyguardManager.inKeyguardRestrictedInputMode()) {
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
} else {
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
}
}
private void acceptCall() {
// for HTC devices we need to broadcast a connected headset
boolean broadcastConnected = MANUFACTURER_HTC.equalsIgnoreCase(Build.MANUFACTURER)
&& !audioManager.isWiredHeadsetOn();
if (broadcastConnected) {
broadcastHeadsetConnected(false);
}
try {
try {
Log.d("AnswerCall","execute input keycode headset hook");
//Turn on speaker
audioManager.setMode(AudioManager.MODE_IN_CALL);
if (!audioManager.isSpeakerphoneOn())
audioManager.setSpeakerphoneOn(true);
audioManager.setMode(AudioManager.MODE_NORMAL);
Runtime.getRuntime().exec("input keyevent " +
Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK));
} catch (IOException e) {
// Runtime.exec(String) had an I/O problem, try to fall back
Log.d("AnswerCall","send keycode headset hook intents");
String enforcedPerm = "android.permission.CALL_PRIVILEGED";
Intent btnDown = new Intent(Intent.ACTION_MEDIA_BUTTON).putExtra(
Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_HEADSETHOOK));
Intent btnUp = new Intent(Intent.ACTION_MEDIA_BUTTON).putExtra(
Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK));
sendOrderedBroadcast(btnDown, enforcedPerm);
sendOrderedBroadcast(btnUp, enforcedPerm);
}
} finally {
if (broadcastConnected) {
broadcastHeadsetConnected(false);
}
}
}
private void broadcastHeadsetConnected(boolean connected) {
Intent i = new Intent(Intent.ACTION_HEADSET_PLUG);
i.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
i.putExtra("state", connected ? 1 : 0);
i.putExtra("name", "mysms");
try {
sendOrderedBroadcast(i, null);
} catch (Exception e) {
}
}
private class CallStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
finish();
}
}
}
终于找到解决办法了。我将上面的代码 运行 放在一个线程中。它运作良好。这是我的代码。希望对大家有帮助
Thread thread = new Thread() {
@Override
public void run() {
try {
while(true) {
sleep(1000);
audioManager.setMode(AudioManager.MODE_IN_CALL);
if (!audioManager.isSpeakerphoneOn())
audioManager.setSpeakerphoneOn(true);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
我遇到了这个解决方案。希望对你有帮助。
final static int FOR_MEDIA = 1;
final static int FORCE_NONE = 0;
final static int FORCE_SPEAKER = 1;
Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
setForceUse.invoke(null, FOR_MEDIA, FORCE_SPEAKER);
我想在 Android 5.0 中使用接听我的 phone 的 phone 的 GUI(Phone 的 GUI)来接听来电。我找到了一种需要制作 activity 的方法,它用于发送一些操作来打开 Phone 的 GUI。我成功地为来电打开了 Phone 的 GUI。问题是如何为 Phone 的 GUI 打开扬声器。我尝试了代码,但它没有打开。你能帮我解决 Android L
中的那个问题吗audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_IN_CALL);
if (!audioManager.isSpeakerphoneOn())
audioManager.setSpeakerphoneOn(true);
audioManager.setMode(AudioManager.MODE_NORMAL);
清单
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
此外,我们是否有更快捷的方式来使用应答 phone 的意图来打开接听来电。我的方法很长,因为它使用了 Activity。
这是我的完整 class 代码
public class AcceptCallActivity extends Activity {
private static final String MANUFACTURER_HTC = "HTC";
private KeyguardManager keyguardManager;
private AudioManager audioManager;
private CallStateReceiver callStateReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
}
@Override
protected void onResume() {
super.onResume();
registerCallStateReceiver();
updateWindowFlags();
acceptCall();
}
@Override
protected void onPause() {
super.onPause();
if (callStateReceiver != null) {
unregisterReceiver(callStateReceiver);
callStateReceiver = null;
}
}
private void registerCallStateReceiver() {
callStateReceiver = new CallStateReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(callStateReceiver, intentFilter);
}
private void updateWindowFlags() {
if (keyguardManager.inKeyguardRestrictedInputMode()) {
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
} else {
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
}
}
private void acceptCall() {
// for HTC devices we need to broadcast a connected headset
boolean broadcastConnected = MANUFACTURER_HTC.equalsIgnoreCase(Build.MANUFACTURER)
&& !audioManager.isWiredHeadsetOn();
if (broadcastConnected) {
broadcastHeadsetConnected(false);
}
try {
try {
Log.d("AnswerCall","execute input keycode headset hook");
//Turn on speaker
audioManager.setMode(AudioManager.MODE_IN_CALL);
if (!audioManager.isSpeakerphoneOn())
audioManager.setSpeakerphoneOn(true);
audioManager.setMode(AudioManager.MODE_NORMAL);
Runtime.getRuntime().exec("input keyevent " +
Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK));
} catch (IOException e) {
// Runtime.exec(String) had an I/O problem, try to fall back
Log.d("AnswerCall","send keycode headset hook intents");
String enforcedPerm = "android.permission.CALL_PRIVILEGED";
Intent btnDown = new Intent(Intent.ACTION_MEDIA_BUTTON).putExtra(
Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_HEADSETHOOK));
Intent btnUp = new Intent(Intent.ACTION_MEDIA_BUTTON).putExtra(
Intent.EXTRA_KEY_EVENT, new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_HEADSETHOOK));
sendOrderedBroadcast(btnDown, enforcedPerm);
sendOrderedBroadcast(btnUp, enforcedPerm);
}
} finally {
if (broadcastConnected) {
broadcastHeadsetConnected(false);
}
}
}
private void broadcastHeadsetConnected(boolean connected) {
Intent i = new Intent(Intent.ACTION_HEADSET_PLUG);
i.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
i.putExtra("state", connected ? 1 : 0);
i.putExtra("name", "mysms");
try {
sendOrderedBroadcast(i, null);
} catch (Exception e) {
}
}
private class CallStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
finish();
}
}
}
终于找到解决办法了。我将上面的代码 运行 放在一个线程中。它运作良好。这是我的代码。希望对大家有帮助
Thread thread = new Thread() {
@Override
public void run() {
try {
while(true) {
sleep(1000);
audioManager.setMode(AudioManager.MODE_IN_CALL);
if (!audioManager.isSpeakerphoneOn())
audioManager.setSpeakerphoneOn(true);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
我遇到了这个解决方案。希望对你有帮助。
final static int FOR_MEDIA = 1;
final static int FORCE_NONE = 0;
final static int FORCE_SPEAKER = 1;
Class audioSystemClass = Class.forName("android.media.AudioSystem");
Method setForceUse = audioSystemClass.getMethod("setForceUse", int.class, int.class);
setForceUse.invoke(null, FOR_MEDIA, FORCE_SPEAKER);