【问题标题】:In an Android fragment no sound is played after an onClick event在 Android 片段中,onClick 事件后不播放声音
【发布时间】:2016-10-15 15:08:41
【问题描述】:

我对这一切都很陌生,所以我开始编写这个应用程序来学习。

该应用程序从 6 个可点击的图像开始,这些图像会导致由一系列“可滑动”屏幕组成的次要活动,每个屏幕都有一个图像,当点击该图像时会产生声音。以下是生成屏幕所需的辅助代码和片段代码:

SecondaryPage.java

import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;

public class SecondaryPage extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Set the content of the activity to use the activity_main.xml layout file
        setContentView(R.layout.secondary);

        // Find the view pager that will allow the user to swipe between fragments
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);

        // Create an adapter that knows which fragment should be shown on each page
        SimpleFragmentPagerAdapter adapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager());

        // Set the adapter onto the view pager
        viewPager.setAdapter(adapter);
    }
}

SimpleFragmentAdapter.java

AnimalsFragement.java(Croc()Camel() 相同,只是名称不同)

import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;

import static com.example.testfrags.R.layout.animals;

public class AnimalsFragment extends Fragment {
    private ImageView imageView;
    private MediaPlayer mp;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = null;
        //Inflating View to access it's resources

        v = inflater.inflate(animals, container, false);
        Log.i("AnimalsFragment", "mp before playing: " + mp);

        //creating clickable image

        imageView = (ImageView) v.findViewById(R.id.jungle_animals);

        // Sound played once clicked
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Start playback.
                mp = MediaPlayer.create(getActivity(), R.raw.lioncub2);
                Log.i("AnimalsFragment", "mp: " + mp);
                mp.start();
                mp.stop();//Stops playback - added precaution

                // release media resources
                releaseMediaPlayer();
                Log.i("AnimalsFragment", "mp after release: " + mp);
                // Little msg confirm end of sound
                Toast.makeText(v.getContext(), "Questo era il Leoncino", Toast.LENGTH_SHORT).show();

            }
        });

        return v;
    } // end of onCreatView

    /**
     * Clean up the media player by releasing its resources.
     */
    private void releaseMediaPlayer() {
        // If the media player is not null, then it may be currently playing a sound.
        if (mp != null) {
            // Regardless of the current state of the media player, release its resources
            // because we no longer need it.
            mp.reset();
            mp.release();

            // Set the media player back to null. 

        } // end of if
    } // end of releaseMediaPlayer

    @Override
    public void onStop() {
        super.onStop();  // Always call the superclass method first
        releaseMediaPlayer();

    }


}

这些是 xml 文件: 次要.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical">

   <android.support.v4.view.ViewPager
       android:id="@+id/viewpager"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />

</LinearLayout>

animals.xml(croc.xml和camel.xml是一样的)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center">

    <ImageView
        android:id="@+id/jungle_animals"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/lion"/>

</LinearLayout>

应用程序编译并运行,但当我单击任何片段中的任何图像时,没有声音播放。我已经在我的设备上尝试过并模拟过,但没有。

我做错了什么?

我尝试在行中将getActivity() 更改为v.getContext()

`mp = MediaPlayer.create(getActivity(), R.raw.lioncub2);` 

但没有任何改变。 所有声音文件都是 mp3。我还编写了一个没有包含三个图像的片段的 secondaryPage.java 版本,只是为了查看 mp3 文件是否可以工作并且它们都可以正常播放。 我还插入了Toast 消息,只是为了检查onClick() 方法是否有效,它确实有效。 当我调试并进入mp = MediaPlayer.create(getActivity(), R.raw.lioncub2); 行并继续时,会播放声音。

这是 Log.i 语句的输出:

10-15 10:50:36.962 2459-2459/com.example.testfrags I/Croc: mp before playing: null
10-15 10:50:37.682 2459-2459/com.example.testfrags I/Choreographer: Skipped 36 frames!  The application may be doing too much work on its main thread.
10-15 10:50:39.472 2459-2459/com.example.testfrags I/AnimalsFragment: mp: android.media.MediaPlayer@b0fd1480
10-15 10:50:39.482 2459-2459/com.example.testfrags I/AnimalsFragment: mp after release: null

提前感谢您的帮助!

【问题讨论】:

    标签: android android-fragments android-mediaplayer


    【解决方案1】:

    您的问题是您在媒体播放器启动后立即停止并释放它。从您的代码中删除 stop 方法并播放声音。

    现在仅仅移除 stop 并不能解决你的全部问题,如果你想使用 MediaPlayer 类,你现在必须做一些工作,因为 MediaPlayer 需要大量工作

    如果您的声音或音频持续时间很短,您应该使用SoundPool class。

    您的问题似乎与我之前回答的这个问题相似。link

    解决您的问题:

    解决方案 1:

    在持有片段的Activity类中声明mediaPlayer并实现TabLayout.OnTabSelectedListener

    ... MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener{...
        MediaPlayer mediaPlayer = null;
        ....
    @Override
    public void onTabSelected(TabLayout.Tab tab) 
    {
    int position= tab.getPosition();
    switch(position)
      {
      case 1: if(mediaPlayer!=null)
                {
                mediaPlayer.stop();
                mediaPlayer.realse();
                }
      break;
      case 2: if(mediaPlayer!=null)
                {
                mediaPlayer.stop();
                mediaPlayer.realse();
                }
      break;
      ....
      }
    ....
    }
    

    现在在您的 Fragment 中添加 MainActivity 的引用,如下所示:

    public class AnimalsFragment extends Fragment {
    private ImageView imageView;
    private MainActivity mainActivity;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = null;
        mainActivity=(MainActivity)getActivity();
        ....
        ....
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Start playback.
               mainActivity.mediaPlayer=MediaPlayer.create(mainActivity, R.raw.song);
               mediaPlayer.start();
    
               ....
               ....
             ....}
    

    我希望这会奏效。

    【讨论】:

    • 非常感谢。我删除了停止方法,但没有任何改变。 MediaPlayer 以前(没有片段编码)在复制文件时没有问题,所以我不明白为什么它现在不起作用。
    • 我先给你答案告诉我你想播放什么类型的音频是短的还是长的?
    • 你真好。音频文件是 mp3 文件中的动物声音,所以不会太长。
    • 所以在那个场景中你不应该使用 Media Player 类,而应该使用为此类文件构建的 SoundPool 类。我在答案中提到的链接中给出了不使用 Media Player 类的原因。
    • 如果您还想使用媒体播放器,那么我将编辑答案等待一段时间。
    【解决方案2】:

    为了它的价值...... 代码中的错误是在声音实际完成之前调用releaseMediaPlayer 方法。 所以我应该通过添加某种形式的控制来检查这一点,我使用MediaPlayer.OnCompletionListener 进行了检查。

    我通过定义一个变量并调用 MediaPalyer.OnCompletionListner 来做到这一点:

     private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {
            // Now that the sound file has finished playing, release the media player resources.
            releaseMediaPlayer();
        }
    

    然后在声音开始播放后调用以下命令:

    mp.setOnCompletionListener(mCompletionListener);
    

    谢谢大家!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-17
      • 2016-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多