Giới thiệu dự án

Sự bùng nổ của thị trường thiết bị di động thông minh đã biến hệ điều hành Android thành nền tảng phổ biến nhất toàn cầu, chiếm hơn 85% thị phần hệ điều hành di động vào giai đoạn 2017–2018. Song hành với sự gia tăng phần cứng là nhu cầu giải trí đa phương tiện, đặc biệt là thưởng thức âm nhạc cá nhân hóa trên smartphone. Tuy nhiên, phần lớn các nền tảng streaming trực tuyến đòi hỏi kết nối mạng 3G/4G hoặc Wi-Fi liên tục, tiêu tốn băng thông, tiêu hao dung lượng pin đáng kể và hoàn toàn bị gián đoạn tại các khu vực sóng yếu hoặc khi di chuyển trên máy bay, tàu xe.

Vấn đề cốt lõi đặt ra là sự thiếu vắng các giải pháp nghe nhạc cục bộ (offline player) gọn nhẹ, có khả năng tối ưu hóa phần cứng di động cấu hình thấp, tiết kiệm năng lượng và hỗ trợ xử lý tín hiệu âm thanh kỹ thuật số độ trễ thấp mà không bị phụ thuộc vào máy chủ trung gian hay quảng cáo gây gián đoạn.

Đồ án tốt nghiệp "Xây dựng ứng dụng Android nghe nhạc offline" do sinh viên Đoàn Hoàng Hải thực hiện dưới sự hướng dẫn của ThS. Phùng Anh Tuấn tại Trường Đại học Dân Lập Hải Phòng (2018) tập trung giải quyết triệt để bài toán này.

Mục tiêu cụ thể của đồ án bao gồm:

  1. Nghiên cứu toàn diện kiến trúc phân tầng hệ điều hành Android từ tầng Linux Kernel, Android Runtime (Dalvik/ART), Libraries đến Application Framework.
  2. Khai thác nguyên lý xử lý tín hiệu âm thanh số (Digital Audio), phân tích cấu trúc mã hóa nén tổn hao (lossy - MP3, AAC) và không tổn hao (lossless - FLAC, WAV, PCM).
  3. Thiết kế và hiện thực hóa ứng dụng Android Native hoàn chỉnh bằng ngôn ngữ Java trên Android Studio, tích hợp MediaPlayer API, quản lý dữ liệu cấu hình qua SharedPreferences, và xây dựng giao diện tương tác động với hệ thống Animation mượt mà.

Giải pháp được lựa chọn là xây dựng ứng dụng Native chạy trực tiếp trên thiết bị (on-device execution), truy xuất trực tiếp bộ nhớ trong và thẻ nhớ ngoài (SD Card) thông qua cơ chế cấp quyền READ_EXTERNAL_STORAGE.

Kết quả kỳ vọng bao gồm:

  • Tệp tin cài đặt APK tối ưu (< 15 MB).
  • Thời gian khởi động ứng dụng cực nhanh (< 1.2 giây).
  • Mức tiêu thụ bộ nhớ RAM ổn định dưới 65 MB khi đang phát nhạc nền.
  • Tương thích đa phiên bản từ Android 4.4 (KitKat) đến Android 8.1 (Oreo).

Phạm vi nghiên cứu tập trung vào môi trường Android thuần túy, phát nhạc từ bộ nhớ lưu trữ cục bộ, không bao gồm các tính năng đồng bộ đám mây hay mạng xã hội.


Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Tại thời điểm nghiên cứu, thị trường ứng dụng nghe nhạc phân hóa thành hai xu hướng rõ rệt: các ứng dụng trực tuyến quy mô lớn (Zing MP3, NhacCuaTui, Spotify) và trình phát nhạc mặc định của hệ điều hành (AOSP Music Player).

Tiêu chí phân tích Trình phát trực tuyến (Zing MP3 / NCT) Trình phát AOSP mặc định Ứng dụng Android Offline (Đề tài)
Yêu cầu mạng Bắt buộc kết nối Internet liên tục Không Không phụ thuộc mạng
Mức chiếm dụng RAM Cao (120 MB – 250 MB) Thấp (30 MB – 45 MB) Rất thấp (35 MB – 60 MB)
Mức tiêu hao pin 8% – 15%/giờ (do modem 3G/4G/Wi-Fi) 2% – 3%/giờ 2.1% – 3.2%/giờ
Khả năng tùy biến UI Bị chi phối bởi banner quảng cáo Rất đơn điệu, không có hiệu ứng Tùy biến linh hoạt, hiệu ứng chuyển cảnh
Tối ưu phần cứng yếu Kém (dễ giật lag trên RAM 512MB) Tốt Xuất sắc (tối ưu qua ART/Dalvik)

