java - 找不到类 'android.media.AudioAttributes$Builder'

标签 java android api audio classloader

所以我目前正在为我正在开发的游戏实现播放声音。现在游戏支持 API 8 到最新的 21。我正在使用 SoundPool 播放和处理声音,但似乎使用 API 21,您必须为 SoundPool 设置 AudioAttributes。

我目前收到以下错误:

05-15 13:56:48.202 26245-26245/thedronegame.group08.surrey.ac.uk.thedronegame E/dalvikvm﹕ Could not find class 'android.media.AudioAttributes$Builder', referenced from method thedronegame.group08.surrey.ac.uk.thedronegame.Sound.initializeRecentAPISoundPool

声级

<pre>package thedronegame.group08.surrey.ac.uk.thedronegame;

import android.annotation.TargetApi;
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.MediaPlayer;
import android.os.Build;
import android.util.Log;

/**
 * Created by Michael on 19/03/15.
 */
public class Sound {

    /**
     * The sound pool
     */
    private SoundPool soundPool = null;


    /**
     * The current Sound.
     */
    private int sound = 0;

    /**
     * false Boolean.
     */
    private boolean loaded = false;

    /**
     * The context.
     */
    private Context context = null;

    /**
     * Audio Manager.
     */
    private AudioManager audioManager = null;

    /**
     * Literal Volume.
     */
    private float literalVolume = 0;

    /**
     * Maximum Volume.
     */
    private float maximumVolume = 0;

    /**
     * Volume.
     */
    private float volume = 0;

    /**
     * A constructor for creating a new Sound object
     */
    public Sound(Context context) {

        this.context = context;

        this.audioManager = (AudioManager) context.getSystemService(context.AUDIO_SERVICE);

        // Set Literal Volume for Audio Manager.
        this.literalVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

        // Set Maximum Volume for Audio Manager.
        this.maximumVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

        // Set volume for GameSound Pool.
        this.volume = literalVolume / maximumVolume;
    }

    /**
    
     * Initialize the SoundPool for later API versions
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void initializeRecentAPISoundPool() {
        // Create AudioAttributes.


        AudioAttributes attributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_GAME)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build();

        this.soundPool = new SoundPool.Builder()
                .setAudioAttributes(attributes)
                .setMaxStreams(7)
                .build();
    }

    /**
    
     * Intialize SoundPool for older API
     versions
     */
    @SuppressWarnings("deprecation")
    private void initializeDeprecatedAPISoundPool() {
        // Initialize SoundPool.
        this.soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC,0);
    }

    /**
    
     * Load Sounds into the SoundPool.
    
     */
    private void loadIntoSoundPool() {
        //todo: finish loadIntoSoundPool() method

        // Loads all sounds from array

        // Sound 0.
        this.soundPool.load(this.context, R.raw.blip_select2, 0);

        // Sound 1.
        //this.soundPool.load(context, R.raw.sound, 1);
    }

    /**
     * Set the initial SoundPool.
    
     *  Call to Method differs dependent on API Version.
    
     */
    public void setInitialSoundPool() {

        // Initialize SoundPool, call specific dependent on SDK Version
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            initializeRecentAPISoundPool();
        }
        else {
            initializeDeprecatedAPISoundPool();
        }

        this.soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {

            @Override
            public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                loaded = true;
                soundPool.load(context, R.raw.blip_select2, 0);
            }
        });

        // Load sounds into sound pool from resources.
        //this.loadIntoSoundPool();

    }

    /**
     * Plays the sound
     * @param id - the sound id
     * @param context - the context
     */
    public void playSound(int id, final Context context) {
        // Create Audio Manager using Context.

        soundPool.play(id, this.volume, this.volume, 1, 0, 1f);


        // Play GameSound from GameSound Pool with defined Volumes.


        Log.e("SoundPool", "Game GameSound Played");
    }
}</code>

有没有人遇到这个问题?任何帮助将不胜感激。

最佳答案

谢谢大卫瓦瑟 :)

我只想与大家分享关于目前适用于 API 21 和更低版本的最终实现。

在为 API 21 + 构建 SoundPool 时发现您必须首先创建 AudioAttributes:

    Log.d("Sound", "Initialize Audio Attributes.");
    // Initialize AudioAttributes.
    AudioAttributes attributes = new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_GAME)
            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
            .build();

在构建 AudioAttributes 之后,您可以使用 Sound.Builder 初始化 SoundPool:

    Log.d("Sound", "Set AudioAttributes for SoundPool.");
    // Set the audioAttributes for the SoundPool and specify maximum number of streams.
    soundPool = new SoundPool.Builder()
            .setAudioAttributes(attributes)
            .setMaxStreams(7)
            .build();

请注意,正如 David Wasser 所指出的,此 AudioAttributes 必须与处理声音的默认类位于不同的类中,因为 API 21 - 兼容设备不知道 AudioAttributes,因此会报告错误.我为 API 21 SoundPool 和 AudioAttributes 实现创建了一个类:

