【问题标题】:Android music player - One PlayerActivity at a timeAndroid 音乐播放器 - 一次一个 PlayerActivity
【发布时间】:2017-03-16 15:55:29
【问题描述】:

我正在编写一个音乐播放器,我有 2 个活动:

  1. 第一个(MainActivity)包含歌曲的 ListView,我设置了一个 OnItemClickListener(在其 onCreate() 方法中),它打开一个名为 PlayerActivity 的新活动,传递已被点击的项目的位置:

    public class MainActivity extends AppCompatActivity {
        Intent intent;
        ArrayList<String> artistsTitles;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            intent=new Intent(getApplicationContext(), PlayerActivity.class);
            artistsTitles=getArtistTitle();
            ListView mainList=(ListView) findViewById(R.id.mainList);
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, artistsTitles);
            mainList.setAdapter(adapter);
            mainList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    intent.putExtra("currentSong", position);
                    startActivity(intent);
                }
            });
        }
    
        private ArrayList<String> getArtistTitle() {
            ContentResolver musicResolve = getContentResolver();
            String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
            String[] projection = { MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.TITLE};
            Uri uri=android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            Cursor cursor = musicResolve.query(uri, projection, selection, null, null);
    
            ArrayList<String> arrayList=new ArrayList<String>();
            while(cursor.moveToNext())
                arrayList.add(cursor.getString(0)+" - "+cursor.getString(1));
    
            return arrayList;
        }
    }
    
  2. 第二个(PlayerActivity)有一个歌曲的字符串路径的ArrayList,并使用MediaPlayer播放具有项目位置的歌曲并使用它访问ArrayList:

    public class PlayerActivity extends AppCompatActivity {
        ArrayList<String> songs;
        MediaPlayer mediaPlayer;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_player);
            songs=new ArrayList<String>();
            songs=getSongs();
            String songPath=songs.get(intent.getIntExtra("songID", 0));
            mediaPlayer=MediaPlayer.create(getApplicationContext(), Uri.parse(songPath));
            try {
                mediaPlayer.reset();
                mediaPlayer.setDataSource(getApplicationContext(), Uri.parse(songPath));
                mediaPlayer.prepare();
                mediaPlayer.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        private ArrayList<String> getSongs() {
            ContentResolver musicResolve = getContentResolver();
    
            String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
            String[] projection = {MediaStore.Audio.Media.DATA};
            Uri uri=android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            Cursor cursor = musicResolve.query(uri, projection, selection, null, null);
    
            ArrayList<String> s = new ArrayList<String>();
            while(cursor.moveToNext())
                s.add(cursor.getString(0));
    
            return s;
        }
    }
    

它运行良好,但是当我返回到第一个活动 (MainActivity) 然后我点击另一个项目(或同一个项目)时,它会创建另一个 PlayerActivity,因此应用程序同时播放 2 首歌曲.

我怎样才能实现它以便它只创建一个 PlayerActivity?

【问题讨论】:

    标签: android android-intent android-activity android-music-player


    【解决方案1】:

    【讨论】:

    • 我已经检查了 singleTask 和 singleInstance,但它的作用相同...
    • 我们需要更多的活动代码。您的媒体播放器在哪里初始化,您的歌曲加载在哪里,...
    • 代码已上传!感谢您的关注。
    • 如果您通过 Intend 启动活动,则会调用 onCreate()。在你的 onCreate 函数中,你总是在创建一个新的媒体播放器,如果它已经存在的话。一个简单的 nullcheck if(mediaPlayer==null) 应该可以解决问题。我会建议 explizit 停止当前正在播放的媒体。看看developer.android.com/reference/android/media/MediaPlayer.html的状态图
    • nullcheck 也不起作用......似乎一旦你点击一个项目,它就会创建一个新的 PlayerActivity,无论它是否存在。
    【解决方案2】:

    解决了!我试图通过 Intent 传递在 MainActivity 中创建的 MediaPlayer 实例,但似乎无法完成。所以,这是我的解决方案:

    1. 创建一个扩展 Application 的类并在那里实例化 MediaPlayer,这样我就有了一个全局 MediaPlayer 对象:

      import android.app.Application;
      import android.media.MediaPlayer;
      
      public class MyApp extends Application {
          MediaPlayer mediaPlayer=null;
      
          public MediaPlayer getMediaPlayer() {
              return mediaPlayer;
          }
      
          public void setMediaPlayer(MediaPlayer mediaPlayer) {
              this.mediaPlayer=mediaPlayer;
          }
      }
      
    2. 在 AndroidManifest.xml 中将 MyApp 设置为我的应用程序的名称:

      <application
      android:name="NicoPlayer"
      ...>
          ...
      </application>
      
    3. 在 PlayerActivity 中创建一个 MediaPlayer 实例并调用 getMediaPlayer() 将全局 MediaPlayer 实例分配给它,所有这些都在 onCreate() 方法中。完成此操作并且 mediaPlayer 正在播放后,将其分配给调用 setMediaPlayer() 的全局 MediaPlayer 实例:

      mediaPlayer=((NicoPlayer)this.getApplication()).getMediaPlayer();
      if(mediaPlayer==null)
          mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.parse(songPath));
      ((NicoPlayer)this.getApplication()).setMediaPlayer(mediaPlayer);
      try {
          mediaPlayer.reset();
          mediaPlayer.setDataSource(getApplicationContext(), Uri.parse(songPath));
          mediaPlayer.prepare();
          mediaPlayer.start();
      } catch (IOException e) {
          e.printStackTrace();
      }
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多