Dựa trên mô hình phân loại yêu cầu MoSCoW:

  • Must have (Bắt buộc): Quét toàn bộ tệp âm thanh cục bộ (.mp3, .wav, .aac), giao diện điều khiển phát nhạc (Play, Pause, Next, Previous, Seek Bar), xử lý Service chạy ngầm khi tắt màn hình, quản lý vòng đời Activity.
  • Should have (Nên có): Hiệu ứng chuyển động giao diện (Fade, Rotate, Zoom), trích xuất thông tin siêu dữ liệu (ID3 metadata), lưu trạng thái cài đặt qua SharedPreferences.
  • Could have (Có thể có): Chế độ phát lặp lại (Loop) và phát ngẫu nhiên (Shuffle), tùy biến danh sách bài hát yêu thích.
  • Won't have (Chưa hỗ trợ): Streaming trực tuyến, đồng bộ hóa đám mây, chỉnh sửa nhạc chuông.

Thách thức kỹ thuật lớn nhất là xử lý cơ chế xin quyền truy cập bộ nhớ ngoài động trên Android 6.0+ (Marshmallow) và tối ưu hóa bộ nhớ tạm khi nạp danh sách hàng trăm tệp MP3 dung lượng lớn.

Thiết kế hệ thống

Kiến trúc ứng dụng tuân thủ mô hình 4 tầng tiêu chuẩn của hệ điều hành Android:

+-------------------------------------------------------------+
|                     TẦNG ỨNG DỤNG (APPLICATIONS)            |
|       MainActivity | SongListActivity | PlayMusicActivity   |
+-------------------------------------------------------------+
|              APPLICATION FRAMEWORK (KHUÔN KHỔ ỨNG DỤNG)     |
|   ActivityManager | WindowManager | ContentProvider | Views |
+-------------------------------------------------------------+
|    LIBRARIES (C/C++)        |    ANDROID RUNTIME (ART/DALVIK)|
|  OpenCORE/Media | SQLite    |   Core Java Libs | DEX Engine |
|  FreeType | LibWebCore      |   Register-based Architecture |
+-------------------------------------------------------------+
|                       LINUX KERNEL 2.6 / 3.x                |
|  Audio Drivers | Memory Mgmt | Process Stack | Power Mgmt   |
+-------------------------------------------------------------+

Technology Stack của dự án:

  • Ngôn ngữ lập trình: Java (JDK 1.8 / Java SE 8).
  • Môi trường phát triển tích hợp (IDE): Android Studio 3.x (IntelliJ IDEA base).
  • Hệ thống build tự động: Gradle Scripts (build.gradle).
  • Máy ảo thử nghiệm: Genymotion 2.12 tích hợp Oracle VirtualBox 4.x hỗ trợ gia tốc phần cứng Intel VT-x.
  • Lưu trữ dữ liệu: SharedPreferences (XML-based storage) và MediaStore ContentProvider.
  • Thư viện âm thanh lõi: android.media.MediaPlayer.

Cấu trúc lưu trữ cấu hình người dùng qua SharedPreferences:

  • Tên tệp: music_player_prefs.xml
  • Chế độ bảo mật: Context.MODE_PRIVATE (ngăn chặn các ứng dụng khác truy cập trái phép).
  • Cặp Key-Value: LAST_PLAYED_SONG_ID (String), SEEK_POSITION (int), IS_SHUFFLE (boolean), IS_REPEAT (boolean).

Methodology

Quy trình phát triển áp dụng mô hình Thác nước kết hợp tạo mẫu nhanh (Iterative Prototyping) qua 4 giai đoạn chính trong 12 tuần:

  1. Tuần 1–3: Nghiên cứu lý thuyết hệ điều hành Android, cấu trúc nén MP3 và API MediaPlayer.
  2. Tuần 4–6: Thiết kế layout XML (res/layout), định nghĩa tài nguyên (res/values, res/drawable), tạo animation XML (res/anim).
  3. Tuần 7–9: Hiện thực mã nguồn Java, liên kết Controller với XML View, xây dựng cơ chế Intent và xử lý đa tiến trình.
  4. Tuần 10–12: Thử nghiệm trên máy ảo Genymotion và thiết bị thật, đo đạc hiệu năng và đóng gói bản build APK.

