在 Android 中实现音频应用通知

Implementing audio app notification in Android

应用程序的目的是使用 exoplayer 通过 url 流媒体播放一些广播电台。遇到的问题是,当应用程序 运行 并且通知开始时,有 2 种不同的流播放,一种是通过我从收音机 UI 按下按钮,另一种是通过通知播放。

我的问题是,当我按下 UI 上的按钮时,它也会更改通知播放器上的流。

P.S。我已经尝试导入一个播放器,但是 mainactivity.java 通过将其称为静态来证明这一点,但这会导致内存泄漏并且流在前台服务中停止。

我使用了这里的 notificationPlayerManager(exoplayer):https://www.youtube.com/watch?v=svdq1BWl4r8

主要Activityclass:

包------------等

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.ui.PlayerNotificationManager;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import org.atsevdev.radioromania.MyServices.*;
import android.view.View;


public class MainActivity extends AppCompatActivity {


    public static final String FOREGROUND_SERVICE = "android.permission.FOREGROUND_SERVICE";

    //initialising variables
    public static final String DigiFm = "http://edge76.rdsnet.ro:84/digifm/digifm.mp3";
    public static final String radio_zu = "http://live.romanticfm.ro:9123/radiozu.mp3";
    public static final String Radio_popular = "http://mp3.radiopopular.ro:7777/;stream.mp3";
    public static final String Eur_fm = "http://89.37.58.103:8000/europafm_mp3_64k";
    public static final String radio_rom_acc = "http://stream2.srr.ro:8000/;stream/1";
    public static final String PROFMurl = "http://edge126.rdsnet.ro:84/profm/profm.mp3";
    public static final String radiobuchuresti = "http://89.238.227.6:8032/\n" +
            "Title1=Bucuresti FM\n" +
            "Length1=-1\n" +
            "Version=2";
    public static final String impactfm = "http://89.39.189.159:8000/";
    private PlayerView playerView;
    public SimpleExoPlayer player;
    public boolean clickCheck = false;






    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        playerView=findViewById(R.id.playview);//playview id xml into private variable
        Intent playService =  new Intent(this, MyServices.class);
        Util.startForegroundService(this, playService);




    }
    @Override
    protected void onStart(){
        super.onStart();

        player = ExoPlayerFactory.newSimpleInstance(this,
                new DefaultTrackSelector());//instantiating new player instances
        playerView.setPlayer(player);//xml player to view

        //creating datasource
        DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this,
                Util.getUserAgent(this, "RadioRomania"));



        //extracting stream url
        final ExtractorMediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse(PROFMurl));
        final ExtractorMediaSource mediaSource0 = new ExtractorMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse(radiobuchuresti));
        final ExtractorMediaSource mediaSource1 = new ExtractorMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse(impactfm));
        final ExtractorMediaSource mediaSource2 = new ExtractorMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse(radio_rom_acc));
        final ExtractorMediaSource mediaSource3 = new ExtractorMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse(Eur_fm));
        final ExtractorMediaSource mediaSource4 = new ExtractorMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse(Radio_popular));
        final ExtractorMediaSource mediaSource5 = new ExtractorMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse(radio_zu));
        final ExtractorMediaSource mediaSource6 = new ExtractorMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse(DigiFm));




        //start video player
        FloatingActionButton stop = (FloatingActionButton) findViewById(R.id.stopPLAY);
        FloatingActionButton bt = (FloatingActionButton) findViewById(R.id.profm);
        FloatingActionButton bt0 = (FloatingActionButton) findViewById(R.id.rad_buc);//buchuresti
        FloatingActionButton bt1 = (FloatingActionButton) findViewById(R.id.impactfm);//impact
        FloatingActionButton bt2 = (FloatingActionButton) findViewById(R.id.radio_ro_acc);
        FloatingActionButton bt3 = (FloatingActionButton) findViewById(R.id.europafm);
        FloatingActionButton bt4 = (FloatingActionButton) findViewById(R.id.radpopular);
        FloatingActionButton bt5 = (FloatingActionButton) findViewById(R.id.Radiozuu);
        FloatingActionButton bt6 = (FloatingActionButton) findViewById(R.id.DigiFm);


        //using onClick methods to choose radio station
        bt.setOnClickListener(new View.OnClickListener() {
           @Override
            public void onClick(View v) { //ini profm
               clickCheck = true;
               player.prepare(mediaSource);
               player.setPlayWhenReady(clickCheck);


               }
        });
        bt0.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) { //ini impact
                clickCheck = true;
                player.prepare(mediaSource0);
                player.setPlayWhenReady(clickCheck);




            }
        });
        bt1.setOnClickListener(new View.OnClickListener() {
            @Override
                public void onClick(View v){ //ini radio ro acc
                    clickCheck = true;
                    player.prepare(mediaSource1);
                    player.setPlayWhenReady(clickCheck);

                }
        });
        bt2.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){ //ini radio ro acc
                clickCheck = true;
                player.prepare(mediaSource2);
                player.setPlayWhenReady(clickCheck);

            }
        });
        bt3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) { //ini profm
                clickCheck = true;
                player.prepare(mediaSource3);
                player.setPlayWhenReady(clickCheck);

            }
        });
        bt4.setOnClickListener(new View.OnClickListener() {//ini radio popular
            @Override
            public void onClick(View v) {
                player.prepare(mediaSource4);


            }
        });
        bt5.setOnClickListener(new View.OnClickListener() {//ini radio popular
            @Override
            public void onClick(View v) {
                clickCheck = true;
                player.prepare(mediaSource5);
                player.setPlayWhenReady(clickCheck);


            }
        });
        bt6.setOnClickListener(new View.OnClickListener() {//ini radio popular
            @Override
            public void onClick(View v) {

            }
        });
        //stop stream here
        stop.setOnClickListener(new View.OnClickListener() {//ini radio popular
            @Override
            public void onClick(View v) {
                player.setPlayWhenReady(false);

            }
        });


    }

    @Override
    protected void onStop(){
        super.onStop();


        playerView.setPlayer(null);
        player.release();
        player = null;
    }

