该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
就是我做的是一个可以切换手机听筒模式和扬声器模式的APP,在其他手机上可以正常切换,但是在华为手机上切换失败,是什么原因?
是不是华为手机又其他方式?希望给出解答
代码如下:
// 切换模式,听筒和免提
private void setSpeakerphoneOn(boolean on) {
try {
// 播放音频流类型
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
// 获得当前类
@SuppressWarnings("rawtypes")
Class audioSystemClass = Class.forName("android.media.AudioSystem");
// 得到这个方法
@SuppressWarnings("unchecked")
Method setForceUse = audioSystemClass.getMethod("setForceUse",
int.class, int.class);
if (on) {// 免提的,打开扬声器
audioManager.setMicrophoneMute(false);
audioManager.setSpeakerphoneOn(true);// 打开扬声器
audioManager.setMode(AudioManager.MODE_NORMAL);
play_voice.setImageResource(R.drawable.talking_mic_press);
// setForceUse.invoke(null, 1, 1);
// 先关闭手机发送给板子语音的线程
stopSpeak();
} else {// 听筒
audioManager.setSpeakerphoneOn(false);
audioManager.setMode(AudioManager.MODE_NORMAL);
setForceUse.invoke(null, 0, 0);
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
play_voice.setImageResource(R.drawable.talking_mic_normal);
// 可以自由说话,也可以接受板子的语音
startSpeak();
play_voice.setClickable(true);
} catch (Exception e) {
e.printStackTrace();
该楼层疑似违规已被系统折叠隐藏此楼查看此楼就是我做的是一个可以切换手机听筒模式和扬声器模式的APP,在其他手机上可以正常切换,但是在华为手机上切换失败,是什么原因?是不是华为手机又其他方式?希望给出解答代码如下:// 切换模式,听筒和免提private void setSpeakerphoneOn(boolean on) {try {// 播放音频流类型setVolumeControlStrea...
android
播放语音,
切换
听筒
模式
遇到的问题在
android
5.0以上我们
设置
听筒
模式
audioManager.setMode(AudioManager.MODE_IN_CALL)没有效果;后来各种查阅资料,发现
android
5.0以上Google官方文档推荐使用
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);直接上
切换
代码:/
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
am.setBluetoothScoOn(true);
am.stopBluetoothSco();
am.setMode(AudioManager.MODE_IN_COMMUNICATION);
am.setMicrophoneMute(false);
am.start
AudioManager audioManager = (AudioManager) mContext.getSystemService (Context.AUDIO_SERVICE);
//audioManager.setMode(AudioMan...
import
android
.media.AudioFormat;
import
android
.media.AudioManager;
import
android
.media.AudioTrack;
import
android
.media.AudioRecord;
import
android
.media.MediaRecorder;
import
android
.os.Bundle;
import
android
.os.Handler;
import
android
.os.Message;
import
android
.util.Log;
import
android
.view.View;
import
android
.widget.Button;
import
android
.widget.TextView;
import
android
x.appcompat.app.AppCompatActivity;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final int SAMPLE_RATE = 44100;
private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_OUT_MONO;
private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
private static final int BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
private static final int MIN_FREQUENCY = 16000;
private static final int MAX_FREQUENCY = 22000;
private static final int SIGNAL_DURATION = 1000; // in ms
private static final int SIGNAL_LENGTH = SAMPLE_RATE * SIGNAL_DURATION / 1000;
private static final double PI_2 = Math.PI * 2;
private AudioTrack mAudioTrack;
private AudioRecord mAudioRecord;
private short[] mSignalBuffer;
private short[] mRecordBuffer;
private double[] mFFTBuffer;
private boolean mIsPlaying;
private boolean mIsRecording;
private Button mButton;
private TextView mTextView;
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = findViewById(R.id.button);
mTextView = findViewById(R.id.textView);
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
double[] fft = (double[]) msg.obj;
mTextView.setText(Arrays.toString(fft));
mSignalBuffer = new short[SIGNAL_LENGTH];
mRecordBuffer = new short[BUFFER_SIZE];
mFFTBuffer = new double[BUFFER_SIZE];
for (int i = 0; i < SIGNAL_LENGTH; i++) {
double t = (double) i / SAMPLE_RATE;
double f = MIN_FREQUENCY + (MAX_FREQUENCY - MIN_FREQUENCY) * t / SIGNAL_DURATION;
mSignalBuffer[i] = (short) (Short.MAX_VALUE * Math.sin(PI_2 * f * t));
mAudioTrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL, SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT, SIGNAL_LENGTH, AudioTrack.MODE_STATIC);
mAudioTrack.write(mSignalBuffer, 0, SIGNAL_LENGTH);
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, BUFFER_SIZE);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mIsPlaying) {
mAudioTrack.stop();
mIsPlaying = false;
mButton.setText("Start");
} else {
mAudioTrack.play();
mIsPlaying = true;
mButton.setText("Stop");
new Thread(new Runnable() {
@Override
public void run() {
while (mIsPlaying) {
int n = mAudioRecord.read(mRecordBuffer, 0, BUFFER_SIZE);
for (int i = 0; i < n; i++) {
mFFTBuffer[i] = mRecordBuffer[i];
FFT.fft(mFFTBuffer);
Message msg = mHandler.obtainMessage(1, mFFTBuffer);
mHandler.sendMessage(msg);
}).start();
@Override
protected void onDestroy() {
super.onDestroy();
mAudioTrack.release();
mAudioRecord.release();
这个代码使用了
Android
的音频 API,通过 `AudioTrack` 发射一个从 16kHz 到 22kHz 线性递增的声波,长度为 1ms。然后通过 `AudioRecord` 接收反射信号,并使用 FFT 算法计算频谱图。最后将频谱图显示在界面上。
需要注意的是,这个代码只是一个示例,可能存在一些问题,比如声波的质量可能不够好,频谱图的计算可能不够准确等。如果需要更高质量的声波和频谱图,需要更加深入地研究音频处理和信号处理的知识。