Android: Как использовать mediaController в классе обслуживания? - PullRequest
3 голосов
/ 25 января 2012

У меня есть приложение, которое воспроизводит радио через MediaPlayer в качестве службы. Можно ли использовать MediaController в классе обслуживания? Проблема в том, что я могу использовать findViewById.

Я пытаюсь включить LinearLayout в готовый метиод ...

public class RadioPlayer extends Service implements OnPreparedListener, MediaController.MediaPlayerControl {
  @Override
  public void onCreate() {
  super.onCreate();
  mediaPlayer = new MediaPlayer();
  mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
  mediaPlayer.setOnPreparedListener(this);
  mediaController = new MediaController(this, false); mediaPlayer.setDataSource(url);
  mediaPlayer.prepareAsync(); 
}

@Override
  public void onPrepared(MediaPlayer mediaPlayer) {
  mediaPlayer.start();
  mediaController.setMediaPlayer(this);
  LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
  View layout = inflater.inflate(R.layout.main, (ViewGroup) findViewById(R.id.main_program_view));
  mediaController.setAnchorView(layout);
}
}

файл main.xml

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/main_program_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#FFFFFF"
        android:orientation="vertical" >  

        <TextView
            android:id="@+id/now_playing_text"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:gravity="center"
            android:text="@string/na_antenie"
            android:textColor="#333333" />    
</LinearLayout>

Ответы [ 2 ]

6 голосов
/ 09 мая 2012

Вы не можете использовать класс mediacontroller в вашем сервисе. Служба не содержит GUI, поэтому findViewById не распознается вашей службой. Вместо этого создайте действие, которое реализует mediaController, затем создайте свой сервис и свяжите его с вашим действием. Итак, у вас есть mediaPlayer в вашем сервисе и контроллер в вашей деятельности.

Это обзор класса деятельности.

public class MusicPlayerActivity extends Activity implements MediaController.MediaPlayerControl{
//Do all the stuff
void initMusic(){
    mMediaController = new MediaController(this,false);
    //Note do not create any variable of mediaplayer
    mMediaController.setMediaPlayer(this);       
    mMediaController.setAnchorView(findViewById(R.id.anchorText));

    new Thread(new Runnable() {

        @Override
        public void run() {
        startService(new Intent("PLAY_MUSIC"));
        }
    }).start();
        MusicService.setPathOfSong("Provide the path");

}
}

Это обзор класса обслуживания.

public class MusicService extends Service implements MediaPlayer.OnPreparedListener {
private MediaPlayer mMediaPlayer;
private static String pathOfSong;
public int onStartCommand(Intent intent, int flags, int startId) {
        mMediaPlayer=new MediaPlayer();
        mMediaPlayer.setOnPreparedListener(this);
        //Other stuff
}
public static void setPathOfSong(String path)
{
    pathOfSong=path;
}
}
4 голосов
/ 26 мая 2012

У меня была такая же проблема, и я не мог заставить ее работать так, как у вас.

Решение состоит в том, чтобы связать Сервис в Деятельности, и затем вы можете получить доступ к MediaPlayer, работающему в Службе, из вашей Деятельности.

Обратите внимание, что для запуска таким образом ваша Служба должна была определитьвсе необходимые методы, такие как getCurrentPosition и т. д.

В своей деятельности добавьте средство привязки:

/****************************************************************** 
 * 
 * Defines callbacks for service binding, passed to bindService() 
 * 
 * ************************************************************** */
private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className,
            IBinder service) {
        // We've bound to LocalService, cast the IBinder and get LocalService instance
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
};

Затем необходимо изменить методы onStart () и onStop () для привязки / отмены привязки службы.

@Override
protected void onStart() {
    super.onStart();
    // Bind to LocalService
    Intent intent = new Intent(this, MusicService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
    super.onStop();
    // Unbind from the service
    if (mBound) {
        unbindService(mConnection);
        mBound = false;
    }
}

То, что я сделал позже, - это создание следующих методов

public void showMediaControllerHere(){
    if (mBound){
        mc = new MediaController(mpContext);
        mc.setAnchorView(findViewById(R.id.anchorText));
        mc.setMediaPlayer(mService);
        mc.setEnabled(true);
        mc.show(0);
    }
}
@Override
  public boolean onTouchEvent(MotionEvent event) {
    //the MediaController will hide after 3 seconds - tap the screen to make it appear again
    if (first){
          if (mBound){
              showMediaControllerHere();
              first = false;
          }
      }
      else {
          if (mBound){
              mc.show(0);
          }
      }
    return false;
  }

Сначала это логическое значение, которое используется, чтобы понять, нужно ли нам создавать медиа-контроллер или нет, я создаю тольков первый раз пользователь касается экрана.

...