Implementation và kết quả

Development process

Cấu trúc mã nguồn của dự án được tổ chức chặt chẽ trong thư mục app/src/main/java:

  • com.hoanghai.musicplayer.activities: Chứa MainActivity, PlayerActivity.
  • com.hoanghai.musicplayer.adapter: Chứa SongAdapter kế thừa từ BaseAdapter / RecyclerView.Adapter.
  • com.hoanghai.musicplayer.model: Chứa đối tượng thực thể Song (Title, Artist, Duration, Path).

Cấu hình quyền và khai báo thành phần trong AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hoanghai.musicplayer">

    <!-- Xin quyền đọc bộ nhớ ngoài để quét tệp nhạc -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity android:name=".PlayerActivity" />
    </application>
</manifest>

Hiện thực hóa máy trạng thái phát nhạc bằng MediaPlayer:

public class PlayerActivity extends AppCompatActivity {
    private MediaPlayer mediaPlayer;
    private ImageView imgDisk;
    private Animation rotateAnim;

    private void initMediaPlayer(String songPath) {
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }
        mediaPlayer = new MediaPlayer();
        try {
            mediaPlayer.setDataSource(songPath);
            mediaPlayer.prepare(); // Chuyển sang trạng thái Prepared
            mediaPlayer.start();   // Chuyển sang trạng thái Started
            
            // Nạp và kích hoạt hiệu ứng xoay đĩa nhạc
            rotateAnim = AnimationUtils.loadAnimation(this, R.anim.rotate_disk);
            imgDisk.startAnimation(rotateAnim);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mediaPlayer != null) {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
            }
            mediaPlayer.release(); // Giải phóng tài nguyên phần cứng
            mediaPlayer = null;
        }
    }
}

Cơ chế lưu trữ trạng thái người dùng bằng SharedPreferences:

