我是Android新手,我必须创建MediaPlayer
才能播放音乐。开始时我的活动歌曲开始播放。但是当我在我的模拟器屏幕上更改方向时MediaPlayer
重新初始化并且另一个音频开始播放。我怎么能避免呢?
这是我的代码:
public class Audio_Activity extends Activity {
MediaPlayer mp = null;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if(isLaunched)
{
setContentView(R.layout.audio);
}
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
length = settings.getInt("TheOffset", 0);
init();
prefs = PreferenceManager.getDefaultSharedPreferences(this);
mp = MediaPlayer.create(getApplicationContext(), R.raw.subhanallah);
playMusic();
mp.setOnCompletionListener(new OnCompletionListener()
{
@Override
public void onCompletion(MediaPlayer arg0)
{
// TODO Auto-generated method stub
}
});
}
private void playMusic()
{
httpGetAsynchTask httpGetAsyncTask = new httpGetAsynchTask();
httpGetAsyncTask.execute();
}
class httpGetAsynchTask extends AsyncTask<String,Integer, Void>
{
protected void onPreExdcute()
{
}
@Override
protected Void doInBackground(String... arg0)
{
// TODO Auto-generated method stub
final SharedPreferences.Editor prefsEdit = prefs.edit();
Log.e("Song is playing", "in Mediya Player ");
mp.setLooping(false);
mp.start();
int millisecond=mp.getDuration();
Log.e("Song is playing", "in Mediya Player " + millisecond);
prefsEdit.putBoolean("mediaplaying", true);
prefsEdit.commit();
//btnChapter.setEnabled(false);
return null;
}
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
btnChapter.setEnabled(false);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Configuration config=getResources().getConfiguration();
if(config.orientation == Configuration.ORIENTATION_PORTRAIT)
{
setContentView(R.layout.audio);
}
else if(config.orientation == Configuration.ORIENTATION_LANDSCAPE)
{
setContentView(R.layout.audio);
}
}
@Override
public void onPause() {
super.onPause();
SharedPreferences.Editor prefsEdit = prefs.edit();
boolean isPlaying = prefs.getBoolean("mediaplaying", false);
if (isPlaying)
{
mp.pause();
int position = mp.getCurrentPosition();
Log.e("Current ", "Position -> " + position);
prefsEdit.putInt("mediaPosition", position);
prefsEdit.commit();
}
}
@Override
protected void onResume() {
super.onResume();
mp.start();
boolean isPlaying = prefs.getBoolean("mediaplaying", false);
if (isPlaying) {
int position = prefs.getInt("mediaPosition", 0);
mp.seekTo(position);
// mp.start();
}
}
}
我在Manifest.xml文件中做了一些更改。
< android:configChanges="orientation|screenSize|keyboard" >
并创建layout-land文件夹。
为什么音乐会播放两次?
答案 0 :(得分:9)
这个问题最简单的答案。
@Override
protected void onSaveInstanceState(Bundle outState)
{
outState.putInt("possition", mpbg.getCurrentPosition());
mpbg.pause();
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
int pos = savedInstanceState.getInt("possition");
mpbg.seekTo(pos);
super.onRestoreInstanceState(savedInstanceState);
}
答案 1 :(得分:5)
当我们将mediaplayer声明为静态变量时,只存在一个mp实例。假设我们的活动方向现在改变,一切都将在方向改变时重新创建,但由于静态属性,不会重新创建Mp变量。通过这种方式我们只是创造一个条件
if(mp!=null && !mp.isPlaying()){
mp = MediaPlayer.create(getApplicationContext(), R.raw.subhanallah);
playMusic();
}
在我们的onCreate()方法中,这将检查音乐是否已播放,如果播放,则条件将不允许应用再次启动音乐播放器。如果音乐没有播放,那么条件将允许应用程序重启音乐。
以下是您的更新代码:
public class Audio_Activity extends Activity {
static MediaPlayer mp = null;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if(isLaunched)
{
setContentView(R.layout.audio);
}
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
length = settings.getInt("TheOffset", 0);
init();
prefs = PreferenceManager.getDefaultSharedPreferences(this);
if(mp == null)
{
initializeMP();
}
if(!mp.isPlaying())
{
playMusic();
}
mp.setOnCompletionListener(new OnCompletionListener()
{
@Override
public void onCompletion(MediaPlayer arg0)
{
// TODO Auto-generated method stub
}
});
}
private void playMusic()
{
httpGetAsynchTask httpGetAsyncTask = new httpGetAsynchTask();
httpGetAsyncTask.execute();
}
public void initializeMP()
{
mp = MediaPlayer.create(getApplicationContext(), R.raw.subhanallah);
}
class httpGetAsynchTask extends AsyncTask<String,Integer, Void>
{
protected void onPreExdcute()
{
}
@Override
protected Void doInBackground(String... arg0)
{
// TODO Auto-generated method stub
final SharedPreferences.Editor prefsEdit = prefs.edit();
Log.e("Song is playing", "in Mediya Player ");
if(mp == null)
{
initializeMP()
}
mp.setLooping(false);
mp.start();
int millisecond=mp.getDuration();
Log.e("Song is playing", "in Mediya Player " + millisecond);
prefsEdit.putBoolean("mediaplaying", true);
prefsEdit.commit();
//btnChapter.setEnabled(false);
return null;
}
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
btnChapter.setEnabled(false);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Configuration config=getResources().getConfiguration();
if(config.orientation == Configuration.ORIENTATION_PORTRAIT)
{
setContentView(R.layout.audio);
}
else if(config.orientation == Configuration.ORIENTATION_LANDSCAPE)
{
setContentView(R.layout.audio);
}
}
@Override
public void onPause() {
super.onPause();
SharedPreferences.Editor prefsEdit = prefs.edit();
boolean isPlaying = prefs.getBoolean("mediaplaying", false);
if (isPlaying)
{
if(mp!=null)
{
mp.pause();
}
int position = mp.getCurrentPosition();
Log.e("Current ", "Position -> " + position);
prefsEdit.putInt("mediaPosition", position);
prefsEdit.commit();
}
}
@Override
protected void onResume() {
super.onResume();
if(mp == null)
{
initializeMP();
}
mp.start();
boolean isPlaying = prefs.getBoolean("mediaplaying", false);
if (isPlaying) {
int position = prefs.getInt("mediaPosition", 0);
mp.seekTo(position);
// mp.start();
}
}
}
答案 2 :(得分:3)
对于这样的任务,你应该使用Service,因为当方向改变时不会重新初始化。
答案 3 :(得分:2)
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("Position", mediaPlayer.getCurrentPosition());
savedInstanceState.putBoolean("isplaying", mediaPlayer.isPlaying());
if (mediaPlayer.isPlaying())
mediaPlayer.pause();
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
position = savedInstanceState.getInt("Position");
mediaPlayer.seekTo(position);
if (savedInstanceState.getBoolean("isplaying"))
mediaPlayer.start();
}
答案 4 :(得分:1)
如果活动不在最前面,媒体播放器也应播放音乐。所以你最好使用一个服务,然后独立于屏幕方向和其他东西:
仔细阅读http://developer.android.com/guide/components/services.html。
特别是START_STICKY
对于媒体播放器服务很重要。
答案 5 :(得分:1)
所以我很长时间都在努力,但我终于明白了。你想要做的是让你的Mediaplayer成为类的静态成员变量,类似于这里的最佳答案。但是,您要避免的陷阱是使用“方便”的create()方法。这实际上在每次调用时都会创建一个新的mediaplayer实例,即使它是静态的。你想做的事情是这样的:
static MediaPlayer m = new MediaPlayer();
现在,无论您在代码中想要创建播放器,请执行以下操作:
m.reset();
try{
m.setDataSource(getApplicationContext(),Uri.parse("android.resource://com.example.app/" + R.raw.soundId));
m.prepare();
}catch(java.io.IOException e){ }
m.seekTo(pos);
m.start();
这一点就是create()虽然方便,但是当你不改变方向时它真的很好,因为它会不断创建新实例并快速耗尽内存。每次调用onCreate()时创建一个静态成员并重新使用它会更简洁。 Reset()将播放器置于正确的状态,以便重新使用。
答案 6 :(得分:0)
当您更改方向时,活动将被销毁并重新创建。
您可以在onSaveInstanceState()中保存视频的实际进度,并从Bundle中获取onRestoreInstanceState()中保存的数据,之后您可以使用进度数据开始播放,如果没有,则从头开始播放保存数据。
答案 7 :(得分:0)
除了使用“服务”之外,还有一个解决方案是在您的活动中实施“onOrientationChange”方法。必须将相同的活动应用于活动的清单文件 'android:configChanges =“orientation | keyboardHidden”';你已经完成了。
在'onOrientationChange'方法中。获取当前播放位置并将其提供给媒体播放器对象并再次播放。
通过这样做,它不会创建媒体播放器的新对象,并使用与当前位置相同的对象。
答案 8 :(得分:0)
因为我多次都在努力解决这个问题,所以我决定创建一个POC作为参考。此示例使用configChanges
标志并手动处理调整大小。它工作得很好恕我直言
答案 9 :(得分:0)
你确定放了
< android:configChanges="orientation|screenSize|keyboard" >
在正确的地方? 你必须把它放在你的玩家的活动中而不是任何其他活动或活动之外。 作为一个例子,我在我的清单中使用了这个:
<activity
android:name=".PlayerActivity"
android:label="@string/title_activity_player"
android:noHistory="true"
android:configChanges="orientation|screenSize">
</activity>
并且它有效..希望它有所帮助..
答案 10 :(得分:0)
您需要使用此代码,不要忘记Text
将其添加到清单活动中
import os
import tkinter as tk
from tkinter.scrolledtext import ScrolledText
ImageDirST = r"your_path"
os.chdir(ImageDirST)
root = tk.Tk()
txt = ScrolledText(root, font="Arial 8")
txt.pack()
for f in sorted(os.listdir(ImageDirST)):
f_name,f_ext = (os.path.splitext(f))
f_sku = (f_name.split(' ')[0])
f_num = (f_name[-2:])
n_name = ('{}_{}{}'.format(f_sku,f_num,f_ext))
txt.insert("end",f"{f} --> {n_name}\n")
root.mainloop()