1

我有一个服务,它传递了一组变量(歌曲、艺术家专辑等),包括一个 MediaPlayer,以及该 MediaPlayer 的一堆方法(播放下一个、上一个等)。

我还有一个活动,它向用户显示 UI,包括下一个/上一个按钮、一个搜索栏和艺术家/专辑/歌曲的显示。

我想知道的是如何让 UI 活动对服务进行更改,以及如何让服务根据选择的歌曲更新活动。

例如:艺术家/专辑/歌曲组合被发送到服务。该服务告诉 MediaPlayer 开始播放该歌曲。歌曲名称/专辑/艺术家显示在活动中,用户可以在 UI 中按播放/暂停等。点击后,服务将采取相应的行动。

我不知道如何让所有这些事情发生,我正忙于广播、意图和静态。我真的很感激一些明确的指导,以及如何做到这一点的一个很好的例子。

感谢您的耐心和帮助。

请在下面找到代码:

音乐服务.java:

package awesome.music.player;

import java.io.IOException;
import java.util.ArrayList;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;

public class MusicService extends Service implements OnCompletionListener,
        OnSeekCompleteListener {

    Intent intent;

    MediaPlayer mediaPlayer = new MediaPlayer();

    String isComplete;
    String serviceStatus;
    String sntSeekPos;
    String artist;
    String selection;
    String album;
    String numSongs;
    int albumId;
    String currentSongPath;

    String[] selectionArgs;

    Uri currentSongUri;

    int songEnded;
    int currentSongIndex;
    int totalSongDuration;

    int intSeekPos;
    int mediaPosition;
    int mediaMax;

    ArrayList<String> pathList;
    ArrayList<String> artistList;
    ArrayList<String> albumList;
    ArrayList<String> titleList;
    ArrayList<String> idList;
    ArrayList<String> durationList;

    private final Handler handler = new Handler();

    public final String BROADCAST_ACTION = "awesome.music.player.seekprogress";
    public final String BROADCAST_OTHER = "awesome.music.player.displaysong";
    Intent seekIntent;
    Intent displayIntent;
    Utilities utils;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        this.intent = intent;

        Bundle extras = intent.getExtras();

        artist = extras.getString("artist");
        selection = extras.getString("selection");
        selectionArgs = extras.getStringArray("selectionArgs");
        album = extras.getString("album");
        albumId = extras.getInt("albumId");
        numSongs = extras.getString("numSongs");
        currentSongIndex = extras.getInt("currentSongIndex");
        currentSongPath = extras.getString("currentSongPath");
        totalSongDuration = extras.getInt("totalSongDuration");

        pathList = extras.getStringArrayList("pathList");
        artistList = extras.getStringArrayList("artistList");
        albumList = extras.getStringArrayList("albumList");
        titleList = extras.getStringArrayList("titleList");
        idList = extras.getStringArrayList("idList");
        durationList = extras.getStringArrayList("durationList");

        prepareSong(currentSongPath);
        playSong();
        displaySong();
        utils = new Utilities();
        seekIntent = new Intent(BROADCAST_ACTION);
        displayIntent = new Intent(BROADCAST_ACTION);
        setupHandler();

        return START_STICKY;

    }

    /*
     * @Override public void onCreate() { super.onCreate();
     * 
     * utils = new Utilities();
     * 
     * seekIntent = new Intent(BROADCAST_ACTION);
     * 
     * setupHandler();
     * 
     * prepareSong(currentSongPath); playSong(); }
     */

    public void prepareSong(String currentSongPath) {
        try {
            mediaPlayer.reset();
            mediaPlayer.setDataSource(currentSongPath);
            mediaPlayer.prepare();

        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void playSong() {

        try {
            mediaPlayer.start();

        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }

    }

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    public void onCompletion(MediaPlayer mediaPlayer) {
        playNext();

    }

    @Override
    public void onStart(Intent intent, int startId) {

        registerReceiver(broadcastReceiver, new IntentFilter(
                MusicPlayer.BROADCAST_SEEKBAR));
        super.onCreate();
        prepareSong(currentSongPath);
        playSong();
    }

    private void setupHandler() {
        handler.removeCallbacks(sendUpdatesToUI);
        handler.postDelayed(sendUpdatesToUI, 1000);

    }

    private Runnable sendUpdatesToUI = new Runnable() {
        public void run() {

            LogMediaPosition();

            handler.postDelayed(this, 1000);

        }

    };

    private void LogMediaPosition() {
        if (mediaPlayer.isPlaying()) {
            mediaPosition = mediaPlayer.getCurrentPosition();

            MusicPlayer.currentDurationLabel.setText(""
                    + utils.milliSecondsToTimer(mediaPosition));

            mediaMax = mediaPlayer.getDuration();
            seekIntent.putExtra("counter", String.valueOf(mediaPosition));
            seekIntent.putExtra("mediamax", String.valueOf(mediaMax));
            seekIntent.putExtra("song_ended", String.valueOf(songEnded));
            sendBroadcast(seekIntent);
        }
    }

    private void displaySong() {

        utils = new Utilities();

        String title = titleList.get(currentSongIndex);
        String artist = artistList.get(currentSongIndex);
        String album = albumList.get(currentSongIndex);

        Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");

        Uri currentSongUri = ContentUris.withAppendedId(sArtworkUri, albumId);

        String totalDuration = utils.milliSecondsToTimer(totalSongDuration);

        mediaPosition = mediaPlayer.getCurrentPosition();

        MusicPlayer.currentDurationLabel.setText(""
                + utils.milliSecondsToTimer(mediaPosition));

        displayIntent.putExtra("title", title);
        displayIntent.putExtra("artist", artist);
        displayIntent.putExtra("album", album);
        displayIntent.putExtra("totalDuration", totalDuration);
        displayIntent.putExtra("currentSongUri", currentSongUri);
        sendBroadcast(displayIntent);

    }

    // receive seekbar position

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            updateSeekPos(intent);

        }
    };

    // Update seek position from Activity
    public void updateSeekPos(Intent intent) {
        int seekPos = intent.getIntExtra("seekpos", 0);
        if (mediaPlayer.isPlaying()) {
            handler.removeCallbacks(sendUpdatesToUI);
            mediaPlayer.seekTo(seekPos);
            setupHandler();

        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mediaPlayer.stop();
        handler.removeCallbacks(sendUpdatesToUI);
        // Unregister seek receiver
        unregisterReceiver(broadcastReceiver);
    }

    public void onSeekComplete(MediaPlayer mediaPlayer) {
        if (!mediaPlayer.isPlaying()) {
            mediaPlayer.start();
        }

    }

    public void playNext() {

        if (mediaPlayer.isPlaying()) {

            if (currentSongIndex < (pathList.size() - 1)) {
                currentSongIndex = currentSongIndex + 1;
                currentSongPath = pathList.get(currentSongIndex);

                prepareSong(currentSongPath);
                playSong();
            } else {
                currentSongIndex = 0;
                currentSongPath = pathList.get(currentSongIndex);
                prepareSong(currentSongPath);
                playSong();
            }
        } else {
            if (currentSongIndex < (pathList.size() - 1)) {
                currentSongIndex = currentSongIndex + 1;
                currentSongPath = pathList.get(currentSongIndex);

                prepareSong(currentSongPath);
            } else {
                currentSongIndex = 0;
                prepareSong(currentSongPath);
            }
        }

        displaySong();
    }

    void playPrevious() {

        if (mediaPlayer.isPlaying()) {

            if (currentSongIndex > 0) {
                currentSongIndex = currentSongIndex - 1;
                currentSongPath = pathList.get(currentSongIndex);

                prepareSong(currentSongPath);
                playSong();
            } else {
                currentSongIndex = pathList.size() - 1;
                currentSongPath = pathList.get(currentSongIndex);

                prepareSong(currentSongPath);
                playSong();
            }
        } else {
            if (currentSongIndex > 0) {
                currentSongIndex = currentSongIndex - 1;
                currentSongPath = pathList.get(Playlist.currentSongIndex);

                prepareSong(currentSongPath);
            } else {
                currentSongIndex = pathList.size() - 1;
                currentSongPath = pathList.get(currentSongIndex);

                prepareSong(currentSongPath);
            }
        }
        displaySong();
    }

}

