2013-05-03 73 views
4

我有我的活動下起着使用一些輔助類新Android的活動,以服務

守則ShoutCastURL流:

import java.net.MalformedURLException; 

import com.androidworkz.androidshoutcastlib.AndroidShoutcastLib; 
import com.androidworkz.androidshoutcastlib.InvalidStreamURLException; 
import com.androidworkz.androidshoutcastlib.Metadata; 
import com.androidworkz.androidshoutcastlib.MetadataListener; 

import android.media.AudioManager; 
import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnBufferingUpdateListener; 
import android.media.MediaPlayer.OnCompletionListener; 
import android.media.MediaPlayer.OnErrorListener; 
import android.media.MediaPlayer.OnPreparedListener; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.PowerManager; 
import android.app.Activity; 
import android.util.Log; 
import android.view.Menu; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.TextView; 

public class Player extends Activity implements OnCompletionListener, 
OnPreparedListener, OnErrorListener, OnBufferingUpdateListener, MusicFocusable { 

    private Boolean playState = false; 
    private String station = "http://38.101.195.5:9156"; 
    public static final float DUCK_VOLUME = 0.1f; 
    private String artistName = null; 
    private String trackName = null; 

    private TextView artist; 
    private TextView track; 
    private TextView status; 
    private Button play; 

    enum AudioFocus { 
     NoFocusNoDuck, // we don't have audio focus, and can't duck 
     NoFocusCanDuck, // we don't have focus, but can play at a low volume 
         // ("ducking") 
     Focused // we have full audio focus 
    } 

    private AudioFocus mAudioFocus = AudioFocus.NoFocusNoDuck; 

    private MediaPlayer mPlayer = null; 
    private AndroidShoutcastLib shoutcast; 
    private AudioManager mAudioManager; 
    AudioFocusHelper mAudioFocusHelper = null; 

    Handler handler = new Handler(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_player); 

     mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE); 

     // create the Audio Focus Helper, if the Audio Focus feature is 
     // available (SDK 8 or above) 
     if (android.os.Build.VERSION.SDK_INT >= 8) { 
      mAudioFocusHelper = new AudioFocusHelper(getApplicationContext(), 
        this); 
     } 
     else { 
      mAudioFocus = AudioFocus.Focused; // no focus feature, so we always "have" audio focus 
     } 

     status = (TextView) findViewById(R.id.status); 

     artist = (TextView) findViewById(R.id.artist); 
     artist.setSelected(true); 

     track = (TextView) findViewById(R.id.track); 
     track.setSelected(true); 

     play = (Button) findViewById(R.id.play); 

     play.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View btn) { 
       if (!playState) { 
        play.setText("Pause"); 
        handler.postDelayed(handlePlayRequest, 300); 
       } 
       else { 
        play.setText("Play"); 
        status.setText("Press Play"); 
        handler.postDelayed(handlePlayRequest, 300); 
       } 
      } 

     }); 

     shoutcast = new AndroidShoutcastLib(); 

     try { 
      shoutcast.setShoutcastUrl(station); 
     } catch (InvalidStreamURLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     shoutcast.setOnMetadataChangedListener(new MetadataListener(){ 

      @Override 
      public void OnMetadataChanged(Metadata item) { 
       artistName = item.artist; 
       trackName = item.track;    
       updateMeta(); 
      } 
     }); 

     setVolumeControlStream(AudioManager.STREAM_MUSIC);  
    } 

    public void onDestroy() { 
     super.onDestroy(); 

     shoutcast = null; 
     handler.removeCallbacks(handlePlayRequest); 
    } 

    public void updateMeta() { 
     handler.post(new Runnable() { 
      @Override 
      public void run() { 
       // This gets executed on the UI thread so it can safely modify Views 
       artist.setText(artistName); 
       track.setText(trackName); 
      } 
     }); 
    } 

    private final Runnable handlePlayRequest = new Runnable() { 
     public void run() { 
      if (playState) { 
       Log.d("Player", "Stop Called"); 
       giveUpAudioFocus(); 
       mPlayer.stop(); 
       mPlayer.reset(); 
       mPlayer.release(); 
       shoutcast.stopStream(); 
       mPlayer = null; 
       playState = false; 
      } 
      else { 
       Log.d("Player", "Play Called"); 
       createMediaPlayer(); 
       getAudioFocus(); 

       try { 
        mPlayer.setDataSource(shoutcast.startStream()); 
       } catch (IllegalArgumentException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (SecurityException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (IllegalStateException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (MalformedURLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (InvalidStreamURLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       mPlayer.prepareAsync(); 
      } 
     } 
    }; 

    private void createMediaPlayer() { 
     mPlayer = new MediaPlayer(); 

     // Make sure the media player will acquire a wake-lock while 
     // playing. If we don't do 
     // that, the CPU might go to sleep while the song is playing, 
     // causing playback to stop. 
     // 
     // Remember that to use this, we have to declare the 
     // android.permission.WAKE_LOCK 
     // permission in AndroidManifest.xml. 
     mPlayer.setWakeMode(getApplicationContext(), 
       PowerManager.PARTIAL_WAKE_LOCK); 

     // we want the media player to notify us when it's ready preparing, 
     // and when it's done 
     // playing: 
     mPlayer.setOnPreparedListener(this); 
     mPlayer.setOnCompletionListener(this); 
     mPlayer.setOnErrorListener(this); 
    } 

    private void startPlayer() { 
     mPlayer.setVolume(1.0f, 1.0f); 
     if (!mPlayer.isPlaying()) { 
      Log.d("Player", "Starting Playback"); 
      mPlayer.start(); 
      playState = true; 
      status.setText("Streaming"); 
     }    
    } 

    private void getAudioFocus() { 
     if (mAudioFocus != AudioFocus.Focused && mAudioFocusHelper != null 
       && mAudioFocusHelper.requestFocus()) 
      mAudioFocus = AudioFocus.Focused; 
    } 

    private void giveUpAudioFocus() { 
     if (mAudioFocus == AudioFocus.Focused && mAudioFocusHelper != null 
       && mAudioFocusHelper.abandonFocus()) 
      mAudioFocus = AudioFocus.NoFocusNoDuck; 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.activity_player, menu); 
     return true; 
    } 

    @Override 
    public void onBufferingUpdate(MediaPlayer arg0, int arg1) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public boolean onError(MediaPlayer mp, int what, int extra) { 
     playState = false; 
     handler.post(handlePlayRequest); 
     return false; 
    } 

    @Override 
    public void onPrepared(MediaPlayer arg0) { 
     startPlayer();  
    } 

    @Override 
    public void onCompletion(MediaPlayer arg0) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onGainedAudioFocus() { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onLostAudioFocus(boolean canDuck) { 
     // TODO Auto-generated method stub 

    } 

} 

上面的代碼工作完美的,當我在前臺扮演的流,

但我的要求是在後臺播放流(我的代碼應播放流,如果用戶與其他應用程序交互)

爲此,我已經創建了一個服務類到上述活動

這裏是代碼:

活動:

import android.os.Bundle; 
import android.app.Activity; 
import android.content.Intent; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.TextView; 

public class Player extends Activity implements OnClickListener { 

    private Boolean playState = false; 
    public static final float DUCK_VOLUME = 0.1f; 
    private String artistName = null; 
    private String trackName = null; 

    private TextView artist; 
    private TextView track; 
    private TextView status; 
    private Button play; 

    Intent playbackServiceIntent; 

    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_player); 

     // create the Audio Focus Helper, if the Audio Focus feature is 
     // available (SDK 8 or above) 

     status = (TextView) findViewById(R.id.status); 

     artist = (TextView) findViewById(R.id.artist); 
     artist.setSelected(true); 

     track = (TextView) findViewById(R.id.track); 
     track.setSelected(true); 

     play = (Button) findViewById(R.id.play); 

     play.setOnClickListener(this); 

     playbackServiceIntent = new Intent(this, BackGroundService.class); 

    } 

    @Override 
    public void onClick(View v) { 
     if (v == play) { 
      startService(playbackServiceIntent); 
      Log.d("hi>>>>>", "gjgj"); 
      finish(); 
     } 
    } 

} 

服務類:

import com.androidworkz.androidshoutcastlib.AndroidShoutcastLib; 
import com.androidworkz.androidshoutcastlib.InvalidStreamURLException; 

import android.app.Service; 
import android.content.Intent; 
import android.media.AudioManager; 
import android.media.MediaPlayer; 
import android.media.MediaPlayer.OnBufferingUpdateListener; 
import android.media.MediaPlayer.OnCompletionListener; 
import android.media.MediaPlayer.OnErrorListener; 
import android.media.MediaPlayer.OnPreparedListener; 
import android.os.AsyncTask; 
import android.os.Handler; 
import android.os.IBinder; 
import android.os.PowerManager; 
import android.util.Log; 

public class BackGroundService extends Service implements OnCompletionListener, 
     OnPreparedListener, OnErrorListener, OnBufferingUpdateListener, 
     MusicFocusable { 
    private Boolean playState = false; 
    private String station = "http://38.101.195.5:9156"; 
    public static final float DUCK_VOLUME = 0.1f; 
    Runnable handlePlayRequest; 

    enum AudioFocus { 
     NoFocusNoDuck, // we don't have audio focus, and can't duck 
     NoFocusCanDuck, // we don't have focus, but can play at a low volume 
         // ("ducking") 
     Focused // we have full audio focus 
    } 

    private AudioFocus mAudioFocus = AudioFocus.NoFocusNoDuck; 

    private MediaPlayer mPlayer = null; 
    private AndroidShoutcastLib shoutcast; 
    private AudioManager mAudioManager; 
    AudioFocusHelper mAudioFocusHelper = null; 

    Handler handler = new Handler(); 

    @Override 
    public IBinder onBind(Intent arg0) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.d("onStartCommand>>>", "onStartCommand"); 

     mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE); 

     // create the Audio Focus Helper, if the Audio Focus feature is 
     // available (SDK 8 or above) 
     if (android.os.Build.VERSION.SDK_INT >= 8) { 
      mAudioFocusHelper = new AudioFocusHelper(getApplicationContext(), 
        this); 
     } else { 
      mAudioFocus = AudioFocus.Focused; // no focus feature, so we always 
               // "have" audio focus 
     } 
     shoutcast = new AndroidShoutcastLib(); 

     try { 
      Log.d("Station>>>", station); 

      shoutcast.setShoutcastUrl(station); 

     } catch (InvalidStreamURLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     new BackgroundSound().execute(); 

     return START_STICKY; 
    } 

    public void onDestroy() { 
     Log.d("onDestroy>>>", "onDestroy"); 

     if (mPlayer.isPlaying()) { 
      mPlayer.stop(); 
     } 
     mPlayer.release(); 
    } 

    @Override 
    public void onGainedAudioFocus() { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onLostAudioFocus(boolean canDuck) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onBufferingUpdate(MediaPlayer arg0, int arg1) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public boolean onError(MediaPlayer arg0, int arg1, int arg2) { 
     // TODO Auto-generated method stub 
     return false; 
    } 

    @Override 
    public void onPrepared(MediaPlayer arg0) { 
     // TODO Auto-generated method stub 
     mPlayer.start(); 
    } 

    private void giveUpAudioFocus() { 
     if (mAudioFocus == AudioFocus.Focused && mAudioFocusHelper != null 
       && mAudioFocusHelper.abandonFocus()) 
      mAudioFocus = AudioFocus.NoFocusNoDuck; 
    } 

    @Override 
    public void onCompletion(MediaPlayer arg0) { 
     // TODO Auto-generated method stub 
     stopSelf(); 
    } 

    private void getAudioFocus() { 
     if (mAudioFocus != AudioFocus.Focused && mAudioFocusHelper != null 
       && mAudioFocusHelper.requestFocus()) 
      mAudioFocus = AudioFocus.Focused; 
    } 

    private void createMediaPlayer() { 
     mPlayer = new MediaPlayer(); 

     // Make sure the media player will acquire a wake-lock while 
     // playing. If we don't do 
     // that, the CPU might go to sleep while the song is playing, 
     // causing playback to stop. 
     // 
     // Remember that to use this, we have to declare the 
     // android.permission.WAKE_LOCK 
     // permission in AndroidManifest.xml. 
     mPlayer.setWakeMode(getApplicationContext(), 
       PowerManager.PARTIAL_WAKE_LOCK); 

     // we want the media player to notify us when it's ready preparing, 
     // and when it's done 
     // playing: 
     mPlayer.setOnPreparedListener(this); 
     mPlayer.setOnCompletionListener(this); 
     mPlayer.setOnErrorListener(this); 
    } 

    private class BackgroundSound extends AsyncTask<Void, Void, Void> { 
     @Override 
     protected Void doInBackground(Void... params) { 
      Log.d("doInBackground>>>", "doInBackground"); 

      Log.d("run>>>", "run"); 

      if (playState) { 
       Log.d("Player", "Stop Called"); 
       giveUpAudioFocus(); 
       mPlayer.stop(); 
       mPlayer.reset(); 
       mPlayer.release(); 
       shoutcast.stopStream(); 
       mPlayer = null; 
       playState = false; 
      } else { 
       Log.d("Player", "Play Called"); 
       createMediaPlayer(); 
       getAudioFocus(); 

       try { 
        mPlayer.setDataSource(shoutcast.startStream()); 
       } catch (IllegalArgumentException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (SecurityException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (IllegalStateException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (MalformedURLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (InvalidStreamURLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       mPlayer.prepareAsync(); 
      } 

      return null; 
     } 
    } 

} 

當我在上面執行服務類別,我可以播放流,但是當控制服務類別時,我的佈局消失

有一件事,我想知道,我從活動到服務的轉換是正確的還是不正確?

任何人可以建議我正確的代碼?

回答

1

如果您只想爲您的應用播放背景音樂,請在您的應用中啓動的線程中播放它/使用AsyncTask類爲您完成。

服務的概念是在後臺運行;背景的意思通常是當你的應用UI是不可見。誠然,它可以像你一樣使用(如果你記得要停止它),但它不正確,它會消耗你不應該使用的資源。

如果您想在活動的背景上執行任務,請使用AsyncTask。

順便說一下,onStart已被棄用。當你使用服務時,實現onStartCommand。

UPDATE:

我覺得這段代碼會爲你工作。添加這個類(包含在你的活動類中)。

 public class BackgroundSound extends AsyncTask<Void, Void, Void> { 
      @Override 
     protected Void doInBackground(Void... params) { 
     MediaPlayer player = MediaPlayer.create(YourActivity.this, R.raw.test_cbr); 
     player.setLooping(true); // Set looping 
     player.setVolume(100,100); 
     player.start(); 
     return null; 
      } 
     } 

現在,爲了控制音樂,保存BackgroundSound對象,而不是annonymously創建它的。聲明它作爲一個外地在您的活動:

 BackgroundSound mBackgroundSound = new BackgroundSound(); 

您的活動的的onResume方法,啓動它:

  public void onResume() { 
      super.onResume(); 
      mBackgroundSound.execute(null); 
      } 

而且你的活動的的onPause方法,阻止它:

  public void onPause() { 
      super.onPause(); 
      mBackgroundSound.cancel(true); 
       } 

這將起作用。

+0

如果假設我們有2個活動,Activity1到Activity2,在Activity2中我寫了Background running task,如果假設用戶點擊BackButton然後點擊應用圖標,我應該可以看到Activity 2的佈局,但是In我的情況我的活動再次開始(從Activity1到Activity2) – 2013-05-03 12:02:10