Android - 如何为 phone 通话打开扬声器phone 和最大音量
Android - How to turn on speakerphone and max volume for phone call
我以为我可以在 PhoneStateListener
内打开扬声器并将音量设置为最大,但我在测试时无法正常工作。我正在使用 AudioManager
尝试打开扬声器并设置音量。这不是正确的方法吗?为什么以下代码无法启用扬声器?
class PlaceCall : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
telephonyManager.listen(CallListener(this), PhoneStateListener.LISTEN_CALL_STATE)
val callIntent = Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber))
startActivity(callIntent)
...
}
}
class CallListener(cont: Context) : PhoneStateListener() {
private var context: Context = cont
override fun onCallStateChanged(state: Int, phoneNumber: String?) {
val audioManager: AudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), 0) //I believe this should set call volume to max?
audioManager.isSpeakerphoneOn = true //I believe this should enable speakerphone, but it doesn't during my tests
}
}
AndroidManifest.xml
...
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
...
编辑:
我也尝试添加一个 BroadcastReceiver
但它并没有改变结果。扬声器仍未启用。这没有意义,我不知道我做错了什么。下面是添加了新 BroadcastReciever 的更新代码(上面的代码仍然相同)。
AndroidManifest.xml (updated)
...
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<application>
<receiver android:name=".ServiceReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
...
class ServiceReceiver : BroadcastReceiver() {
lateinit var telephonyManager: TelephonyManager
override fun onReceive(context: Context, intent: Intent) {
telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
telephonyManager.listen(CallListener(context), PhoneStateListener.LISTEN_CALL_STATE)
val audioManager: AudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager.mode = AudioManager.MODE_IN_CALL
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), 0)
audioManager.isSpeakerphoneOn = true
}
}
a PhoneStateListener
顾名思义只是一个监听器,它不能对当前调用执行操作,这是默认 Phone
应用程序的职责。
好消息是您可以让用户将您的应用设置为默认 Phone
应用,但它会强制您实施某些可能超出您的应用范围的活动和服务。
您需要实现自己的拨号盘 activity 来拨打电话,您自己的 InCallService
来处理活动呼叫,以及您自己的 in-call UI 来允许用户静音、打开扬声器、连接蓝牙、在 call-waiting 上拨打电话、在通话中发送拨号音等
您可以查看 this series of medium posts 如何将您的应用设为默认 Phone 应用。
将您的应用设置为默认 phone 应用,并且您的应用控制当前应用后,您可以使用 setAudioRoute
打开扬声器 phone。
编辑:
您可以尝试在 AudioManager 中使用 setSpeakerphoneOn
(isX
始终用于检查值,setX
用于修改值),但是文档说:
This method should only be used by applications that replace the
platform-wide management of audio settings or the main telephony
application.
我不确定 Android 是否通过阻止应用程序调用此方法来强制执行此操作,如果是,则在哪个 Android 平台上执行此操作,但您可以尝试一下。
还有一种方法是使用 java 反射来访问隐藏的 API、see here,但是使用反射几乎肯定会在最近版本的 Android 上崩溃,并且可能会阻止您的应用进入 Google Play。即便如此,还是值得一试。
我以为我可以在 PhoneStateListener
内打开扬声器并将音量设置为最大,但我在测试时无法正常工作。我正在使用 AudioManager
尝试打开扬声器并设置音量。这不是正确的方法吗?为什么以下代码无法启用扬声器?
class PlaceCall : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
telephonyManager.listen(CallListener(this), PhoneStateListener.LISTEN_CALL_STATE)
val callIntent = Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber))
startActivity(callIntent)
...
}
}
class CallListener(cont: Context) : PhoneStateListener() {
private var context: Context = cont
override fun onCallStateChanged(state: Int, phoneNumber: String?) {
val audioManager: AudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), 0) //I believe this should set call volume to max?
audioManager.isSpeakerphoneOn = true //I believe this should enable speakerphone, but it doesn't during my tests
}
}
AndroidManifest.xml
...
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
...
编辑:
我也尝试添加一个 BroadcastReceiver
但它并没有改变结果。扬声器仍未启用。这没有意义,我不知道我做错了什么。下面是添加了新 BroadcastReciever 的更新代码(上面的代码仍然相同)。
AndroidManifest.xml (updated)
...
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<application>
<receiver android:name=".ServiceReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
...
class ServiceReceiver : BroadcastReceiver() {
lateinit var telephonyManager: TelephonyManager
override fun onReceive(context: Context, intent: Intent) {
telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
telephonyManager.listen(CallListener(context), PhoneStateListener.LISTEN_CALL_STATE)
val audioManager: AudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager.mode = AudioManager.MODE_IN_CALL
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), 0)
audioManager.isSpeakerphoneOn = true
}
}
a PhoneStateListener
顾名思义只是一个监听器,它不能对当前调用执行操作,这是默认 Phone
应用程序的职责。
好消息是您可以让用户将您的应用设置为默认 Phone
应用,但它会强制您实施某些可能超出您的应用范围的活动和服务。
您需要实现自己的拨号盘 activity 来拨打电话,您自己的 InCallService
来处理活动呼叫,以及您自己的 in-call UI 来允许用户静音、打开扬声器、连接蓝牙、在 call-waiting 上拨打电话、在通话中发送拨号音等
您可以查看 this series of medium posts 如何将您的应用设为默认 Phone 应用。
将您的应用设置为默认 phone 应用,并且您的应用控制当前应用后,您可以使用 setAudioRoute
打开扬声器 phone。
编辑:
您可以尝试在 AudioManager 中使用 setSpeakerphoneOn
(isX
始终用于检查值,setX
用于修改值),但是文档说:
This method should only be used by applications that replace the platform-wide management of audio settings or the main telephony application.
我不确定 Android 是否通过阻止应用程序调用此方法来强制执行此操作,如果是,则在哪个 Android 平台上执行此操作,但您可以尝试一下。
还有一种方法是使用 java 反射来访问隐藏的 API、see here,但是使用反射几乎肯定会在最近版本的 Android 上崩溃,并且可能会阻止您的应用进入 Google Play。即便如此,还是值得一试。