如何在从片段返回到活动时,通过按设备返回按钮使媒体播放器停止。

huangapple go评论79阅读模式
英文:

How to make media player stop when pressing device back button from a fragment back to activity

问题

问题是媒体播放器在按下设备的返回按钮时仍然在播放。如何在按下设备的返回按钮时完全销毁片段、媒体播放器以及其中的所有内容,以便在屏幕上不可见?

我对编程还很陌生,所以对于如何改进代码的所有建议和评论都欢迎。谢谢!

活动(Activity):

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    // ...(你的代码继续)
}

片段(Fragment):

import androidx.fragment.app.Fragment;
import android.media.MediaPlayer;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.Button;
import android.os.Bundle;
import android.widget.SeekBar;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
import java.io.IOException;

public class fragment1 extends Fragment {
    // ...(你的代码继续)
}

编辑:

我尝试了提供的解决方案,但是某种方式片段中的媒体播放器仍然没有被销毁。当我返回到片段时,其中的 seekbar 被重置,但音频文件仍在播放。当我再次点击播放时,它会在之前的音频文件上叠加播放,导致同时播放两个文件。

英文:

My problem is that media player keeps playing when i press device back button. How to completely destroy the fragment and the media player and everything in it when pressing device back button so that it is not visible on the screen?

I'm new to programming so all advice and comments on how to improve the code are welcome. Thank you

Activity:

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    Button button1;
    Button button2;
    Button button3;

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

        setContentView(R.layout.activity_main);

        button1 = findViewById(R.id.button1);
        button2 = findViewById(R.id.button2);
        button3 = findViewById(R.id.button3);

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FragmentManager fm= getSupportFragmentManager();
                fragment1 fragment = new fragment1();
                fm.beginTransaction()
                        .replace(R.id.container,fragment)
                        .addToBackStack(null)
                        .commit();
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FragmentManager fm= getSupportFragmentManager();
                fragment2 fragment= new fragment2();
                fm.beginTransaction()
                        .replace(R.id.container,fragment)
                        .addToBackStack(null)
                        .commit();
            }
        });

        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FragmentManager fm= getSupportFragmentManager();
                fragment3 fragment= new fragment3();
                fm.beginTransaction()
                        .replace(R.id.container,fragment)
                        .addToBackStack(null)
                        .commit();
            }
        });
    }
}

Fragment:

import androidx.fragment.app.Fragment;
import android.media.MediaPlayer;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.Button;
import android.os.Bundle;
import android.widget.SeekBar;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.TextView;
import java.io.IOException;

public class fragment1 extends Fragment {

    MediaPlayer mp;
    Button play;
    SeekBar seekBar;
    TextView elapsedTimeLabel;
    TextView remainingTimeLabel;
    int totalTime;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_fragment1, container, false);

        final MediaPlayer mp = new MediaPlayer();
        try {
            mp.setDataSource("https://firebasestorage.googleapis.com...");
        } catch (IOException e) {
            e.printStackTrace();
        }

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

        final Button play = rootView.findViewById(R.id.play);
        elapsedTimeLabel = rootView.findViewById(R.id.elapsedTimeLabel);
        remainingTimeLabel = rootView.findViewById(R.id.remainingTimeLabel);
        totalTime = mp.getDuration();
        mp.seekTo(0);
        seekBar = rootView.findViewById(R.id.seekBar);
        seekBar.setMax(totalTime);
        seekBar.setOnSeekBarChangeListener

                (new SeekBar.OnSeekBarChangeListener() {
                     @Override
                     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                         if (fromUser) {
                             mp.seekTo(progress);
                             seekBar.setProgress(progress);
                         }
                     }
                     @Override
                     public void onStartTrackingTouch(SeekBar seekBar) {
                     }
                     @Override
                     public void onStopTrackingTouch(SeekBar seekBar) {
                     }
                 }
                );

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (mp != null) {
                    try {
                        Message msg = new Message();
                        msg.what = mp.getCurrentPosition();
                        handler.sendMessage(msg);
                        Thread.sleep(1000);
                    } catch (InterruptedException ignored) {
                    }
                }
            }
        }).start();

        mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {

            public void onCompletion(MediaPlayer sound) {

                play.setBackgroundResource(R.drawable.play);
            }
        });

        play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mp.isPlaying()) {
                    mp.pause();
                    play.setBackgroundResource(R.drawable.play);

                } else {

                    mp.start();
                    play.setBackgroundResource(R.drawable.pause);
                }

            }

        });

        return rootView;
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            int currentPosition = msg.what;
            seekBar.setProgress(currentPosition);

            String elapsedTime = createTimeLabel(currentPosition);
            elapsedTimeLabel.setText(elapsedTime);

            String remainingTime;
            remainingTime = createTimeLabel(totalTime - currentPosition);
            remainingTimeLabel.setText("-" + remainingTime);
        }
    };

    public String createTimeLabel(int time) {
        String timelabel;
        int min = time / 1000 / 60;
        int sec = time / 1000 % 60;

        timelabel = min + ":";
        if (sec < 10) timelabel += "0";
        timelabel += sec;
        return timelabel;

    }


    public void play(View view) {
        if (mp == null) {
            mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    stopPlayer();
                }
            });
        }

        mp.start();
    }

    public void pause(View view) {
        if (mp != null) {
            mp.pause();
        }
    }

    private void stopPlayer() {
        if (mp != null) {
            mp.release();
            mp = null;

        }
    }
}

