Android: остановка активности виджета MediaPlayer во время телефонных звонков

Я использовал решения, представленные в этом ответе Остановка и запуск музыки при входящих вызовах но не могу понять, как реализовать это в моем коде. Это то, что я сделал -

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

person AhulR    schedule 20.07.2013    source источник


Ответы (1)


Вот что я понял:

  • Вы пишете виджет приложения для медиаплеера
  • пользователь нажимает кнопку, чтобы начать воспроизведение (что-то)
  • Входящий звонок => звук останавливается

Вот как бы я продолжил:

  1. Вы привязываете службу (android.app.Service), которая воспроизводит вашу звуковую дорожку, к кнопке на вашем виджете.
  2. Служба запускает реальную задачу MediaPlayer.
  3. При поступлении вызова задача приостанавливает работу MediaPlayer.
  4. Когда вызов завершается, задача может (в зависимости от того, что вы хотите) возобновить работу MediaPlayer.

1) Внутри KameWidget.onUpdate(..), что-то вроде:

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) Сервис:

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) Аудио Задача:

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

Я действительно не знаю, как работает телефония. Вы должны будете понять это сами.

Это моя идея. Я надеюсь, что это помогает.

person Carl K.    schedule 20.07.2013
comment
Спасибо за вашу помощь. К сожалению, я не смог реализовать это в своем коде. Класс TelephonyManager показывает ошибки, а также я не знаю, что делать с OnRecieve() и как использовать OnStartCommand(). :( - person AhulR; 30.07.2013
comment
afaik, вам не нужно onReceive(). В прослушивателе состояния телефона вы просто вызовете audioTask.pause() или audioTask.resume(). - person Carl K.; 09.08.2013