在 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;
应用程序的目的是使用 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;