Я установив OnClickListener в cardviews на моем ViewHolder:Как вызвать служебное вложение из MainActivity через фрагмент?
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
view.setBackgroundResource(mBackground);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mBoundString = mValues.get(position);
holder.mTextView.setText(mValues.get(position));
holder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MainActivity mActivity= new MainActivity();
mActivity.onClickPlayButton(v);
}
});
Glide.with(holder.mImageView.getContext())
.load(Stations.getRandomCheeseDrawable())
.fitCenter()
.into(holder.mImageView);
}
Это мой onClickPlayButton на MainActivity:
public void onClickPlayButton(View view) {
radioServiceBinder.play();
}
Это код обслуживания:
public class RadioService extends Service implements OnErrorListener, OnCompletionListener, OnPreparedListener, OnInfoListener {
private MediaPlayer mediaPlayer;
private List<String> radioStreamURL = new ArrayList<>();
private int radioStreamingIndex = 0;
public static final String MODE_CREATED = "CREATED";
public static final String MODE_DESTROYED = "DESTROYED";
public static final String MODE_PREPARED = "PREPARED";
public static final String MODE_STARTED = "STARTED";
public static final String MODE_PLAYING = "PLAYING";
public static final String MODE_PAUSED = "PAUSED";
public static final String MODE_STOPPED = "STOPPED";
public static final String MODE_COMPLETED = "COMPLETED";
public static final String MODE_ERROR = "ERROR";
public static final String MODE_BUFFERING_START = "BUFFERING_START";
public static final String MODE_BUFFERING_END = "BUFFERING_END";
private boolean isPrepared = false;
private final IBinder binder = new RadioBinder();
@Override
public void onCreate() {
// add stations to the list
radioStreamURL.add("http://momori.animenfo.com:8000/");
radioStreamURL.add("http://momori.animenfo.com:8000/");
radioStreamURL.add("http://momori.animenfo.com:8000/");
/* Create MediaPlayer when it starts for first time */
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnInfoListener(this);
sendBroadcast(new Intent(MODE_CREATED));
}
@Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
mediaPlayer.reset();
isPrepared = false;
sendBroadcast(new Intent(MODE_DESTROYED));
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
sendBroadcast(new Intent(MODE_STARTED));
/* Starts playback at first time or resumes if it is restarted */
if(mediaPlayer.isPlaying())
sendBroadcast(new Intent(MODE_PLAYING));
else if(isPrepared) {
sendBroadcast(new Intent(MODE_PAUSED));
}
return Service.START_STICKY;
}
@Override
public void onPrepared(MediaPlayer _mediaPlayer) {
/* If radio is prepared then start playback */
sendBroadcast(new Intent(MODE_PREPARED));
isPrepared = true;
play();
}
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
/* When no stream found then complete the playback */
mediaPlayer.stop();
mediaPlayer.reset();
isPrepared = false;
sendBroadcast(new Intent(MODE_COMPLETED));
}
public void prepare() {
/* Prepare Async Task - starts buffering */
try {
mediaPlayer.setDataSource(radioStreamURL.get(radioStreamingIndex));
mediaPlayer.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void nextStation(){
changeStation(radioStreamingIndex+1);
}
public void prevStation(){
changeStation(radioStreamingIndex-1);
}
public void changeStation(int stationIndex){
if(stationIndex > 0 && stationIndex < radioStreamURL.size()){
radioStreamingIndex = stationIndex;
stop();
play();
}
}
public void play() {
if(isPrepared) {
mediaPlayer.start();
System.out.println("RadioService: play");
//sendBroadcast(new Intent(MODE_PLAYING));
}
else
{
//sendBroadcast(new Intent(MODE_STARTED));
prepare();
}
}
public void pause() {
mediaPlayer.pause();
System.out.println("RadioService: pause");
sendBroadcast(new Intent(MODE_PAUSED));
}
public void stop() {
mediaPlayer.stop();
mediaPlayer.reset();
isPrepared = false;
System.out.println("RadioService: stop");
sendBroadcast(new Intent(MODE_STOPPED));
}
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
/* Check when buffering is started or ended */
if(what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {
sendBroadcast(new Intent(MODE_BUFFERING_START));
}
else if(what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
sendBroadcast(new Intent(MODE_BUFFERING_END));
}
return false;
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
sendBroadcast(new Intent(MODE_ERROR));
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Log.v("ERROR","MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + extra);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.v("ERROR","MEDIA ERROR SERVER DIED " + extra);
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.v("ERROR","MEDIA ERROR UNKNOWN " + extra);
break;
}
return false;
}
@Override
public IBinder onBind(Intent intent) {
return binder;
}
/* Allowing activity to access all methods of RadioService */
public class RadioBinder extends Binder {
RadioService getService() {
// Return this instance of RadioService so clients can call public methods
return RadioService.this;
}
}
}
Когда я щелкните по нему, я получил эту ошибку в logcat: java.lang.NullPointerException: попытка вызвать виртуальный метод ... RadioService.play() 'в ссылке на нулевой объект.
Я не думаю, что в методе play() есть что-то неправильное.
Я хочу, чтобы OnClickListener или onClickPlayButton вызывали метод play() из моего класса сервиса, привязанного к моей MainActivity. Как я могу это достичь? Я застрял в этой проблеме.
я принимаю ваш 'ViewHolder' принадлежит адаптеру, который принадлежит вашему «Фрагменту», который находится в вашей «MainActivity»? Передайте фрагменты 'Context' в ваш' ViewHolder' и вызовите там '((MainActivity) context.getActivity()). OnClickPlayButton (v)'. – kphil
Да. Я попробую это и опубликую результаты здесь. Спасибо за помощь. –
@kphil, метод 'getActivity()' в классе 'Context' отсутствует. Ваш код должен быть без него: '((MainActivity) контекст) .onClickPlayButton (v);' Смотрите мой обновленный ответ; – mohax