Как остановить воспроизведение звука при поступлении телефонного звонка в Android

#android #service #android-mediaplayer #android-audiomanager

#Android #Обслуживание #android-медиаплеер #android-audiomanager

Вопрос:

привет, я новичок в Android и создаю простое приложение для онлайн-радио для моей церкви проблема в том, что мне нужно, чтобы служба воспроизведения останавливалась и перезапускалась, когда на телефон поступает звонок, и завершала его. пока я могу остановить службу просто отлично, но когда она снова запускается, просто вылетает, поэтому я не знаю, чтоя делаю неправильно

 import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.res.Resources;
import android.os.IBinder;
import android.os.PowerManager.WakeLock;
import android.support.v4.app.NotificationCompat;
import com.spoledge.aacdecoder.MultiPlayer;


public class RadioService extends Service{


     WakeLock wakelock;
     //TelephonyManager teleManager= null;
     //PhoneStateListener listener;
     NotificationManager mNotificationManager;
     public static MultiPlayer aacPlayer;
     public static String radio;
     private static Boolean isTuning;

    // private TeleListener myListener = null;



     @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
        }


     @Override
     public void onCreate(){
            super.onCreate();
            setTuning(false);

            setRadio(getString(R.string.rhema));
            aacPlayer = new MultiPlayer();





    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId){

        setTuning(true);

                setTuning(true);

            aacPlayer.playAsync(radio);
            //CallReceiver.setTuning(true);

            Resources r= getResources();
            String[] Notify = r.getStringArray(R.array.PlayNotify);
            // prepare intent which is triggered if the
            // notification is selected

            Intent inten = new Intent(this, PlayerActivity.class);
            PendingIntent pIntent = PendingIntent.getActivity(this, 0, inten, 0);

            // build notification
            // the addAction re-use the same intent to keep the example short
            NotificationCompat.Builder n  = new NotificationCompat.Builder(this)
                    .setContentTitle(Notify[0])
                    .setContentText(Notify[1])
                    .setSmallIcon(R.drawable.noti_icon)
                    .setContentIntent(pIntent)
                    .setAutoCancel(true)
                    .setOngoing(true)
                    .setContentIntent(pIntent);

            Notification hola = n.build();
            startForeground(100, hola);

            //startForeground(startId, notification);
        return START_STICKY;
    }

     @Override
        public void onDestroy() {
            // TODO Auto-generated method stub
            pause();


            //CallReceiver.setTuning(false);
            super.onDestroy();

        }
    public static boolean getTuning() {
        return isTuning;
    }
    public void setTuning(boolean Tuning) {
        isTuning = Tuning;
    }
    public void setRadio(String r){
        radio = r;
    }

    public void PlayNotify(){
        Resources r= getResources();
        String[] Notify = r.getStringArray(R.array.PlayNotify);
        // prepare intent which is triggered if the
        // notification is selected

        Intent intent = new Intent(this, RadioService.class);
        PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);

        // build notification
        // the addAction re-use the same intent to keep the example short
        NotificationCompat.Builder n  = new NotificationCompat.Builder(this)
                .setContentTitle(Notify[0])
                .setContentText(Notify[1])
                .setSmallIcon(R.drawable.noti_icon)
                .setContentIntent(pIntent)
                .setAutoCancel(true);

        n.setOngoing(true);   
        n.setContentIntent(pIntent);
        //NotificationManager mNotificationManager =(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

            // mId allows you to update the notification later on.
            mNotificationManager.notify(100, n.build()); 
    }

    public static void play(){
        aacPlayer.playAsync(radio);

    }
    public static void pause(){
        aacPlayer.stop();

    }

}
  

и это трансляция

     import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

public class CallReceiver extends BroadcastReceiver{
    TelephonyManager telManager;
    Context context;
    public static boolean Tuning = false;
    PlayerActivity mainActivity;
    NotificationManager mNotificationManager;

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


            mainActivity=new PlayerActivity();


    this.context=context;

    telManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    telManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);

}

private final PhoneStateListener phoneListener = new PhoneStateListener() {

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        try {
            switch (state) {
            case TelephonyManager.CALL_STATE_RINGING: {
                //PAUSE
                if(Tuning){

                    context.stopService(new Intent(context,RadioService.class));
                    }

            break;
            }
            case TelephonyManager.CALL_STATE_OFFHOOK: {
                if(Tuning){

                    context.stopService(new Intent(context,RadioService.class));
                }

            break;
            }
            case TelephonyManager.CALL_STATE_IDLE: {
                //PLAY
                if(Tuning){

                    showNotification(context);
                    context.stopService(new Intent(context,RadioService.class));}
            break;
            }
            default: { }
            }
            } catch (Exception ex) {

            }
        }

    };

    public static void setTuning(boolean r){

        Tuning = r;
    }
    private void showNotification(Context context) {
        PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
                new Intent(context, PlayerActivity.class), 0);

        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(context)
                .setSmallIcon(R.drawable.noti_icon)
                .setContentTitle("Rhema Stereo")
                .setContentText("Vuelve a Sintonizarnos.");
        mBuilder.setContentIntent(contentIntent);
        mBuilder.setDefaults(Notification.DEFAULT_SOUND);
        mBuilder.setAutoCancel(true);
        NotificationManager mNotificationManager =
            (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(1, mBuilder.build());}

 }
  

проблема в том, что из действий я могу запускать и останавливать службу просто отлично, но здесь я могу только остановить ее. Итак, на данный момент я использую уведомление, чтобы вернуться к действию и перезапустить сервис

Комментарии:

1. я думаю, вам нужно добавить код для запуска сервиса в TelephonyManager.CALL_STATE_IDLE случай

Ответ №1:

Если позволите, я бы предложил другой подход к этой проблеме. Вы заявляете, что:

мне нужно, чтобы служба воспроизведения останавливалась и перезапускалась, когда на телефон поступает вызов

Однако проблема более сложная. Вы также должны остановить воспроизведение, например, при поступлении уведомления или при запуске пользователем другого музыкального проигрывателя. Вместо того, чтобы отслеживать все эти возможности независимо, Android предоставляет встроенную поддержку этой концепции — она называется audio focus. В широком смысле это означает, что только одно приложение может фокусироваться на звуке в один момент времени, и вы должны отказаться, если оно попросит.

Такое поведение может быть получено с помощью OnAudioFocusChangeListener .

В принципе, вы должны:

  • Перед началом воспроизведения запросите фокусировку звука.
  • Начинайте воспроизведение только в том случае, если вы его эффективно получили.
  • Отключите фокус при остановке воспроизведения.
  • Обработайте потерю фокуса звука (либо уменьшив громкость, либо полностью остановив воспроизведение).

Пожалуйста, ознакомьтесь со статьей «Управление аудиофокусом» в документации Android.

Комментарии:

1. Спасибо! Это было именно то, что мне было нужно, оно работает безупречно

2. @user3739754 Я рад! Не забудьте принять ответ, если он показался вам полезным 🙂

Ответ №2:

вам необходимо добавить этот фрагмент в ваше текущее действие

 IntentFilter receiverFilter = new IntentFilter(
        Intent.ACTION_HEADSET_PLUG);
BootBroadcast receiver = new BootBroadcast();
registerReceiver(receiver, receiverFilter);
  

затем то же самое нужно зарегистрировать в приемнике manifest.xml

например:

 <receiver
            android:name="YOUR_ACTION_STRING.BootCompletedReceiver"
            android:enabled="true"
            android:exported="false" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
  

Также добавьте этот флаг в класс BootBroadcast

 newIntent .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);