Parkinson
Parkinson

Reputation: 71

Accessing a view from a service

So basically, i got a list view that shows a list of bands. When i press on one of the bands in the list, it creates a band profile page via an adapter. In this layout, i got a play button, which starts a MediaPlayer service and play a song.

So far, so good.

The problem is, im trying to update the seekBar, located in the band profile page (created by the adapter mentioned above), from the MediaPlayer service Java file, but i'm unable to reach it.

i'm trying to use :

    LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
    View layout = inflater.inflate(R.layout.activity_singleband, null, false);
    seekBar = (SeekBar) layout.findViewById(R.id.seekBarBand);

but it seems that it uses another "instance" of the view, and not the one i'm currently viewing.

Here is the full MusicService Java file:

public class MusicService extends Service {
    SeekBar seekBar;
    Handler handler;
    Runnable runnable;

    NotificationManager nMN;

    TextView BandName;

    String songLink;
    String songName;
    String bandName;

    String SongPlaying="";
    String BandPlaying="";

    public static MediaPlayer mp;
    public static Boolean mpState = true;
    public static Boolean mpPause = false;
    public static Boolean isPlaying = false;


    @Override
    public void onCreate() {
                super.onCreate();

    }
    // Play Cycle for seekBar
    public void PlayCycle(){
        seekBar.setProgress(mp.getCurrentPosition());
        if (mp.isPlaying()){
            runnable = new Runnable() {
                @Override
                public void run() {
                    PlayCycle();

                }
            };
            handler.postDelayed(runnable, 1000);
        }

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        songLink = intent.getStringExtra("SongLink");
        songName = intent.getStringExtra("SongName");
        bandName = intent.getStringExtra("BandName");


        LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
        View layout = inflater.inflate(R.layout.activity_singleband, null, false);
        seekBar = (SeekBar) layout.findViewById(R.id.seekBarBand);
        BandName = (TextView) layout.findViewById(R.id.singleBandNameView);
        BandName.setText("Bla Bla");
        System.out.print("Band Name : "+ BandName.getText() );

        handler = new Handler();

        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean input) {
                if (input){
                    mp.seekTo(progress); 
                }
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });

        if (isPlaying && !songName.equals(SongPlaying) && !BandPlaying.equals(bandName)) {
            Stop();
            mp = new MediaPlayer();
            mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
            try {
                Uri songUri = Uri.parse(songLink);
                mp.setDataSource(getApplicationContext(), songUri);
                SongPlaying = songName;
                Toast.makeText(getApplicationContext(), "Please wait", Toast.LENGTH_SHORT).show();
                isPlaying=true;
                new prepare().execute();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        else if (!isPlaying && !songName.equals(SongPlaying) && !BandPlaying.equals(bandName) ) {
            mp = new MediaPlayer();
            mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
            try {
                Uri songUri = Uri.parse(songLink);
                mp.setDataSource(getApplicationContext(), songUri);
                SongPlaying = songName;
                Toast.makeText(getApplicationContext(), "Please wait", Toast.LENGTH_SHORT).show();
                new prepare().execute();
                isPlaying=true;
            }
            catch (IOException e) {
                e.printStackTrace();
            }

        }
        else {
            Toast.makeText(getApplicationContext(), "Song is Already Playing", Toast.LENGTH_SHORT).show();

        }
        return super.onStartCommand(intent, flags, startId);
        }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mp.release();
        handler.removeCallbacks(runnable);
    }




    /// Permanent Notification
    private void showNotification() {
        nMN = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        Notification n = new Notification.Builder(this)
                .setContentTitle(songName)
                .setContentText(bandName)
                .setSmallIcon(R.drawable.ic_bandcamp)
                //.addAction(R.drawable.ic_play_arrow_black_24dp, "button1", new pause())
                .setOngoing(true)
                .build();
        nMN.notify(1, n);
    }

    /// PREPARE SONG TO PLAY //
    public class prepare extends AsyncTask {
        @Override
        protected Object doInBackground(Object[] objects) {
            try {
                mp.prepare();
                PlayCycle();
                seekBar.setMax(mp.getDuration());
                mp.start();
                SongPlaying = songName;
                isPlaying=true;
                showNotification();  // show notification
                mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        Toast.makeText(getApplicationContext(),"Song Finished", Toast.LENGTH_LONG).show();
                        new stop().execute();
                    }
                });
            } catch (IOException io){ io.printStackTrace(); }
            return null; }}


    /// STOP PLAYING SONG //
    public static void Stop()
    {
        mp.reset();
        mp.release();
        isPlaying=false;
    }
    public static class stop extends AsyncTask {
        @Override
        protected Object doInBackground(Object[] objects) {
            try {
                mp.reset();
                mp.release();
                isPlaying=false;
            } catch (Exception io){ io.printStackTrace(); }
            return null; }}

    /// PAUSE PLAYING SONG//
    public static class pause extends AsyncTask {
        @Override
        protected Object doInBackground(Object[] objects) {
            try {
                mp.pause(); }
            catch (Exception io){ io.printStackTrace();   }
            return null; }}

    public static class start extends AsyncTask {
        @Override
        protected Object doInBackground(Object[] objects) {
            try {
                mp.start(); }
            catch (Exception io){ io.printStackTrace();   }
            return null; }}

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

Upvotes: 0

Views: 897

Answers (1)

Alexei Artsimovich
Alexei Artsimovich

Reputation: 1184

Okey Firstly I suggest you to read more about Android Service classes. Secondly Do NOT place you visual components like a SeekBar or TextView in the Service because it doesn't make any sense. Service is just a background task and do not know about the UI. Since it's executed in the background you don't even need AsyncTask inside this so thirdly remove ALL AsyncTasks in your service and run their task like they don't need to be executed in the background.

So all what you have to do is create a Fragment/Activity for the UI, then bind your Fragment/Acitivity with your Service to communicate and update UI components. The easiest way is make the Service a Singleton like it's done here:

    public class MusicService extends Service {
private static MusicService instance = null;

public static MusicService getInstance() {
    return instance;
}

Handler handler;
Runnable runnable;

NotificationManager nMN;

String songLink;
String songName;
String bandName;

String SongPlaying="";
String BandPlaying="";

public static MediaPlayer mp;
public static Boolean mpState = true;
public static Boolean mpPause = false;
public static Boolean isPlaying = false;


@Override
public void onCreate() {
    instance = this;
    super.onCreate();
}
// Play Cycle for seekBar
public void PlayCycle(){
    seekBar.setProgress(mp.getCurrentPosition());
    if (mp.isPlaying()){
        runnable = new Runnable() {
            @Override
            public void run() {
                PlayCycle();

            }
        };
        handler.postDelayed(runnable, 1000);
    }

}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    songLink = intent.getStringExtra("SongLink");
    songName = intent.getStringExtra("SongName");
    bandName = intent.getStringExtra("BandName");
    handler = new Handler();

    if (isPlaying && !songName.equals(SongPlaying) && !BandPlaying.equals(bandName)) {
        Stop();
        mp = new MediaPlayer();
        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
        try {
            Uri songUri = Uri.parse(songLink);
            mp.setDataSource(getApplicationContext(), songUri);
            SongPlaying = songName;
            Toast.makeText(getApplicationContext(), "Please wait", Toast.LENGTH_SHORT).show();
            isPlaying=true;
            new prepare().execute();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
    else if (!isPlaying && !songName.equals(SongPlaying) && !BandPlaying.equals(bandName) ) {
        mp = new MediaPlayer();
        mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
        try {
            Uri songUri = Uri.parse(songLink);
            mp.setDataSource(getApplicationContext(), songUri);
            SongPlaying = songName;
            Toast.makeText(getApplicationContext(), "Please wait", Toast.LENGTH_SHORT).show();
            new prepare().execute();
            isPlaying=true;
        }
        catch (IOException e) {
            e.printStackTrace();
        }

    }
    else {
        Toast.makeText(getApplicationContext(), "Song is Already Playing", Toast.LENGTH_SHORT).show();

    }
    return super.onStartCommand(intent, flags, startId);
    }

@Override
public void onDestroy() {
    super.onDestroy();
    mp.release();
    handler.removeCallbacks(runnable);
}




/// Permanent Notification
private void showNotification() {
    nMN = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Notification n = new Notification.Builder(this)
            .setContentTitle(songName)
            .setContentText(bandName)
            .setSmallIcon(R.drawable.ic_bandcamp)
            //.addAction(R.drawable.ic_play_arrow_black_24dp, "button1", new pause())
            .setOngoing(true)
            .build();
    nMN.notify(1, n);
}

/// PREPARE SONG TO PLAY //
public class prepare extends AsyncTask {
    @Override
    protected Object doInBackground(Object[] objects) {
        try {
            mp.prepare();
            PlayCycle();
            seekBar.setMax(mp.getDuration());
            mp.start();
            SongPlaying = songName;
            isPlaying=true;
            showNotification();  // show notification
            mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    Toast.makeText(getApplicationContext(),"Song Finished", Toast.LENGTH_LONG).show();
                    new stop().execute();
                }
            });
        } catch (IOException io){ io.printStackTrace(); }
        return null; }}


/// STOP PLAYING SONG //
public static void Stop()
{
    mp.reset();
    mp.release();
    isPlaying=false;
}
public static class stop extends AsyncTask {
    @Override
    protected Object doInBackground(Object[] objects) {
        try {
            mp.reset();
            mp.release();
            isPlaying=false;
        } catch (Exception io){ io.printStackTrace(); }
        return null; }}

/// PAUSE PLAYING SONG//
public static class pause extends AsyncTask {
    @Override
    protected Object doInBackground(Object[] objects) {
        try {
            mp.pause(); }
        catch (Exception io){ io.printStackTrace();   }
        return null; }}

public static class start extends AsyncTask {
    @Override
    protected Object doInBackground(Object[] objects) {
        try {
            mp.start(); }
        catch (Exception io){ io.printStackTrace();   }
        return null; }}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    // throw new UnsupportedOperationException("Not yet implemented");
    return null;
}

Upvotes: 1

Related Questions