音乐播放器.java:

package awesome.music.player;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

public class MusicPlayer extends Activity implements OnSeekBarChangeListener {

    public ImageButton play;
    public ImageButton next;
    public ImageButton previous;

    public static ImageView albumArt;

    static TextView songArtistAlbumLabel;
    static TextView songTitleLabel;
    static TextView currentDurationLabel;
    static TextView totalDurationLabel;

    static String serviceStatus;

    private SeekBar seekBar;

    private int seekMax;

    boolean mBroadcastIsRegistered;

    public static Utilities utils;

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

        play = (ImageButton) findViewById(R.id.playButton);
        next = (ImageButton) findViewById(R.id.nextButton);
        previous = (ImageButton) findViewById(R.id.previousButton);
        albumArt = (ImageView) findViewById(R.id.imageView1);

        songArtistAlbumLabel = (TextView) findViewById(R.id.songArtistAlbumLabel);
        songTitleLabel = (TextView) findViewById(R.id.songTitleLabel);
        totalDurationLabel = (TextView) findViewById(R.id.totalDurationLabel);
        songArtistAlbumLabel = (TextView) findViewById(R.id.songArtistAlbumLabel);

        play.setOnClickListener(playListener);
        next.setOnClickListener(nextListener);
        previous.setOnClickListener(previousListener);

        seekBar = (SeekBar) findViewById(R.id.seekBar);
        seekBar.setOnSeekBarChangeListener(this);

        intent = new Intent(BROADCAST_SEEKBAR);

