I have a service to play sound.
I'm trying to stop the sound when I receive a call but I can't.
I want to stop the sound when I receive a call and replay when it ends.
Someone know what I did wrong?
This is my Service code:
public class MyMediaPlayer extends Service implements OnInfoListener, OnPreparedListener, OnErrorListener, AudioManager.OnAudioFocusChangeListener {
public static MediaPlayer mMediaPlayer;
public static String START_PLAY = "START_PLAY";
IBinder mBinder = new LocalBinder();
MusicServicePhoneStateListener mPhoneListener;
public static final String BROADCAST_ACTION = AC.PACKAGE_NAME+".ACTION_HEADSET_PLUG";
Intent intent;
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
/*public MyMediaPlayer getServerInstance() {
return MyMediaPlayer.this;
}*/
}
#Override
public void onCreate()
{
super.onCreate();
mPhoneListener = new MusicServicePhoneStateListener();
((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE)).listen(mPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
intent = new Intent(BROADCAST_ACTION);
}//onCreate
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getBooleanExtra(START_PLAY, false)) {
initializePlayer();
}
return START_STICKY;
}
public void initializePlayer() {
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mMediaPlayer.setDataSource("rtsp://example.com/file.stream");
}
catch (Exception e) {
Log.e("MyMediaPlayer", "Error");
}
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnInfoListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnErrorListener(this);
mMediaPlayer.prepareAsync();
}
#Override
public void onPrepared(MediaPlayer player) {
startMediaPlayer();
}
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
case AudioManager.AUDIOFOCUS_GAIN:
// resume playback
if (mMediaPlayer == null) initializePlayer();
else if (!mMediaPlayer.isPlaying()) mMediaPlayer.start();
mMediaPlayer.setVolume(1.0f, 1.0f);
break;
case AudioManager.AUDIOFOCUS_LOSS:
// Lost focus for an unbounded amount of time: stop playback and release media player
stopMediaPlayer();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// Lost focus for a short time, but we have to stop
// playback. We don't release the media player because playback
// is likely to resume
pauseMediaPlayer();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// Lost focus for a short time, but it's ok to keep playing
// at an attenuated level
if (mMediaPlayer.isPlaying()) mMediaPlayer.setVolume(0.1f, 0.1f);
break;
}
}
#Override
public void onDestroy(){
stopMediaPlayer();
((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE)).listen(mPhoneListener, PhoneStateListener.LISTEN_NONE);
}
#Override
public boolean onError(MediaPlayer player, int what, int extra) {
if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED || what == MediaPlayer.MEDIA_ERROR_UNKNOWN || extra == MediaPlayer.MEDIA_ERROR_TIMED_OUT || extra == MediaPlayer.MEDIA_ERROR_IO) {
Log.e("MediaPlayer","Error");
}
stopMediaPlayer();
return true;
}
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
return false;
}
public void startMediaPlayer() {
mMediaPlayer.start();
}
public void pauseMediaPlayer() {
if(mMediaPlayer.isPlaying()) mMediaPlayer.pause();
}
public void stopMediaPlayer() {
if(mMediaPlayer.isPlaying()) mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
Log.d("MediaPlayer","stop()");
}
private class MusicServicePhoneStateListener extends PhoneStateListener {
private boolean mResumeAfterCall = false;
#Override
public void onCallStateChanged(int state, String incoming_number) {
switch (state) {
case TelephonyManager.CALL_STATE_OFFHOOK:
case TelephonyManager.CALL_STATE_RINGING:
mResumeAfterCall = mMediaPlayer.isPlaying();
stopMediaPlayer();
break;
case TelephonyManager.CALL_STATE_IDLE:
if (mMediaPlayer == null && mResumeAfterCall) initializePlayer();
break;
default:
break;
}
}
}
}
I do not understand why pause() and stop() are not working :(
I have put stopMediaPlayer(); on TelephonyManager.CALL_STATE_OFFHOOK || TelephonyManager.CALL_STATE_RINGING and initializePlayer(); on TelephonyManager.CALL_STATE_IDLE an this work, but I do not know why not work with stop() or pause().
You can try a some hack.
Remember current play progress with getCurrentPosition()
Execute release()
When you need to resume playing you need open stream again and rewing to last remember position by seekTo(int ms)
64 state explanation :
It's the 'stopped' state. When in that state, you need to call
prepare() again before starting playback.
Related
Heres my problem:
I am implementing a music player (PlayerActivity.java / xml) which is bound to a service (PlayerService.java) that basically is just an instance of a musicplayer so that it can run in the background. When lefting the app or changing the activity and the restarting the activity i want to bind to the still running service without stopping or restarting it. I have tried using only bindService() but that made me face the problem: somehow without calling startService() before bindService the Service doesn't get initialized or it takes a few milliseconds so that the functions only get null when accessing service functions.
Here is my service class:
public class playerService extends Service {
public boolean running = false;
public MediaPlayer mediaPlayer;
public boolean isPrepared = false;
private String url;
public class serviceBinder extends Binder {
public playerService getService() {
return playerService.this;
}
}
public boolean isRunning(){
return running;
}
private IBinder mBinder = new serviceBinder();
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.w("Service", "started");
mediaPlayer = new MediaPlayer();
running = true;
Log.e("!!!", running + "");
return START_STICKY;
}
public void pause() {
mediaPlayer.pause();
}
public void resume() {
mediaPlayer.start();
}
public void setupPlayer() {
try {
if (mediaPlayer != null) {
mediaPlayer.reset();
}
} catch (Exception e) {
Log.e("MediaPlayer", e.getMessage());
}
try {
mediaPlayer.setDataSource(url);
mediaPlayer.prepareAsync();
} catch (Exception e) {
Log.e("MediaPlayerToo", e.getMessage());
}
}
public void reset(){
mediaPlayer.reset();
}
public void updateUrl(String url){
this.url = url;
}
public void start(){
mediaPlayer.start();
}
public int getCurrentPosition(){
return mediaPlayer.getCurrentPosition();
}
public int getDuration(){
return mediaPlayer.getDuration();
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
mediaPlayer.reset();
}
}
I experimented with waiting until the Service has started with a boolean. But when i add any kind of code
after
mService = binder.getService();
startService(intent);
it seems to not get created at all.
Here is also my onServiceConnected class
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
playerService.serviceBinder binder = (playerService.serviceBinder) service;
Intent intent = new Intent(getApplicationContext(), playerService.class);
mService = binder.getService();
startService(intent);
//... <- adding code here will result in the Service not starting?!!
}
I know that my problem is quite confusing, but this was the best i could come up explaining it. I would be really glad if you had any idea because this problem stops me from deployment. Thank you very much!!
I want to convert Java code to C# but facing problem to do so
public class MyService extends Service {
static final String CONNECTIVITY_CHANGE_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
NotificationManager manager ;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (CONNECTIVITY_CHANGE_ACTION.equals(action)) {
//check internet connection
if (!ConnectionHelper.isConnectedOrConnecting(context)) {
if (context != null) {
boolean show = false;
if (ConnectionHelper.lastNoConnectionTs == -1) {//first time
show = true;
ConnectionHelper.lastNoConnectionTs = System.currentTimeMillis();
} else {
if (System.currentTimeMillis() - ConnectionHelper.lastNoConnectionTs > 1000) {
show = true;
ConnectionHelper.lastNoConnectionTs = System.currentTimeMillis();
}
}
if (show && ConnectionHelper.isOnline) {
ConnectionHelper.isOnline = false;
Log.i("NETWORK123","Connection lost");
//manager.cancelAll();
}
}
} else {
Log.i("NETWORK123","Connected");
showNotifications("APP" , "It is working");
// Perform your actions here
ConnectionHelper.isOnline = true;
}
}
}
};
registerReceiver(receiver,filter);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
This part I am not getting which coming in middle of code
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent)
{
}
};
You probably want to see a more comprehensive answer for this to see how the given suggestions all fits together:
public class MyService : Service
{
internal const string CONNECTIVITY_CHANGE_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
internal NotificationManager manager;
public override IBinder onBind(Intent intent)
{
return null;
}
public override int onStartCommand(Intent intent, int flags, int startId)
{
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
BroadcastReceiver receiver = new BroadcastReceiverAnonymousInnerClass();
registerReceiver(receiver,filter);
return START_STICKY;
}
private class BroadcastReceiverAnonymousInnerClass : BroadcastReceiver
{
public override void onReceive(Context context, Intent intent)
{
string action = intent.Action;
if (CONNECTIVITY_CHANGE_ACTION.Equals(action))
{
//check internet connection
if (!ConnectionHelper.isConnectedOrConnecting(context))
{
if (context != null)
{
bool show = false;
if (ConnectionHelper.lastNoConnectionTs == -1)
{ //first time
show = true;
ConnectionHelper.lastNoConnectionTs = DateTimeHelper.CurrentUnixTimeMillis();
}
else
{
if (DateTimeHelper.CurrentUnixTimeMillis() - ConnectionHelper.lastNoConnectionTs > 1000)
{
show = true;
ConnectionHelper.lastNoConnectionTs = DateTimeHelper.CurrentUnixTimeMillis();
}
}
if (show && ConnectionHelper.isOnline)
{
ConnectionHelper.isOnline = false;
Log.i("NETWORK123","Connection lost");
//manager.cancelAll();
}
}
}
else
{
Log.i("NETWORK123","Connected");
showNotifications("APP", "It is working");
// Perform your actions here
ConnectionHelper.isOnline = true;
}
}
}
}
public override void onDestroy()
{
base.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
internal static class DateTimeHelper
{
private static readonly System.DateTime Jan1st1970 = new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
public static long CurrentUnixTimeMillis()
{
return (long)(System.DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
}
}
I think you would do something like this
var receiver = new MyReceiver();
public class MyReceiver : BroadcastReceiver
{
public override void onReceive(Context context, Intent intent)
{
}
}
Since C# does not allow anonymous classes you will have to explicitly create it and then pass the data that you need there from this class.
[BroadcastReceiver(Enabled = true, Exported = false)]
public class SampleReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
// Do stuff here.
}
}
Then use it like:
var receiver = new SampleReceiver();
Im creating an app in android studio where I want 10 clips to be played at the same time side by side. Im having some problems with some lags already at three clips and I wounder if Im better off using threads? In that case how?
Any hint would be very much apreciated
Here is my code so far. I know it is not very efficient and I am better off using an array of a player object for example but Im just testing so far:
public class MainActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {
private MediaPlayer mp1, mp2, mp3;
private TextureView tv1, tv2, tv3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = findViewById(R.id.textureView1);
tv2 = findViewById(R.id.textureView2);
tv3 = findViewById(R.id.textureView3);
tv1.setSurfaceTextureListener(this);
tv2.setSurfaceTextureListener(this);
tv3.setSurfaceTextureListener(this);
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
Surface surface = new Surface(surfaceTexture);
mp1 = MediaPlayer.create(this, R.raw.a7);
mp1.setSurface(surface);
// mp1.prepareAsync(); //
mp1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp1) {
mp1.start();
}
});
Surface surface2 = new Surface(surfaceTexture);
mp2 = MediaPlayer.create(this, R.raw.a9);
mp2.setSurface(surface2);
// mp1.prepareAsync(); //
mp2.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp2) {
mp2.start();
}
});
Surface surface3 = new Surface(surfaceTexture);
mp3 = MediaPlayer.create(this, R.raw.a10);
mp3.setSurface(surface3);
// mp1.prepareAsync(); //
mp3.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp3) {
mp3.start();
}
});
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
#Override
protected void onPause() {
if (mp1 != null && mp1.isPlaying()) {
mp1.pause();
}
super.onPause();
}
#Override
protected void onResume() {
if (mp1 != null) {
mp1.start();
}
super.onResume();
}
#Override
protected void onDestroy() {
if (mp1 != null) {
mp1.stop();
mp1.release();
mp1 = null;
}
super.onDestroy();
}
}
You should play media in a different non-ui thread. like this:-
public class MediaService extends Service {
private MediaPlayer mp1, mp2, mp3;
private static final String ACTION_START = TAG + ".ACTION_START";
private IBinder mBinder = new MyBinder();
private MediaPlayer.OnPreparedListener mMediaPrepared = new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
Log.d(TAG, "MediaPlayer.onPrepared");
onCommandPlay(mp);
}
};
#Override
public IBinder onBind(Intent intent) {
Log.v(TAG, "onBind");
return mBinder;
}
#Override
public void onCreate() {
super.onCreate();
m1 = MediaPlayer.create(this, R.raw.a1);
m2 = MediaPlayer.create(this, R.raw.a2);
m3 = MediaPlayer.create(this, R.raw.a9);
}
#Override
public void onDestroy() {
super.onDestroy();
if (m1 != null) m1 .release();
if (m2 != null) m2 .release();
if (m3 != null) m3 .release();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final String action = intent.getAction();
Log.d(TAG, "onStartCommand: " + intent.getAction());
if (ACTION_START.equals(action)) {
onCommandStart();
return START_STICKY;
}
stopSelf();
return Service.START_STICKY_COMPATIBILITY;
}
/**
* Performs actions related to media player when Service onStartCommand method is called
*
*/
private void onCommandStart() {
// Create Notifications with remote views
mNotification = new NotificationCompat.Builder(this).setTicker("Media Service started...")
.setSmallIcon(R.mipmap.ic_launcher)
.setContent(collapsed)
.setAutoCancel(false)
.setOngoing(true)
.build();
startForeground(NOTIFICATION_ID, mNotification);
startPlaying();
}
private void onCommandPlay(MediaPlayer mp) {
try {
mp.start();
} catch (IllegalStateException e) {
Log.e(TAG, "onCommandPlay", e);
}
}
/**
* Start playing the provided media item
*
*/
private void startPlaying() {
mCurrent = item;
try {
mp1.reset();
mp1.setOnPreparedListener(mMediaPrepared);
mp2.reset();
mp2.setOnPreparedListener(mMediaPrepared);
mp3.reset();
mp3.setOnPreparedListener(mMediaPrepared);
AssetFileDescriptor afd1 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a9););
AssetFileDescriptor afd2 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a10););
AssetFileDescriptor afd3 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a8););
mp1.setDataSource(afd1 .getFileDescriptor(), afd1 .getStartOffset(), afd1.getLength());
mp2.setDataSource(afd2 .getFileDescriptor(), afd2 .getStartOffset(), afd2 .getLength());
mp3.setDataSource(afd3 .getFileDescriptor(), afd3 .getStartOffset(), afd3 .getLength());
mp1.prepareAsync();
mp2.prepareAsync();
mp3.prepareAsync();
} catch (IOException e) {
Log.e(TAG, "startPlaying", e);
}
}
public class MyBinder extends Binder {
public MediaService getService() {
return MediaService.this;
}
}
}
then start the service from Activity like this:
Intent intent = new Intent(context, MediaService.class);
intent.setAction(ACTION_START);
startServie(intent);
You should also handle different media playing use-cases. You can refer this link for more.
I'm developing a simple Android game that plays sound in background by service. When game starts, the sound is playing good. But when pressing volume up key or down button, the app exits immediately.
public class PlayAudio extends Service{
private static final String LOGCAT = null;
MediaPlayer objPlayer;
public void onCreate(){
super.onCreate();
Log.d(LOGCAT, "Service Started!");
objPlayer = MediaPlayer.create(this,R.raw.relax);
}
public int onStartCommand(Intent intent, int flags, int startId){
objPlayer.start();
Log.d(LOGCAT, "Media Player started!");
if(objPlayer.isLooping() != true){
Log.d(LOGCAT, "Problem in Playing Audio");
}
return 1;
}
public void onStop(){
objPlayer.stop();
objPlayer.release();
}
public void onPause(){
objPlayer.stop();
objPlayer.release();
}
public void onDestroy(){
objPlayer.stop();
objPlayer.release();
}
#Override
public IBinder onBind(Intent objIndent) {
return null;
}
}
this code to start playing sound
public void playAudio() {
Intent objIntent = new Intent(this, PlayAudio.class);
startService(objIntent);
}
Problem solved. I just missed the condition:
if (keyCode == KeyEvent.KEYCODE_BACK){}
I'm setting an OnClickListener to cardviews on my ViewHolder:
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);
}
This is my onClickPlayButton on MainActivity:
public void onClickPlayButton(View view) {
radioServiceBinder.play();
}
This is the Service code:
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;
}
}
}
When I click it, I got this error on logcat: java.lang.NullPointerException: Attempt to invoke virtual method ....RadioService.play()' on a null object reference.
I don't think there is anything wrong in the play() method.
I want the OnClickListener or the onClickPlayButton to call the play() method from my Service class that is binded to my MainActivity. How can I achieve this?
I'm stuck at this problem.
Yours error here
MainActivity mActivity= new MainActivity();
mActivity.onClickPlayButton(v);
You try to call method of new instance of Activitys class. But you should call method of current, running instance of yours activity. So you must send reference to yours activity to adapter and call yours method on it.
As I understand, you initialize variables and bind yours Service in OnCreate or onResume of yours activity. But this methods not invoked adter you create a new instance of MainActivity class;
UPD_0:
So yours adapters class should be like this:
public class YOURS_ADAPTERS_CLASS_NAME extends RecyclerView.Adapter<YOURS_ADAPTERS_CLASS_NAME.ViewHolder>
{
Context ctx;
public YOURS_ADAPTERS_CLASS_NAME(Context ctx)
{
this.ctx=ctx;
}
///other lines of yours code
So now you have instance of yours running activity inside yours adapters class. You now should cast it to yours activitys class and call yours method this way:
MainActivity mActivity= (MainActivity) ctx;
mActivity.onClickPlayButton(v);
Also, you don't need (as i can see) an argument in method onClickPlayButton()