服务class:

包---等

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.IBinder;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.ui.PlayerNotificationManager;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import org.atsevdev.radioromania.MainActivity.*;



public class MyServices extends Service {


    private SimpleExoPlayer player1;
    private PlayerNotificationManager playerNotificationManager;
    public boolean clickCheck = false;


    //importing urls from main
    public String  DigiFm = MainActivity.DigiFm;
    public String radioZU = MainActivity.radio_zu;
    public String europaFM = MainActivity.Eur_fm;
    public String radio_acc_ro = MainActivity.radio_rom_acc;
    public String radio_bucuresti = MainActivity.radiobuchuresti;
    public String impactFM = MainActivity.impactfm;
    public String radiopopular = MainActivity.Radio_popular;
    public String PROfm = MainActivity.PROFMurl;



    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    public void onCreate(){
        super.onCreate();
        final Context context = this;

        player1 = ExoPlayerFactory.newSimpleInstance(context, new DefaultTrackSelector());
        DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(
                context, Util.getUserAgent(context, "RadioRomania"));


        //////////////////////Media Sources/////////////////////////////////
       final  MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory).
                createMediaSource(Uri.parse(DigiFm));
      final  MediaSource mediaSource0 = new ExtractorMediaSource.Factory(dataSourceFactory).
                createMediaSource(Uri.parse(radioZU));
       final MediaSource mediaSource1 = new ExtractorMediaSource.Factory(dataSourceFactory).
                createMediaSource(Uri.parse(radiopopular));
      final  MediaSource mediaSource2 = new ExtractorMediaSource.Factory(dataSourceFactory).
                createMediaSource(Uri.parse(europaFM));
      final  MediaSource mediaSource3 = new ExtractorMediaSource.Factory(dataSourceFactory).
                createMediaSource(Uri.parse(radio_acc_ro));
      final  MediaSource mediaSource4 = new ExtractorMediaSource.Factory(dataSourceFactory).
                createMediaSource(Uri.parse(PROfm));
      final  MediaSource mediaSource5 = new ExtractorMediaSource.Factory(dataSourceFactory).
                createMediaSource(Uri.parse(radio_bucuresti));
      final  MediaSource mediaSource6 = new ExtractorMediaSource.Factory(dataSourceFactory).
                createMediaSource(Uri.parse(impactFM));
        player1.prepare(mediaSource);
        player1.prepare(mediaSource0);
        player1.prepare(mediaSource1);
        player1.prepare(mediaSource2);
        player1.prepare(mediaSource3);
        player1.prepare(mediaSource4);
        player1.prepare(mediaSource5);
        player1.prepare(mediaSource6);
        player1.setPlayWhenReady(clickCheck);


        ////////////////////////////////////////////////////////////////////////////////
        playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel(
                context, "Channel ID", R.string.app_name, 0,
                new PlayerNotificationManager.MediaDescriptionAdapter() {
                    @Override
                    public String getCurrentContentTitle(Player player) {
                        return null;
                    }

                    @Nullable
                    @Override
                    public PendingIntent createCurrentContentIntent(Player player) {
                        Intent intent = new Intent(context, MainActivity.class);
                        return PendingIntent.getActivity(context, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
                    }

                    @Nullable
                    @Override
                    public String getCurrentContentText(Player player) {
                        return null;
                    }

                    @Nullable
                    @Override
                    public Bitmap getCurrentLargeIcon(Player player, PlayerNotificationManager.BitmapCallback callback) {
                        return null;
                    }
                }
        );
    playerNotificationManager.setNotificationListener(new PlayerNotificationManager.NotificationListener() {
        @Override
        public void onNotificationStarted(int notificationId, Notification notification) {
            startForeground(0, notification);
            clickCheck = true;

        }

    @Override
    public void onNotificationCancelled(int notificationId) {
    stopSelf();
    clickCheck = false;
    }
});
playerNotificationManager.setPlayer(player1);
}
public int onStardCommand(Intent intent, int flats, int stardId){

    return START_STICKY;
}


@Override
public void onDestroy(){
    playerNotificationManager.setPlayer(null);
    player1.release();
    player1 = null;
}
}

经过一番研究,我找到了答案。对于其他希望将主要 activity 绑定到服务的人。

在那个过程中我使用了这个方法从服务绑定播放器:

public SimpleExoPlayer getPlayer1()
{
    return player1;
}

然后在你的 main 中调用它:

player = myServices.player1;