        if (mBroadcastIsRegistered != true) {
            registerReceiver(broadcastReceiver, new IntentFilter(
                    MusicService.BROADCAST_ACTION));
            ;

            mBroadcastIsRegistered = true;
        }

    }

    private OnClickListener playListener = new OnClickListener() {
        public void onClick(View v) {
            MusicService.playSong();

        }
    };

    private OnClickListener nextListener = new OnClickListener() {
        public void onClick(View v) {
            MusicService.playNext();
        }
    };

    private OnClickListener previousListener = new OnClickListener() {
        public void onClick(View v) {
            MusicService.playPrevious();
        }
    };

    public static final String BROADCAST_SEEKBAR = "awesome.music.player.sendseekbar";
    Intent intent;

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent serviceIntent) {
            updateUI(serviceIntent);
        }
    };

    private void updateUI(Intent serviceIntent) {
        String counter = serviceIntent.getStringExtra("counter");
        String mediamax = serviceIntent.getStringExtra("mediamax");
        String strSongEnded = serviceIntent.getStringExtra("song_ended");
        int seekProgress = Integer.parseInt(counter);
        seekMax = Integer.parseInt(mediamax);
        Integer.parseInt(strSongEnded);
        seekBar.setMax(seekMax);
        seekBar.setProgress(seekProgress);
    }

    public void onProgressChanged(SeekBar seekBar, int progress,
            boolean fromUser) {
        if (fromUser) {
            int seekPos = seekBar.getProgress();
            intent.putExtra("seekpos", seekPos);
            sendBroadcast(intent);
        }

    }

    public void onStartTrackingTouch(SeekBar seekBar) {
        // TODO Auto-generated method stub

    }

    public void onStopTrackingTouch(SeekBar seekBar) {
        // TODO Auto-generated method stub

    }

}

播放.xml:

<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="296dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_x="10dp"
        android:layout_y="446dp"
        android:paddingLeft="6dp"
        android:paddingRight="6dp"
        android:progressDrawable="@drawable/seekbar_progress"
        android:thumb="@drawable/seek_handler" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="37dp"
        android:layout_height="37dp"
        android:layout_x="6dp"
        android:layout_y="397dp"
        android:src="@drawable/ic_tab_albums_white" />

    <TextView
        android:id="@+id/songTitleLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="55dp"
        android:layout_y="395dp"
        android:text="Song Label"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/songArtistAlbumLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="55dp"
        android:layout_y="417dp"
        android:text="Artist - Album Label"
        android:textSize="15sp" />

    <TextView
        android:id="@+id/currentDurationLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="10dp"
        android:layout_y="481dp"
        android:text="0:00" />

    <TextView
        android:id="@+id/totalDurationLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="281dp"
        android:layout_y="477dp"
        android:text="3:30" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_x="41dp"
        android:layout_y="312dp"
        android:gravity="center_horizontal" >

        <ImageButton
            android:id="@+id/previousButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_x="132dp"
            android:layout_y="308dp"
            android:src="@drawable/ic_previous" />

        <ImageButton
            android:id="@+id/playButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50sp"
            android:layout_marginRight="50sp"
            android:src="@drawable/ic_pause" />

        <ImageButton
            android:id="@+id/nextButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_next" />
    </LinearLayout>

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="287dp"
        android:layout_height="272dp"
        android:layout_x="16dp"
        android:layout_y="13dp"
        android:background="@drawable/dummy_album_art"
        android:scaleType="fitXY" />

</AbsoluteLayout>
4

2 回答 2

2

一般来说,与服务通信的三种主要方式

1-Binder(在绑定服务中) 2-Messenger 3-AIDL

在 Android 上,一个进程不能正常访问另一个进程的内存。所以说,他们需要将他们的对象分解为操作系统可以理解的原语,并为你将对象编组跨越该边界。进行编组的代码编写起来很乏味,因此 Android 使用 AIDL 为您处理它。

Using AIDL is necessary only if

1-您允许来自不同应用程序的客户端访问您的 IPC 服务 2-您希望在您的服务中处理多线程。如果您不需要跨不同应用程序执行并发 IPC,

 Using Binder 

你应该通过实现一个Binder来创建你的接口,或者,如果你想执行IPC,但不需要

 Using Messenger

要处理多线程,请使用 Messenger 实现您的界面。

http://developer.android.com/guide/developing/tools/aidl.html

http://java.dzone.com/articles/android-aidl-and-remote-client

其他然后这可以使用

1- 来自服务的广播意图

2 -

于 2012-06-07T12:38:40.067 回答
1
  1. 您必须创建一个在创建应用程序时启动的播放服务,您可以从扩展 Application 的类启动我们的服务。

  2. 您可以使用aidl 与活动通信服务。由于活动已经开始,当活动停止时它不能被杀死。

  3. 您可以使用 Mediastore 内容解析器来获取有关艺术家专辑等曲目的数据。

MediaStore.Audio.Media.* 您希望它提供所有数据的列以及歌曲的路径

4.我目前也在构建播放器.......但是这一切都在我使用它时工作

于 2012-07-19T07:03:18.613 回答