【问题标题】:Media Player pauses the music when the activity loses focus(when home or screen goes off)当活动失去焦点时(当主屏幕或屏幕关闭时),媒体播放器会暂停音乐
【发布时间】:2016-08-10 18:12:19
【问题描述】:

当按下主页按钮或屏幕熄灭时,媒体播放器会停止音乐....即使活动失去焦点,我希望音乐继续播放....但我希望音乐暂停来电以及用户暂停音乐....当通过后退按钮关闭活动时,音乐也应该停止

这是我的代码示例:

package com.example.acer.aartisangrah;

import android.content.Context;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

public class ekdanta extends AppCompatActivity implements Runnable, View.OnClickListener,SeekBar.OnSeekBarChangeListener {
TextView tv4;
Button b9, b10,but19;
int count = 0;
MediaPlayer play;
SeekBar seek_bar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_ekdanta);
    tv4 = (TextView) findViewById(R.id.textView9);
    tv4.setTextSize(18);
    tv4.setText(Html.fromHtml(getString(R.string.thirteen)));
    b9 = (Button) findViewById(R.id.b9);
    b10 = (Button) findViewById(R.id.b10);
    seek_bar = (SeekBar) findViewById(R.id.seekBar);
    seek_bar.setOnSeekBarChangeListener(this);
    seek_bar.setEnabled(false);
    but19 = (Button) findViewById(R.id.button19);
    but19.setOnClickListener(this);
    TelephonyManager mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    mTelephonyManager.listen(mPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
private final PhoneStateListener mPhoneListener=new PhoneStateListener(){
    public void onCallStateChanged(int state, String incomingNumber) {
        super.onCallStateChanged(state, incomingNumber);

        // Call receive state
        if (state != TelephonyManager.CALL_STATE_IDLE) {
            if ((play!= null) && (play.isPlaying()))
            {
                play.pause();
                but19.setBackgroundResource(R.drawable.play);
            }
        }
    }
};

public void run() {
    int currentPosition = play.getCurrentPosition();
    final int total = play.getDuration();
    while (play != null && currentPosition < total) {
        try {
            Thread.sleep(1000);
            currentPosition = play.getCurrentPosition();
        } catch (InterruptedException e) {
            return;
        } catch (Exception e) {
            return;
        }
        seek_bar.setProgress(currentPosition);
    }
}
public void onClick(View v) {
    if (v.equals(but19)) {
        if (play == null) {
            play = MediaPlayer.create(getApplicationContext(), R.raw.ekadanta);
            seek_bar.setEnabled(true);
        }
        if (play.isPlaying()) {
            play.pause();
            but19.setBackgroundResource(R.drawable.play);
        } else {
            play.start();
            but19.setBackgroundResource(R.drawable.pause);
            seek_bar.setMax(play.getDuration());
            new Thread(this).start();
        }
    }
    play.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            play.seekTo(0);
            but19.setBackgroundResource(R.drawable.play);
        }
    });
}

@Override
protected void onPause()
{
    super.onPause();
}

@Override
protected void onDestroy()
{
    super.onDestroy();
    play.release();
}

@Override
public void onProgressChanged(SeekBar seek_bar, int progress, boolean fromUser) {
    try{
        if(play.isPlaying()||play!=null){
            if (fromUser)
                play.seekTo(progress);
        }
        else if(play==null){
            Toast.makeText(getApplicationContext(),"First Play", Toast.LENGTH_SHORT).show();
            seek_bar.setProgress(0);
        }
    }
    catch(Exception e){
        Log.e("seek bar",""+e);
        seek_bar.setEnabled(false);
    }
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {

}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {

}

public void increase(View inc) {
    count++;
    if (count == 1) {
        tv4.setTextSize(22);
    } else if (count == 2) {
        tv4.setTextSize(30);
    } else if (count >= 3) {
        count = 3;
        tv4.setTextSize(40);
    }
}

public void decrease(View dec) {
    count--;
    if (count <= 0) {
        tv4.setTextSize(18);
        count = 0;
    }
    if (count == 1) {
        tv4.setTextSize(22);
    } else if (count == 2) {
        tv4.setTextSize(30);
    } else if (count == 3) {
        tv4.setTextSize(40);
    }
}
}

