user1352742
user1352742

Reputation:

Passing variables between service & activity and vice-versa

I've got a service which is passed a bundle of variables (song, artist album etc.), and includes a MediaPlayer, and a bunch of methods for that MediaPlayer (play next, previous etc.).

I've also got an activity, which displays the UI to the user, including next/previous buttons, a Seekbar, and the display of the artist/album/song.

What I'd like to know is how to get the UI activity to make changes to the service, and the service to update the activity depending on which song is selected..

For example: An artist/album/song combination is sent to the service. The service tells a MediaPlayer to begin playing that song. The song title/album/artist is displayed in the activity, and the user can press play/pause etc in the UI. Upon clicking, the service will act accordingly.

I don't know how to get all these things happening, and I'm getting caught up with broadcasts and intents and statics.. I would really appreciate some clear guidance, and a good example of how this could be done.

Thank you for your patience & help.

Please find the code below:

MusicService.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();
    }

}

MusicPlayer.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

    }

}

playing.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>

Upvotes: 1

Views: 4908

Answers (2)

Privartan
Privartan

Reputation: 11

  1. You have to make a playback service that starts when the application is created you can start our service from a class that extends Application.

  2. You can use aidl to communicate a service with activity.As activity is already startedit cant get killed when the activity stops.

  3. You can use Mediastore content resolver to get data about tracks there artists albums etc..

MediaStore.Audio.Media.* Columns you want it provide all data and also path of the song

4.I am also currently in process of building player.......but all this is working as i use it

Upvotes: 1

Dheeresh Singh
Dheeresh Singh

Reputation: 15701

as general there a three main ways to commnicate with Services

1-Binder (in bind service) 2-Messenger 3-AIDL

On Android, one process cannot normally access the memory of another process. So to talk, they need to decompose their objects into primitives that the operating system can understand, and marshall the objects across that boundary for you. The code to do that marshalling is tedious to write, so Android handles it for you with AIDL.

Using AIDL is necessary only if

1- you allow clients from different applications to access your service for IPC 2- you want to handle multithreading in your service. If you do not need to perform concurrent IPC across different applications,

 Using Binder 

you should create your interface by implementing a Binder or, if you want to perform IPC, but do not need

 Using Messenger

to handle multithreading, implement your interface using a Messenger.

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

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

other then this can use

1- Broadcasting intent from service

2 -

Upvotes: 2

Related Questions