Sunday, January 13, 2019

Chơi nhạc liên tục trong danh sách


Ta đã có thể lấy các file mp3 trong thẻ nhớ đưa vào dach sách để phát. Bây giờ làm sao để có thể chơi nhạc liên tục, sau khi ấn chọn bài mà play xong, các bài sau cứ thế phát tiếp.
Khai báo thêm vào class chơi nhạc các biến sau.
int dem = 0;
int dem2=0;
private final Handler handler = new Handler();
Copy hàm sau vào trên ngoặc đóng dưới cùng.
Runnable notification;
     private void play() {
          if (mPlayer.isPlaying()) {
                notification = new Runnable() {
          @TargetApi(Build.VERSION_CODES.GINGERBREAD)
               @SuppressLint("NewApi")
               public void run() {
          play();
                     }
               };
          handler.postDelayed(notification, 1000);
          }
          else{
               if (dem2 == 1) {
                    mPlayer.pause();
               } else {
                     dem = dem + 1;
                     if (dem == mMusicList.size()) {
                          dem = 0;
                     }
                      
                     mPlayer.reset();
                     String path=mAudioPath.get(dem);
                   try {
                          mPlayer.setDataSource(path);
                     } catch (IllegalArgumentException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                     } catch (SecurityException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                     } catch (IllegalStateException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                     } catch (IOException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                     }      
               try {
                          mPlayer.prepare();
                     } catch (IllegalStateException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                     } catch (IOException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                     }
                   mPlayer.start();
               play();
               }
          }
   }
Trong hàm này ta dùng handler để kiểm tra, nếu thấy nhạc không phát tức là đã dừng bài, ta liền khởi tạo và phát bài tiếp theo trong danh sách.
Thay toàn bộ lệnh trong listView bằng các dòng.
dem2=0;
dem=arg2-1;
if (mPlayer.isPlaying()) {
mPlayer.reset();    
handler.removeCallbacks(notification);
}
play();
Tức là khi ấn ta gọi hàm để play, nếu đang phát mà ấn bài khác thì thoát bài hiện tại và chơi bài mới.
Để chơi được nhạc khi điện thoại khoá máy, tắt màn hình, ta thêm vào.
@Override
public void onPause() {
super.onPause();
play();
}
Cuối cùng, vì có dùng handler nên phải tắt nó đi khi thoát class, nếu không nhạc sẽ phát tiếp bài khác.
@Override
    public void onStop() {
        super.onStop();
   handler.removeCallbacks(notification);
}
Đoạn này có thể phải thêm cả vào nút Quit trong class hoặc nút Back của điện thoại, hoặc trong onDestroy()tuỳ thực tế mà dùng.
Nếu muốn nhạc phát không theo thứ tự trên xuống mà chọn bài ngẫu nhiên ta tạo một biến Random ở trong khoảng kích thước mảng các bài hát. Sau đó sửa phương thức chơi nhạc đi để có thể gán số id bài hát vào là được.
Một vấn đề nữa là ta muốn set tên bài hát đang phát vào textView nổi dưới đáy listView chẳng hạn. Ta sẽ tạo thêm textView trong RelativeLayout và set nó android:layout_alignParentBottom="true". Còn ListView thì android:layout_above="@+id/textview. Sau đó thêm vào trong phương thức play() và trong lệnh của listView.
tenbai.setText(mMusicList.get(dem));
Có những trường hợp ta vừa chơi nhạc khi ấn vào danh sách, vừa ấn vào nút nào đó. Ta phải kiểm tra để nếu handler đã chạy, ta không gọi lại nó nữa, chỉ start play thôi. Nếu không nó có thể chạy song trùng, tốn bộ nhớ, gây rắc rối khi thoát class.
Ta kiểm tra bằng cách tạo một biến boolean isRunning = false;
Sau đó cho nó vào trong lệnh run.
     private void play() {
     if (mPlayer.isPlaying()) {
          notification = new Runnable() {
               @TargetApi(Build.VERSION_CODES.GINGERBREAD)
               @SuppressLint("NewApi")
               public void run() {
                   isRunning = true;
                     play();
               }
          };
          handler.postDelayed(notification, 1000);
              
        }

Nếu giá trị là true, ta biết handler đã chạy.

No comments:

Post a Comment