简体   繁体   中英

Android: Stopping MediaPlayer activity of widget during Phone Calls

I have used the solutions provided in this answer Stopping & Starting music on incoming calls but can't figure out how to implement it in my code. This is what I did -

public class KameWidget extends AppWidgetProvider {
public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
MediaPlayer mPlay;
Context mContext;

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
            R.layout.main);

    Intent active = new Intent(context, KameWidget.class);
    active.setAction(ACTION_WIDGET_RECEIVER);
    PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context,
            0, active, 0);
    remoteViews.setOnClickPendingIntent(R.id.IBWidget, actionPendingIntent);
    appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}

@Override
public void onReceive(Context context, Intent intent) {

    final String action = intent.getAction();
    if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
        final int appWidgetId = intent.getExtras().getInt(
                AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);
        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
            this.onDeleted(context, new int[] { appWidgetId });
        }
    } else {
        if (intent.getAction().equals(ACTION_WIDGET_RECEIVER)) {

            mPlay = MediaPlayer.create(context, R.raw.kamehameha);
            mPlay.start();
            PhoneStateListener phoneStateListener = new PhoneStateListener() {
                @Override
                public void onCallStateChanged(int state,
                        String incomingNumber) {
                    if (state == TelephonyManager.CALL_STATE_RINGING
                            || state == TelephonyManager.CALL_STATE_OFFHOOK) {
                        mPlay.stop();
                    }
                    super.onCallStateChanged(state, incomingNumber);
                }
            };
            TelephonyManager mgr = (TelephonyManager) mContext
                    .getSystemService(Context.TELEPHONY_SERVICE);
            if (mgr != null) {
                mgr.listen(phoneStateListener,
                        PhoneStateListener.LISTEN_CALL_STATE);
            }
        } else {
        }
        super.onReceive(context, intent);
    }
  }
}

Here's what I understood:

  • You write a media-player app widget
  • user presses a button to make it start play (something)
  • Call comes in => the sound pauses

Here's how I would go on about it:

  1. You bind a service ( android.app.Service ) that plays your audio track to a button on your widget.
  2. The service starts the actual MediaPlayer task.
  3. When a call comes in, the task pauses the MediaPlayer.
  4. When the call ends, the task may (depends on what you want) resume the MediaPlayer.

1) Inside KameWidget.onUpdate(..), something like:

Intent intentPlay = new Intent(context, YourPlaySoundService.class);
PendingIntent piPlay = PendingIntent.getService(context, 0, intentPlay, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews views = new RemoteViews(context.getPackageName(), layoutId);
views.setOnClickPendingIntent(R.id.play, piPlay);
...

2) The Service:

public class YourPlaySoundService extends Service {
  ...
  public int onStartCommand (Intent intent, int flags, int startId) {
    // Start the Audio Task
    // Instantiate AudioTask
    AudioTask task = new AudioTask();
    // E.g. get your resource ID from the widget:
    Bundle extras = intent.getExtras();
    int resId = extras.getInt(YOUR_RESOURCE_PARAM_KEY);
    task.execute(resId);

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

3) The Audio Task:

public class AudioTask extends AsyncTask<Integer, Void, Void> {
  private MediaPlayer mMediaPlayer;
  // Telephony-Stuff

  public void resume() {
    if(/* check on correct media player state */) {
      mMediaPlayer.start();
    }
  }
  public void pause() {
    if(mMediaPlayer.isPlaying()) {
      mMediaPlayer.pause();
    }
  }
  public void stop() {
    if(mMediaPlayer.isPlaying()) {
      mMediaPlayer.stop();
    }
    mMediaPlayer.release();
    mMediaPlayer = null;
  }

  protected Void doInBackground(Integer ... params) {
    int resId = params[0];
    // get the resources from a context (the service)
    AssetFileDescriptor afd = mResources.openRawResourceFd(resId);
    try {   
      mMediaPlayer.reset();
      mMediaPlayer.setDataSource(
          afd.getFileDescriptor(), 
          afd.getStartOffset(),
          afd.getDeclaredLength()
          );
      mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {
        public void onPrepared(MediaPlayer mp) {
          mp.seekTo(0);
          mp.start();
        }
      });
      mMediaPlayer.prepare();
      afd.close();
    }
    catch (Exception e) {
      Log.e("TAG", e.getMessage(), e);
    }
    return null;
  }

  // Copied from your link: http://stackoverflow.com/a/5610996/747906
  PhoneStateListener phoneStateListener = new PhoneStateListener() {
    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        if (state == TelephonyManager.CALL_STATE_RINGING) {
            mMediaPlayer.pause();
        } else if(state == TelephonyManager.CALL_STATE_IDLE) {
            //Not in call: Play music
        } else if(state == TelephonyManager.CALL_STATE_OFFHOOK) {
            //A call is dialing, active or on hold
        }
        super.onCallStateChanged(state, incomingNumber);
    }
  };
}

I don't really know how the telephony stuff works. You'll have to figure it out yourself.

This is my idea. I hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM