如何在所有活动和片段中使用 MediaPlayer 的单个实例?

     2023-04-18     220

关键词:

【中文标题】如何在所有活动和片段中使用 MediaPlayer 的单个实例?【英文标题】:How to use single instance of MediaPlayer across all activities and fragments? 【发布时间】:2018-04-10 12:57:51 【问题描述】:

我有几个显示来自 SD 卡的歌曲的活动和片段,当我点击其中任何一个时,它就会播放。问题是我必须在每个活动和片段中创建一个新的媒体播放器实例。因此,如果我在一项活动中播放一首歌曲并在另一项活动中播放另一首歌曲,这两首歌曲将同时播放。我阅读了关于单例类和使媒体播放器静态的信息,但我需要更多信息。下面是我的代码。

public class ArtistSongAlbumSong extends AppCompatActivity 

ArrayList<SongInfoModel> ArtistSongAlbumSongList = new ArrayList<>();

RecyclerView recyclerView_artistalbumsongs;

ArtistSongAlbumSongAdapter artistSongAlbumSongAdapter;

private static MediaPlayer player = new  MediaPlayer();

Context isContext;

private int currentIndex;


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_artistsongallsong);

    recyclerView_artistalbumsongs = findViewById(R.id.recyclerView_artistSongAllSong);

    isContext = ArtistSongAlbumSong.this;

    Long albumid = getIntent().getExtras().getLong("album_id");

    LinearLayoutManager aslinearLayoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerView_artistalbumsongs.setLayoutManager(aslinearLayoutManager);


    Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

    String selection = MediaStore.Audio.Media.IS_MUSIC + "!=0";
    Cursor cursor = getApplicationContext().getContentResolver().query(uri, null, selection, null, null);
    if (cursor != null) 
        if (cursor.moveToFirst()) 
            do 
                String name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
                String nameArtist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
                String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
                Long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
                Long newAlbumId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
                Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
                Uri albumArtUri = ContentUris.withAppendedId(sArtworkUri, albumid);

                if (newAlbumId.equals(albumid)) 

                    SongInfoModel s6 = new SongInfoModel(name, nameArtist, duration, data, albumArtUri);
                    ArtistSongAlbumSongList.add(s6);
                

             while (cursor.moveToNext());
        


        cursor.close();

        Collections.sort(ArtistSongAlbumSongList, new Comparator<SongInfoModel>() 
            @Override
            public int compare(SongInfoModel lhs, SongInfoModel rhs) 
                return lhs.getSongName().compareTo(rhs.getSongName());
            
        );


    





    artistSongAlbumSongAdapter = new ArtistSongAlbumSongAdapter(getApplicationContext(), ArtistSongAlbumSongList);

    artistSongAlbumSongAdapter.onItemClickListener(new ArtistSongAlbumSongAdapter.ArtistSongAlbumSongListener() 
        @Override
        public void onClickListener(SongInfoModel songInfoModel, int position, RelativeLayout relativeLayout, View view) 
            MainActivity.setsongText(songInfoModel);
            MainActivity.ButtonPlay();
            MainActivity.PauseImage();

            changeSelectedSong(position);
            prepareSong(songInfoModel);

        

        @Override
        public void onLongClickListener(SongInfoModel songInfoModel, int position, RelativeLayout relativeLayout, View view) 

        
    );

    recyclerView_artistalbumsongs.setAdapter(artistSongAlbumSongAdapter);


    player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() 
        @Override
        public void onPrepared(MediaPlayer mediaPlayer) 

            togglePlay(mediaPlayer);

        
    );

    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() 
        @Override
        public void onCompletion(MediaPlayer mediaPlayer) 
            onSongCompletion1(mediaPlayer);
        
    );








public void prepareSong(SongInfoModel song) 

    player.reset();


    try 
        player.setDataSource(song.getData());
        player.prepareAsync();
     catch (IOException e) 
        e.printStackTrace();
    




private void togglePlay(MediaPlayer mp) 

    if (mp.isPlaying()) 
        mp.stop();
        mp.reset();

     else 

        mp.start();


        MainActivity.Handler(mp);


    




private void changeSelectedSong(int index)
  //  artistSongAlbumSongAdapter.notifyItemChanged(artistSongAlbumSongAdapter.getSelectedPosition());
    currentIndex = index;
    artistSongAlbumSongAdapter.setSelectedPosition(currentIndex);
  //  artistSongAlbumSongAdapter.notifyItemChanged(currentIndex);