public void savePlaybackState(String songPath, int currentPosition) {
    SharedPreferences sharedPreferences = getSharedPreferences("MUSIC_PREFS", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString("CURRENT_SONG_PATH", songPath);
    editor.putInt("CURRENT_POSITION", currentPosition);
    editor.apply(); // Ghi bất đồng bộ xuống disk
}

Truyền dữ liệu giữa các Activity thông qua IntentBundle:

// Gửi dữ liệu từ Danh sách sang Trình phát nhạc
Intent intent = new Intent(MainActivity.this, PlayerActivity.class);
Bundle bundle = new Bundle();
bundle.putString("SONG_NAME", songList.get(position).getTitle());
bundle.putString("SONG_PATH", songList.get(position).getPath());
intent.putExtras(bundle);
startActivity(intent);

Testing và validation

Quá trình kiểm thử được thực thi trên môi trường máy ảo Genymotion (Google Nexus 5 - Android 6.0, Google Pixel - Android 8.0) và thiết bị phần cứng thực tế (Samsung Galaxy J7 Prime, Xiaomi Redmi Note 4).

Kết quả kiểm thử hiệu năng:

  • Tốc độ phản hồi tương tác UI: Đạt chuẩn 60 FPS trong các hiệu ứng chuyển trang và xoay đĩa nhạc.
  • Độ trễ khởi tạo âm thanh (Audio Latency): < 85 ms từ lúc chạm nút Play đến khi giải mã tín hiệu ra loa.
  • Mức tiêu hao CPU trung bình: 1.8% – 3.2% khi phát tệp MP3 bitrate 320 kbps chuẩn Stereo 44.1 kHz.
  • Tỷ lệ kiểm thử giao diện & chức năng: Đạt 100% kịch bản kiểm thử (Play/Pause, Chuyển bài, Tua thanh SeekBar, Tự động chuyển bài khi kết thúc tệp).
+---------------------+-------------------+---------------------+
| Kịch bản kiểm thử   | Kết quả mong đợi  | Trạng thái thực tế  |
+---------------------+-------------------+---------------------+
| Quét 500 bài hát    | < 2.0 giây        | 1.35 giây (PASS)    |
| Tắt màn hình        | Nhạc vẫn tiếp tục | Duy trì tốt (PASS)  |
| Cuộc gọi đến        | Tự động Pause     | Đã xử lý (PASS)     |
| Rút tai nghe        | Tự ngắt phát nhạc | Đã xử lý (PASS)     |
+---------------------+-------------------+---------------------+

Đổi mới và đóng góp

  1. Ứng dụng mô hình tâm thính học (Psychoacoustics) trong quản lý buffer âm thanh: Tận dụng đặc tính nén của chuẩn MP3 (loại bỏ dải tần ngoài ngưỡng nghe 20 Hz – 20 kHz của tai người) kết hợp với thuật toán biến đổi cosin rời rạc biến đổi (MDCT), ứng dụng tính toán bộ đệm luồng vừa đủ cho các khung dữ liệu 576 mẫu, giảm thiểu 40% chi phí I/O đọc ổ đĩa so với các cơ chế buffer thông thường.
  2. Kiến trúc giao diện phân tầng tối ưu Animation: Triển khai hiệu ứng đĩa quay đồng bộ với chu kỳ phát nhạc thông qua việc nạp các tệp XML Animation được tính toán sẵn từ thư mục res/anim, giúp giảm tải việc tính toán đồ họa trực tiếp trên luồng chính (Main UI Thread), duy trì độ mượt mà ổn định.
  3. Cơ chế quản lý bộ nhớ đệm hai lớp: Kết hợp nạp metadata qua ContentProvider và lưu trữ trạng thái bằng SharedPreferences, ứng dụng loại bỏ hoàn toàn việc phải quét lại toàn bộ thẻ nhớ trong mỗi lần khởi động lại, tăng tốc độ truy cập danh sách nhạc lên 3.5 lần.

So sánh với các giải pháp trên thị trường:

  • So với Zing MP3 / NhacCuaTui: Tiết kiệm 100% dung lượng data di động, giảm 68% mức chiếm dụng RAM, loại bỏ hoàn toàn tình trạng giật lag do kết nối mạng chập chờn.
  • So với AOSP Stock Player: Giao diện trực quan hơn nhờ tích hợp Material Design cơ bản, hỗ trợ hiệu ứng xoay đĩa nhạc sinh động, tối ưu hóa thao tác điều hướng chỉ với một chạm.

Ứng dụng thực tế và triển khai

Tình huống sử dụng thực tế

  • Người dùng thường xuyên di chuyển: Người đi máy bay, tàu hỏa, xe bus đường dài hoặc dã ngoại tại các vùng không có sóng viễn thông.
  • Thiết bị cấu hình khiêm tốn: Các dòng điện thoại thông minh phổ thông có dung lượng RAM từ 512 MB – 1 GB tại các thị trường đang phát triển.
  • Hệ thống nhúng chuyên dụng: Làm nền tảng giải trí cho các thiết bị Android nhúng trên ô tô (Android Car Dashboard), máy nghe nhạc cầm tay chạy hệ điều hành Android tùy biến.

Yêu cầu triển khai và khả năng mở rộng

  • Yêu cầu hệ thống tối thiểu: Thiết bị chạy Android 4.4 (KitKat - API 19) trở lên, vi xử lý ARMv7 hoặc x86, RAM tối thiểu 512 MB, dung lượng bộ nhớ trống tối thiểu 20 MB.
  • Yêu cầu đề nghị: Android 8.0/8.1 (Oreo), RAM 2 GB, hỗ trợ thẻ nhớ ngoài MicroSD chuẩn Class 10.
  • Hiệu quả kinh tế (ROI): Chi phí phát triển và vận hành tiệm cận 0 VNĐ do không yêu cầu duy trì máy chủ backend, không tốn chi phí thuê bao CDN truyền phát dữ liệu, mang lại giải pháp kinh tế tối ưu cho người dùng cá nhân.

Hạn chế và hướng phát triển

Hạn chế kỹ thuật

  • Chưa tích hợp bộ cân bằng âm sắc chuyên sâu (Equalizer) với các hiệu ứng âm thanh 3D, Bass Boost.
  • Chưa hỗ trợ tự động tìm kiếm và đồng bộ hóa lời bài hát (LRC lyrics synchronization).
  • Việc quét tệp phụ thuộc vào cơ chế lập chỉ mục của hệ thống, đôi khi gặp độ trễ nếu thẻ nhớ bị phân mảnh nặng.

Hướng phát triển

  • Tích hợp thư viện đồ họa hiển thị sóng âm theo thời gian thực (Visualizer Audio Waveform).
  • Nâng cấp kiến trúc lên mô hình MVVM (Model-View-ViewModel) kết hợp Android Jetpack (Room Database, LiveData, ViewModel).
  • Hỗ trợ phát các định dạng chất lượng cao Hi-Res Audio 24-bit/192 kHz sử dụng thư viện ExoPlayer hoặc FFmpeg Audio Engine.

Đối tượng hưởng lợi

  • Sinh viên ngành CNTT: Nguồn tài liệu học tập thực tế về lập trình Android Native, cấu trúc dự án chuẩn trong Android Studio, cách xử lý vòng đời Activity và cơ chế tương tác đa màn hình bằng Intent/Bundle.
  • Lập trình viên Mobile: Mẫu tham khảo chất lượng về cách điều khiển MediaPlayer, xử lý đa luồng ngầm và quản lý trạng thái phiên làm việc cục bộ bằng SharedPreferences.
  • Doanh nghiệp / Đơn vị sản xuất thiết bị: Giải pháp tham khảo để xây dựng module phát âm thanh ngoại tuyến cho các thiết bị phần cứng thông minh chạy Android nhúng.
  • Nhà nghiên cứu: Cung cấp số liệu thực nghiệm về mức tiêu thụ năng lượng và hiệu năng giải mã các chuẩn nén âm thanh số (MP3, WAV, AAC, FLAC) trên nền tảng di động.

Câu hỏi thường gặp

1. Yêu cầu kỹ thuật tối thiểu để biên dịch và triển khai ứng dụng là gì?

Để biên dịch dự án, máy tính cần cài đặt Java Development Kit (JDK 7 hoặc JDK 8), Android Studio phiên bản 3.0 trở lên và Android SDK hỗ trợ từ API Level 19 (Android 4.4) đến API Level 27 (Android 8.1). Đối với thiết bị di động, ứng dụng yêu cầu RAM tối thiểu 512 MB và bộ nhớ trống từ 20 MB.

2. Giới hạn xử lý số lượng bài hát của ứng dụng là bao nhiêu?

Ứng dụng có thể quản lý danh sách lên đến 5.000 bài hát mà không gây tràn bộ nhớ (OutOfMemory Exception) nhờ cơ chế tái sử dụng View của ListView/RecyclerView kết hợp mô hình ViewHolder, chỉ nạp vào RAM các thành phần đang hiển thị trên màn hình.

3. Làm thế nào ứng dụng xử lý khi có cuộc gọi đến trong lúc đang phát nhạc?

Ứng dụng sử dụng lớp AudioManager và lắng nghe sự kiện AudioFocusChange. Khi có cuộc gọi đến hoặc ứng dụng khác yêu cầu quyền phát âm thanh, hệ thống sẽ tự động gửi thông điệp AUDIOFOCUS_LOSS_TRANSIENT để tạm dừng (pause) bài hát và tự động tiếp tục (resume) khi cuộc gọi kết thúc.

4. Ứng dụng có tự động cập nhật khi người dùng chép thêm bài hát mới vào thẻ nhớ không?

Có. Thông qua việc truy vấn MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, ứng dụng sẽ tự động đồng bộ danh sách nhạc mới mỗi khi khởi chạy lại Activity chính hoặc khi người dùng kích hoạt thao tác quét lại bộ nhớ.

5. Chi phí duy trì và khả năng thương mại hóa của sản phẩm như thế nào?

Sản phẩm hoạt động độc lập không cần máy chủ (serverless), do đó chi phí bảo trì định kỳ bằng 0. Ứng dụng có thể thương mại hóa bằng cách đóng gói phát hành miễn phí trên Google Play Store và tích hợp mạng lưới quảng cáo ngoại tuyến hoặc cung cấp phiên bản trả phí nâng cấp thêm tính năng Equalizer chuyên nghiệp.


Kết luận

Đồ án "Xây dựng ứng dụng Android nghe nhạc offline" đã hoàn thành xuất sắc toàn bộ các mục tiêu đặt ra: từ việc nghiên cứu lý thuyết nền tảng hệ điều hành Android, làm chủ kỹ thuật xử lý tín hiệu âm thanh kỹ thuật số, đến việc xây dựng thành công một sản phẩm ứng dụng di động hoàn chỉnh, hoạt động mượt mà và tối ưu hóa hiệu năng.

Dự án chứng minh tính khả thi vượt trội của giải pháp phát nhạc nội bộ trong việc tiết kiệm tài nguyên phần cứng và năng lượng, mang lại giá trị sử dụng thiết thực cho cộng đồng người dùng di động. Các nhà phát triển và sinh viên quan tâm có thể tiếp cận mã nguồn dự án để tiếp tục mở rộng thêm các tính năng nâng cao như xử lý hiệu ứng âm thanh số DSP và đồng bộ lời bài hát tự động.