从服务

时间:2018-06-02 16:47:19

标签: java android android-layout service android-seekbar

所以基本上,我有一个列表视图,显示了一个乐队列表。 当我按下列表中的一个波段时,它会通过适配器创建波段配置文件页面。 在这个布局中,我有一个播放按钮,它启动一个MediaPlayer服务并播放一首歌。

到目前为止,非常好。

问题是,我试图从MediaPlayer服务Java文件更新位于band配置文件页面(由上面提到的适配器创建)的seekBar,但是我无法访问它。

我正在尝试使用:

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

但似乎它使用了视图的另一个“实例”,而不是我正在查看的那个。

以下是完整的MusicService Java文件:

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

}

很想得到一些建议。 提前谢谢。

1 个答案:

答案 0 :(得分:1)

Okey首先,我建议您阅读有关Android服务类的更多信息。其次, NOT 在服务中放置像SeekBar或TextView这样的可视组件,因为它没有任何意义。服务只是一个后台任务,不了解UI。由于它在后台执行,你甚至不需要在其中使用AsyncTask,因此在你的服务中删除 ALL AsyncTasks并运行他们的任务,就好像他们不需要在后台执行一样。

所以你要做的就是为UI创建一个Fragment / Activity,然后将你的Fragment / Acitivity与你的服务绑定,以便沟通和更新UI组件。 最简单的方法是使服务成为单身人士,就像在这里完成一样:

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