private void onSongCompletion1(MediaPlayer mediaPlayer) 


    if(currentIndex + 1 < ArtistSongAlbumSongList.size())
        SongInfoModel next  = ArtistSongAlbumSongList.get(currentIndex +1);
        changeSelectedSong(currentIndex + 1);
        prepareSong(next);
        MainActivity.setsongText(next);
    else

        SongInfoModel next1  = ArtistSongAlbumSongList.get(0);
        changeSelectedSong(0);
        prepareSong(ArtistSongAlbumSongList.get(0));
        MainActivity.setsongText(next1);
    


单例类:

public class MyMediaPlayer extends MediaPlayer  

private static MyMediaPlayer mpclass ;




private MyMediaPlayer() 



public static MyMediaPlayer getInstance() 
    if (mpclass == null) 
        synchronized (MyMediaPlayer.class) 
            if (mpclass == null) 
                mpclass = new MyMediaPlayer();
            
        
    

    return mpclass;

【问题讨论】:

【参考方案1】:

您需要按照以下步骤操作

1) 创建一个播放音频的服务并在此处创建 Media Player 实例 2)在活动中绑定它(它可以是你的基本活动) 3)在活动中使用服务引用来获取媒体播放器实例并完成。在所有片段的活动中使用此实例

【讨论】:

我不打算使用服务。那不好吗?你能告诉我另一个比服务更简单的解决方案吗? 是的,它也可以在没有服务的情况下完成。如果媒体播放器在您的基本活动中创建实例。您也可以在片段中的所有活动中访问该实例 我为媒体播放器创建了一个单例类。上面贴的代码。但问题是我已经在所有活动和片段中实现了 setOnCompletionListeners() 但只有最新实现的 setOnCompletionListener() 有效。我不知道为什么 在基类中做同样的事情并提供回调(使用覆盖方法)子类。然后你就可以得到你想要的:) 但是如果我在基类中实现 setOnCompletionListeners(),我将如何将 arrayList、对象和所有其他东西传递给它?

如何在不使用片段的情况下访问所有活动中的导航抽屉?

】如何在不使用片段的情况下访问所有活动中的导航抽屉?【英文标题】:Howtoaccessnavigationdrawerinallactivitieswithoutusingfragments?【发布时间】:2014-03-2907:27:47【问题描述】:我想在所有活动中访问导航抽屉。我不想使用片段。相反... 查看详情

如何在活动的 onSaveInstanceState() 之后杀死所有打开的片段

】如何在活动的onSaveInstanceState()之后杀死所有打开的片段【英文标题】:HowtokillallopenfragmentsafteronSaveInstanceState()ofactivity【发布时间】:2021-05-2501:23:42【问题描述】:我在我的应用程序中使用一个活动多片段架构。我知道当系统... 查看详情

返回活动时如何避免创建MediaPlayer的新实例

】返回活动时如何避免创建MediaPlayer的新实例【英文标题】:HowtoavoidcreatinganewinstanceofMediaPlayerwhenreturningtoactivity【发布时间】:2016-07-1410:23:32【问题描述】:我正在使用MediaPlayer,当用户按下返回离开活动时,它会继续在后台播... 查看详情

在android中使用mediaplayer播放音频文件(代码片段)

...加音频文件有多种方法。例如,您可以使用ExoPlayer或MediaPlayer在Android应用程序中播放音频文件。在本文中,您将学习如何在Android中使用MediaPlayer播放音频文件。以下是您将在此博客中学习的内容: 查看详情

如何在片段而不是活动中使用 setContentView

】如何在片段而不是活动中使用setContentView【英文标题】:HowtousesetContentViewinfragmentinsteadofanactivity【发布时间】:2020-07-3021:26:47【问题描述】:亲爱的***ers:)AllAssetsFragment从MainActivity打开。在这个片段中,我无法正确设置setContentVi... 查看详情

如何使用接口在片段和活动之间进行通信?

】如何使用接口在片段和活动之间进行通信?【英文标题】:Howtouseinterfacetocommunicatebetweenfragmentandactivity?【发布时间】:2021-03-1422:57:18【问题描述】:我只是想从我的MainActivity中调用Fragment方法。所以我尝试使用接口。publicinterfa... 查看详情

如何在 Xamarin 中使用 MediaPlayer 获取曲目的持续时间