编辑

使用此代码进行活动后...此活动无法在某些设备上打开...应用程序自行关闭...请帮助!!! 没有此代码的其他活动也可以正常工作...

【问题讨论】:

    标签: java android android-mediaplayer


    【解决方案1】:

    首先,你有以下代码

    @Override
    protected void onPause()
    {
        super.onPause();
        if ((play!= null) && (play.isPlaying()))
        {
            play.pause();
        }
    }
    

    onPause 方法在每次活动进入后台(失去焦点)或被用户关闭时执行。因此,您的第一步是从 onPause 方法中删除此代码,在该方法中您故意调用 play.pause()

    您应该覆盖onBackPressed() 方法并执行与您正在执行的操作类似的操作,但调用play.stop()

    检查 here,特别是在 Performing cleanup 部分,其中显示以下内容

    MediaPlayer 对象会消耗大量系统 资源,所以你应该只保留它,只要你需要和调用 完成后释放()。调用这个很重要 明确的清理方法而不是依赖系统垃圾 收集,因为在垃圾之前可能需要一些时间 收集器回收 MediaPlayer

    请务必查看该指南。

    【讨论】:

    • 嘿,我在想只要super.onBackPressed() 被称为finish() 就会很快跟进。因此,mediaPlayer 实例也将被销毁(只要它的引用不被任何其他外部类持有,最终就会收集垃圾)。所以,我不需要在onBackPressed() 中停止它。
    • 是的,你是对的,它最终会被垃圾回收,但建议作为一种好的做法,在你确定使用完媒体播放器后释放它。检查我更新的答案:)
    • 是的..如果不在onPause()中,我通常至少将清理代码放在onDestroy()中(取决于用例):)...
    • @LeandroTemperoni...此活动在某些设备上无法打开(redmi note 3)...。应用程序在单击活动后自行关闭.....
    【解决方案2】:

    当应用程序进入后台时停止音乐暂停。评论play.pause()如下:

    @Override 
    protected void onPause() 
    { 
        super.onPause(); 
        if ((play!= null) && (play.isPlaying())) 
        { 
            // play.pause(); 
        } 
    } 
    

    播放本身应该在后按时停止(我几乎可以肯定)。确保在 onDestroy() 中处理掉 mediaPlayer。

    在通话接收时停止它。在您的活动中实例化以下接收器:

    // Listens for phone state and pauses in an event of call
        private final PhoneStateListener mPhoneListener = new PhoneStateListener() {
            public void onCallStateChanged(int state, String incomingNumber) {
                super.onCallStateChanged(state, incomingNumber);
    
                // Call receive state
                if (state != TelephonyManager.CALL_STATE_IDLE) {
                    if ((play!= null) && (play.isPlaying())) 
                    { 
                        play.pause(); 
                    }
                }
            }
        };
    

    您需要注册为(可能在onCreate()):

    // Make mTelephonyManager an instance variable
    TelephonyManager mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    mTelephonyManager.listen(mPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
    

    别忘了在onDestroy()注销它:

    mTelephonyManager.listen(mPhoneListener, PhoneStateListener.LISTEN_NONE);
    

    【讨论】:

    • 这按我想要的方式工作,但问题是当音乐在背景中播放并且用户从启动器打开应用程序时,应用程序重新启动,当点击播放新音乐时,它会重新开始(这个问题如果应用是从最近的应用中打开的,则不会导致)
    • @Devk 好的..音乐是从头开始,还是在之前播放的音乐上播放[连同它]?
    • 音乐在之前的播放音乐上播放
    • 你正在停止onDestroy()中的音乐,对吧?
    • 这就像我正在播放音乐并按下主页按钮,现在如果我从启动器打开应用程序......应用程序从开始加载并再次播放音乐会导致它播放已经播放的音乐......
    猜你喜欢
    • 2017-02-26
    • 2017-10-31
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多