You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

安卓足球弹跳记录APP声音级别(Sound Level)始终显示0.0求助

解决声音级别振幅始终显示0.0的问题

作为第一次用Java开发Android应用的新手,遇到这种功能卡壳的情况太正常啦!结合你描述的场景,咱们一步步来排查最可能导致振幅一直显示0.0的原因:

1. 首先检查录音权限是否配置正确

Android系统对录音有严格的权限要求,这是最容易踩的坑:

  • 在AndroidManifest.xml里添加静态权限:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 如果用MediaRecorder保存文件的话需要 -->
  • 对于Android 6.0(API 23)及以上版本,还要在代码中动态申请权限:
private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200;
private boolean permissionToRecordAccepted = false;
private String[] permissions = {Manifest.permission.RECORD_AUDIO};

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ... 其他初始化代码
    ActivityCompat.requestPermissions(this, permissions, REQUEST_RECORD_AUDIO_PERMISSION);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_RECORD_AUDIO_PERMISSION) {
        permissionToRecordAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
    }
    if (!permissionToRecordAccepted) finish();
}

2. 检查音频录制组件的初始化与振幅获取逻辑

你目前只贴了代码开头,大概率是音频录制的初始化或者振幅获取方法有问题,这里给你两种常用的实现方式参考:

方式一:使用MediaRecorder获取振幅

private MediaRecorder mediaRecorder;
private TextView soundLevelTv;
private Handler handler = new Handler();
private Runnable updateSoundLevelRunnable;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    soundLevelTv = findViewById(R.id.sound_level_tv); // 确保你的TextView ID正确

    // 初始化MediaRecorder
    mediaRecorder = new MediaRecorder();
    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mediaRecorder.setOutputFile(getCacheDir().getAbsolutePath() + "/temp_audio.3gp"); // 临时文件

    try {
        mediaRecorder.prepare();
        mediaRecorder.start();
    } catch (IOException e) {
        e.printStackTrace();
    }

    // 定时更新振幅
    updateSoundLevelRunnable = new Runnable() {
        @Override
        public void run() {
            if (mediaRecorder != null) {
                int amplitude = mediaRecorder.getMaxAmplitude();
                // 转换为0.0-1.0的浮点数显示(根据需求调整)
                float soundLevel = amplitude / 32767.0f;
                soundLevelTv.setText(String.format("%.1f", soundLevel));
            }
            handler.postDelayed(this, 100); // 每100ms更新一次
        }
    };
    handler.post(updateSoundLevelRunnable);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (mediaRecorder != null) {
        mediaRecorder.stop();
        mediaRecorder.release();
        mediaRecorder = null;
    }
    handler.removeCallbacks(updateSoundLevelRunnable);
}

注意:getMaxAmplitude()第一次调用会返回0,之后每次调用会返回上次调用以来的最大振幅,所以定时调用才能拿到实时数值。

方式二:使用AudioRecord获取更精准的振幅

如果需要更实时的音频数据,可以用AudioRecord:

private AudioRecord audioRecord;
private TextView soundLevelTv;
private Thread recordThread;
private boolean isRecording = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    soundLevelTv = findViewById(R.id.sound_level_tv);

    // 配置AudioRecord参数
    int sampleRate = 44100;
    int channelConfig = AudioFormat.CHANNEL_IN_MONO;
    int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);

    audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, channelConfig, audioFormat, bufferSize);

    // 启动录音线程
    isRecording = true;
    recordThread = new Thread(new Runnable() {
        @Override
        public void run() {
            audioRecord.startRecording();
            short[] buffer = new short[bufferSize];
            while (isRecording) {
                int readSize = audioRecord.read(buffer, 0, bufferSize);
                if (readSize > 0) {
                    // 计算当前缓冲区的最大振幅
                    int maxAmplitude = 0;
                    for (short s : buffer) {
                        int amplitude = Math.abs(s);
                        if (amplitude > maxAmplitude) {
                            maxAmplitude = amplitude;
                        }
                    }
                    float soundLevel = maxAmplitude / 32767.0f;
                    // 回到主线程更新UI
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            soundLevelTv.setText(String.format("%.1f", soundLevel));
                        }
                    });
                }
            }
            audioRecord.stop();
            audioRecord.release();
        }
    });
    recordThread.start();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    isRecording = false;
    try {
        recordThread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

3. 检查TextView的关联是否正确

确认你在代码中通过findViewById正确获取了TextView实例,并且布局文件中的ID和代码里的一致,不然就算计算出了振幅,也没法显示到屏幕上。

如果按照上面的步骤排查后还是有问题,可以把你完整的音频录制相关代码贴出来,这样能更精准地定位问题哦!

内容的提问来源于stack exchange,提问作者RubenDefour

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:38:49