】如何在Xamarin中使用MediaPlayer获取曲目的持续时间【英文标题】:HowdoIgetdurationoftrackusingMediaPlayerinXamarin【发布时间】:2017-08-1411:07:38【问题描述】:我想使用XamarinC#Android查找音轨的持续时间。我正在使用MediaPlayer播放我的音频... 查看详情

如何在使用片段和计时器的选项卡式活动上更新 UI

】如何在使用片段和计时器的选项卡式活动上更新UI【英文标题】:howtoupdateUIonatabbedactivitywhichusesfragmentsandtimers【发布时间】:2019-08-1815:52:09【问题描述】:我有一个带有3个片段的选项卡式活动。第一个片段允许用户选择一个测... 查看详情

如何在使用 kotlin 从活动中按下后刷新片段

】如何在使用kotlin从活动中按下后刷新片段【英文标题】:Howtorefreshafragmentafteronbackpressedfromactivitywithkotlin【发布时间】:2020-05-1014:11:26【问题描述】:在我的带有Kotlin的android应用程序中,我有一个用户帐户界面,显示他的所有... 查看详情

如何在所有活动中使用Android Studio默认导航抽屉[重复]

】如何在所有活动中使用AndroidStudio默认导航抽屉[重复]【英文标题】:HowtouseAndroidStudiodefaultNavigationDrawerinallActivities[duplicate]【发布时间】:2016-03-1900:10:21【问题描述】:如何在其他Activity中使用Android默认Navigation?我不想使用返... 查看详情

如何使用 Kotlin 在所有活动中播放背景音乐?

】如何使用Kotlin在所有活动中播放背景音乐?【英文标题】:HowtoplaybackgroundmusicthroughallactivitiesusingKotlin?【发布时间】:2019-09-2313:30:10【问题描述】:如何使用Kotlin在所有活动中在后台播放音乐文件?我到处寻找,但我只找到了J... 查看详情

mediaplayer不使用本地文件(代码片段)

...listview事件中,将播放这首歌。我使用这个时出现问题:MediaPlayermp=newMediaPlayer.create(this,myFile);mp.start();这将是第一次工作。当我点击listView上的第二首歌时,第一首歌继续播放。我知道Create()将创建另一个MediaPlayer实例。我已经声... 查看详情

如何在不锁定活动方向的情况下锁定片段方向?

】如何在不锁定活动方向的情况下锁定片段方向?【英文标题】:Howtolockfragmentorientationwithoutlockingactivityorientation?【发布时间】:2013-12-2015:50:51【问题描述】:我有一个特定的用例,我希望将片段锁定为纵向模式,但仍旋转活动... 查看详情

如何在片段中使用与活动中不同的菜单?

】如何在片段中使用与活动中不同的菜单?【英文标题】:Howtousedifferentmenuinfragmentthaninactivity?【发布时间】:2016-11-1315:39:29【问题描述】:我想为我的主要活动创建一个菜单,并为包含在主要活动中的片段提供一个菜单。当片... 查看详情

如何在单个活动中使用片段中的主要活动浮动操作按钮?

】如何在单个活动中使用片段中的主要活动浮动操作按钮?【英文标题】:Howtousemainactvitiyfloatingactionbuttonfromfragmentsinsingleactivity?【发布时间】:2021-12-1518:57:17【问题描述】:我在单个活动中使用带有浮动操作按钮的BottomAppbar。Fa... 查看详情

即使我切换了活动,如何在活动中播放单个音频文件?

...如果我更改Activity,音频文件应该同时播放。我尝试使用MediaPlayer,但是当我切换活动音频停止时对此有什么可能的解决方案。【问题讨论】:【 查看详情

如何使用启动模式和活动别名删除除根活动之外的所有活动?

】如何使用启动模式和活动别名删除除根活动之外的所有活动?【英文标题】:HowtoremoveallActivitiesexceptrootactivitywithlaunchmodeandactivityalias?【发布时间】:2021-05-0301:15:27【问题描述】:我正在研究Android编程中的启动模式意图标志和... 查看详情

选择片段 A 时如何在 ViewPager 上不一起启动所有片段

】选择片段A时如何在ViewPager上不一起启动所有片段【英文标题】:HowtonotstartallfragmentstogetheronViewPagerwhenfragmentAisselected【发布时间】:2018-07-2318:24:44【问题描述】:所以我使用ViewPager让我的应用程序更快,而不是为每个布局使用a... 查看详情