EDIT:

I tried the provided solutions but somehow the mediaplayer in the fragment doesnt get destroyed. When I go back to the fragment the seekbar in it is reset but the audio file is still playing. When I press play again it starts to play again on top of the previous one so that theres 2 files playing on the same time

答案1

得分: 2

每个片段都有一个 onDestroy() 回调函数,用于在片段从返回堆栈中弹出并销毁时调用。您可以在该方法中调用 stopPlayer()

@Override
public void onDestroy() {
    super.onDestroy();
    stopPlayer();
}
英文:

Each Fragment has an onDestroy() callback for when the fragment is popped off the back stack and destroyed. You can call your stopPlayer() from that method.

@Override
public void onDestroy() {
    super.onDestroy();
    stopPlayer();
}

答案2

得分: 0

很遗憾,没有直接的方法来做到这一点,因为该片段没有onBackPressed()方法,您需要创建一个回调并在片段中实现它才能使其正常工作。

首先,您需要创建一个接口和一个实现接口的类,以拥有一个通用方法。

  1. 创建接口类 OnBackPressedListener

OnBackPressedListener.java

public interface OnBackPressedListener {
    void goBack();
}
  1. 在您的 MainActivity 中创建监听器并为其创建一个设置器,在重写onBackPressed()方法后在其中使用它。

您的 MainActivity 应该如下所示:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private OnBackPressedListener onBackPressedListener;

    public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
        this.onBackPressedListener = onBackPressedListener;
    }
    
    @Override
    public void onBackPressed() {
        if (onBackPressedListener != null){
            onBackPressedListener.goBack();
        }
        super.onBackPressed();
    }
}
  1. Fragment中实现OnBackPressedListener接口,并在其中使用它来停止播放器。

Fragment1.java

public class Fragment1 extends Fragment implements OnBackPressedListener {
    
    @Override
    public void goBack() {
        stopPlayer();
    }
}

附注

  • 考虑将您的 fragment1 改为以大写字母 F 开头的 Fragment1
英文:

Unfortunately, there is no direct way to do that Since the fragment doesn't have an onBackPressed() method, you will have to make a callback and implement it in the fragment to make it work.

First, you need to create an interface and class which implements its interface to have a generic method

  1. Create class interface OnBackPressedListener

OnBackPressedListener.java

public interface OnBackPressedListener {
    void goBack();
}
  1. in your MainActivity Create the listener and make a setter for it and use it inside the onBackPressed() method after overriding it.

Your MainActivity should be something like this

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private OnBackPressedListener onBackPressedListener;

    public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
        this.onBackPressedListener = onBackPressedListener;
    }
    
    @Override
    public void onBackPressed() {
        if (onBackPressedListener != null){
            onBackPressedListener.goBack();
        }
        super.onBackPressed();
    }
}
  1. In the Fragment you should implement the OnBackPressedListener` interface and use it to stop the player

Fragment1.java

public class fragment1 extends Fragment implements OnBackPressedListener {
    
    @Override
    public void goBack() {
        stopPlayer();
    }
}

Side note

  • Consider refactoring your fragment1 name to be Fragment1 with uppercased F

答案3

得分: 0

@Override
public void onDestroy() {
    stopPlayer();
    super.onDestroy();
}

在片段中,重写 onDestroy 函数。在调用 super.onDestroy() 之前,停止播放器

英文:
@Override
public void onDestroy() {
    stopPlayer();
    super.onDestroy();
}

In Fragment, override the OnDestroy function. and stop the player before calling super.onDestroy()

huangapple
  • 本文由 发表于 2020年10月5日 09:33:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/64201460.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定