SoundRecent.java

    import android.annotation.TargetApi;
    import android.media.AudioAttributes;
    import android.media.SoundPool;
    import android.os.Build;
    import android.util.Log;

    /**
     * Created by michaelstokes on 17/05/15.
     */
    public class SoundRecent {

        /**
        
         * Initialize the SoundPool for later API versions
         */
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public SoundPool initializeRecentAPISoundPool(SoundPool soundPool) {

        Log.d("Sound", "Initialize Audio Attributes.");
        // Initialize AudioAttributes.
        AudioAttributes attributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_GAME)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build();

        Log.d("Sound", "Set AudioAttributes for SoundPool.");
        // Set the audioAttributes for the SoundPool and specify maximum number of streams.
        soundPool = new SoundPool.Builder()
                .setAudioAttributes(attributes)
                .setMaxStreams(7)
                .build();

        return soundPool;
    }
}

**对于您的原始 SoundClass,将调用设备 API 版本检查和相应的初始化程序:**

    package thedronegame.group08.surrey.ac.uk.thedronegame;

import android.annotation.TargetApi;
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Build;
import android.util.Log;

/**
 * Created by Michael on 19/03/15.
 */
public class Sound {

    /**
     * The sound pool
     */
    private SoundPool soundPool = null;


    /**
     * The current Sound.
     */
    private int sound = 0;

    /**
     * false Boolean.
     */
    private boolean loaded = false;

    /**
     * The context.
     */
    private Context context = null;

    /**
     * Audio Manager.
     */
    private AudioManager audioManager = null;

    /**
     * Literal Volume.
     */
    private float literalVolume = 0;

    /**
     * Maximum Volume.
     */
    private float maximumVolume = 0;

    /**
     * Volume.
     */
    private float volume = 0;

    /**
     * A constructor for creating a new Sound object
     */
    public Sound(Context context) {

        this.context = context;

        this.audioManager = (AudioManager) context.getSystemService(context.AUDIO_SERVICE);

        // Set Literal Volume for Audio Manager.
        this.literalVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

        // Set Maximum Volume for Audio Manager.
        this.maximumVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

        // Set volume for GameSound Pool.
        this.volume = literalVolume / maximumVolume;

    }

    /**
    
     * Initialize the SoundPool for later API versions
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void initializeRecentAPISoundPool() {

        Log.d("SoundPool", "Initialize recent API Sound Pool");
        this.soundPool = new SoundRecent().initializeRecentAPISoundPool(this.soundPool);
    }

    /**
    
     * Intialize SoundPool for older API
     versions
     */
    @SuppressWarnings("deprecation")
    private void initializeDeprecatedAPISoundPool() {
        // Initialize SoundPool.
        this.soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
    }

    /**
    
     * Load Sounds into the SoundPool.
    
     */
    private void addSoundsToSoundPool() {

        Log.d("Sound", "Load Sounds.");

        int soundID = 0;

        // Load Sound 1
        soundID = soundPool.load(context, R.raw.blip_select2, 1);
        Log.d("Sound", "Sound " + soundID + " Loaded.");

        // Load Sound 2
        soundID = soundPool.load(context, R.raw.pickup_coin3, 1);
        Log.d("Sound", "Sound " + soundID + " Loaded.");

        // Load Sound 3
        soundID = soundPool.load(context, R.raw.explosion2, 1);
        Log.d("Sound", "Sound " + soundID + " Loaded.");

        // Load Sound 4
        soundID = soundPool.load(context, R.raw.powerup8, 1);
        Log.d("Sound", "Sound " + soundID + " Loaded.");

        // Load Sound 5
        soundID = soundPool.load(context, R.raw.powerup15, 1);
        Log.d("Sound", "Sound " + soundID + " Loaded.");

        // Load Sound 6
        soundID = soundPool.load(context, R.raw.jump9, 1);
        Log.d("Sound", "Sound " + soundID + " Loaded.");

        // Load Sound 7
        soundID = soundPool.load(context, R.raw.powerup18, 1);
        Log.d("Sound", "Sound " + soundID + " Loaded.");
    }

    /**
     * Set the initial SoundPool.
    
     *  Call to Method differs dependent on API Version.
    
     */
    public void setInitialSoundPool() {

        Log.d("Sound", "Initialize Recent or Deprecated API SoundPool.");

        // Initialize SoundPool, call specific dependent on SDK Version
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Log.d("Sound", "Initialize Recent API SoundPool.");
            initializeRecentAPISoundPool();
        }
        else {
            Log.d("Sound", "Initialize Old API SoundPool.");
            initializeDeprecatedAPISoundPool();
        }

        this.soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {

            @Override
            public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
                loaded = true;
            }
        });

        // Add and Load sounds into SoundPool.
        this.addSoundsToSoundPool();
    }

    /**
     * Plays the sound
     * @param id - the sound id
     * @param context - the context
     */
    public void playSound(int id, final Context context) {

        Log.d("Sound", "Play GameSound " + id + 1 + ".");
        soundPool.play(id + 1, this.volume, this.volume, 1, 0, 1f);
        Log.d("Sound", "GameSound " + id + 1 + " Played");
    }
}

关于java - 找不到类 'android.media.AudioAttributes$Builder',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30260520/

相关文章:

c# - 如何在 ASP.NET 中执行之前拦截 api 中的 GET 请求?

python - 将二进制数据从 Python 传递到 C API 扩展

java - 如何在Windows 7环境中删除类路径

java - 使用java在postgresql中插入串行类型字段数据

java - 静态方法中的 TimerTask 在执行之前会被垃圾回收吗?

android - 如何通过android端编码使用firebase发送通知?

java - 字母顺序不适用于自定义 ListView

php - 折线图生成

java - 如何从java中的文本文件获取数组大小和元素的输入?

java - 使用 envers 进行 Junit 测试