Clase de actividad de Android en servicio
Tengo mi actividad abajo que juega el ShoutCastURL que fluye usando un cierto Classess del ayudante
Código:
- Obtener la orientación del dispositivo de Android incluso cuando AutoRotation está desactivado
- Cómo configurar la columna de tabla en android
- Sobre cómo trabajar con Fragment en Android 2.1 actualizado
- No se puede establecer una vista de lista personalizada en ListFragment
- Android ViewPager: fragmentos superpuestos cuando el ancho de página se establece en 90%
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 } }
El código de arriba está funcionando perfecto cuando jugué el Stream en ForeGround,
Pero mi requisito es reproducir la secuencia en el fondo también (mi código debe reproducir la secuencia, si el usuario está interactuando con las otras aplicaciones también)
Para eso, he creado una clase de servicio para la actividad anterior
Aquí está el código:
Actividad:
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(); } } }
Clase de servicio:
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; } } }
Cuando ejecuto por encima de la clase de servicio, puedo reproducir la secuencia, pero mi diseño desaparece cuando el control llega a la clase de servicio
Una cosa, quiero saber que, mi conversión de la actividad al servicio es correcto o no?
¿Podría alguien sugerirme un código correcto?
- Cómo dividir tres columnas utilizando el diseño lineal en Android
- ¿Cómo mostrar el diseño del menú en el diseño mainactivity en la ventana de vista previa en Android Studio?
- ¿Puedo subrayar texto en un diseño de Android?
- ScrollView setOverScrollMode reemplazo en API <9
- Android Studio: xmlns: el mapa no funciona
- Android.view.inflateexception binario archivo xml línea # 1 error inflar clase android.widget.relativeLayout
- No se puede arrastrar y soltar una imagen simple en el estudio android
- Cómo puedo hacer que mis botones sean más grandes
Si quieres reproducir música de fondo solo para tu aplicación, entonces la puedes reproducir en un subproceso lanzado desde tu aplicación / usar la clase AsyncTask para hacerlo por ti.
El concepto de servicios es correr en segundo plano; Por segundo plano, el significado suele ser cuando la interfaz de usuario de la aplicación NO ES VISIBLE . Es cierto, puede ser utilizado como usted tiene (si recuerda detenerlo), pero no es justo, y consume los recursos que no debe estar utilizando.
Si desea realizar tareas en el fondo de su actividad, utilice AsyncTask.
Por cierto, onStart está obsoleto. Cuando utiliza servicios, implemente onStartCommand.
ACTUALIZAR:
Creo que este código funcionará para usted. Agregue esta clase (incluida en su clase de actividad).
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; } }
Ahora, para controlar la música, guarde su objeto BackgroundSound en lugar de crearlo de forma anónima. Declártalo como un campo en tu actividad:
BackgroundSound mBackgroundSound = new BackgroundSound();
En el método onResume de su actividad, inícielo:
public void onResume() { super.onResume(); mBackgroundSound.execute(null); }
Y en el método onPause de su actividad, detenga:
public void onPause() { super.onPause(); mBackgroundSound.cancel(true); }
Esto funcionará.