Android:如何在服务类中使用mediaController?

发布于 2024-12-28 20:39:14 字数 1705 浏览 2 评论 0原文

我有一个通过 MediaPlayer 作为服务播放广播的应用程序。是否可以在 Service 类中使用 MediaController? 问题是我可以使用findViewById。

我尝试在 onPrepeared 方法中获取 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>

I have a app that plays radio via MediaPlayer as a service. Is it possible to use MediaController in Service class?
The problem is that I can use findViewById.

I try to get my LinearLayout in onPrepeared methiod ...

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 file

<?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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ヤ经典坏疍 2025-01-04 20:39:14

您不能在您的服务中使用媒体控制器类。服务不包含 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;
}
}

You cannot use mediacontroller class in your service. A service does not contain a GUI so findViewById is not recognized by your service.
Instead create an activity which implements mediaController then create your service and bind it to your activity. So you have mediaPlayer in your service and controller in your activity.

This is an overview of activity class.

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");

}
}

This is an overview of service class.

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;
}
}
热鲨 2025-01-04 20:39:14

我遇到了同样的问题,但无法按照您的方式工作。

解决方案是在 Activity 中绑定 Service,然后您可以从 Activity 中访问在 Service 中运行的 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;
  }

是一个布尔值,用于实现是否必须创建媒体控制器,我仅在用户第一次触摸屏幕时创建。

I had the same problem and I couldn't get it working the way you have it.

The solution is to bind the Service in the Activity and then you may access the MediaPlayer running in the Service from within your Activity.

Please note that to run this way your Service must have defined all necessary methods like getCurrentPosition etc.

In your Activity add the binding facility:

/****************************************************************** 
 * 
 * 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;
    }
};

Then you must modify the onStart() and onStop() methods to Bind/unBind the service.

@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;
    }
}

What I did later is to create the following methods

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;
  }

first is a boolean that is used to realize whether we have to create the mediacontroller or not, I create only on the first time the user touches the screen.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文