Он работает с моей основной Activity и моим фрагментом, но если я использую метод LoadSound() в Sound классе, то getAssets() не работает.
public class CarnivoreFragment extends Fragment {
private int mCowSound;
private View view;
private ImageButton mCowImageButton;
public CarnivoreFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_carnivore, container, false);
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Sound.createOldSoundPool();
} else {
Sound.createNewSoundPool();
}
mCowSound = Sound.loadSound("cow.wav");
mCowImageButton = (ImageButton) view.findViewById(R.id.imageButtonCow);
mCowImageButton.setOnClickListener(onClickListener);
return view;
}
View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.imageButtonCow:
Sound.playSound(mCowSound);
Toast.makeText(view.getContext(), "Cow", Toast.LENGTH_SHORT).show();
break;
}
}
};
}
И мой класс "Sound":
public class Sound {
private static SoundPool mSoundPool;
private static AssetManager mAssetManager;
private static int mStreamID;
private static Context context;
public Sound(Context context) {
this.context = context;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void createNewSoundPool() {
AudioAttributes attributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_GAME)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
mSoundPool = new SoundPool.Builder()
.setAudioAttributes(attributes)
.build();
}
@SuppressWarnings("deprecation")
public static void createOldSoundPool() {
mSoundPool = new SoundPool(3, AudioManager.STREAM_MUSIC, 0);
}
public static int playSound(int sound) {
if (sound > 0) {
mStreamID = mSoundPool.play(sound, 1, 1, 1, 0, 1);
}
return mStreamID;
}
public static int loadSound(String fileName) {
mAssetManager = context.getAssets();
AssetFileDescriptor afd;
try {
afd = mAssetManager.openFd(fileName);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context, "Не могу загрузить файл " + fileName,
Toast.LENGTH_SHORT).show();
return -1;
}
return mSoundPool.load(afd, 1);
}
}
Как решить эту проблему?
Ответ
Если создание экземпляров класса не входит в алгоритм использования класса Sound (так как все поля и методы в нем статические), то ваши методы не смогут получать контекст (так как конструктор не отрабатывает), который необходим для работы метода getAssets()
В качестве решения можно предложить передавать контекст через параметры метода, в котором он требуется:
public static int loadSound(Context context, String fileName) {
mAssetManager = context.getAssets();
....
}
Вызов из фрагмента:
mCowSound = Sound.loadSound(getActivity(), "cow.wav");
Если экземпляра активити будет недостаточно для контекста getAssets(), то нужно использовать другие способы доступа к контексту. Более правильно - получить экземпляр контекста один раз при создании фрагмента и "подсовывать" его везде, где требуется, а не вызывать каждый раз метод его получения.
Комментариев нет:
Отправить комментарий