20212324 2023-2024-2 《移动平台开发与实践》移动平台开发综合实践
1.综合实践内容
- 参考CSDN上大神教程,实现了可注册登录的音乐播放器:
- 布局:至少使用了两种布局方式;
- 登录功能:使用了数据库相关操作,注册成功数据保存到SQLite,登录验证时比对数据库,校验用户名和密码是否正确
- 音乐列表界面:使用ListView,通过ContentResolver获取本地音乐;
- 播放功能:音乐使用Service控制,应用退到后台后仍支持播放;播放界面美观好看;
- 使用Toast提示,注册成功还是失败,登录,播放,分享等
- 所有字符串全部放到Strings.xml中,java和布局文件中不出现字符串
1.1课程总结和思考
- 王老师的课程总是以通俗易懂的解释和丰富的实例实践引导读者进入对应领域的广阔世界。在一学期的学习中,我们从基础知识、布局、UI组件、资源和权限、四大组件、数据存储、网络编程、多媒体等方面系统完整地学习实践了Android开发相关知识,同样重要的,我们在一次次的学习与实践当中体会到了实践的重要性、亲身感受到了技术与创意的结合,更培养了我们的问题解决能力。在十次课和六次实践以及一次大实践中,我们切切实实提高了自己的编程能力和水平,也对AndroidStudio的使用更加纯熟,这是课程的一大特色,即让同学们真真切切理解并提高了相应能力。
- 这一段学习旅程即将告一段落,感谢王老师这段时间以来的辛勤教导,也感谢同学们一直以来的无私奉献。感谢老师点燃了我们对学习的热情,激发了我们探索未知的勇气;感谢大家的无私帮助,让我们都在彼此学术和人生的道路上都受益匪浅。衷心感谢大家的辛勤付出和悉心关怀,我将永远铭记在心。
1.2成果演示
-
演示视频如下:
-
2024-06-17 15-28-28.mp4
-
-
功能和界面如下:
- 登录界面activity_login
- 注册界面
- 注册成功跳转登录页面
- 登录成功跳转播放器页面
- 播放音乐
- 添加至我喜欢
- 调整播放循环
- 设置分享
2.总体实践思路
2.1实验分析过程
2.1.1功能实现
- MusicPlayer 应当是一款集成了用户注册登录功能的音乐播放器应用。该应用通过以下几个关键功能模块实现:
- 用户注册与登录机制:
- 用户可以通过注册界面创建新账户,其信息保存在 SQLite 数据库中。
- 登录时,系统会校验用户名和密码的正确性,确保账户安全。
- 音乐播放功能:
- 用户登录后可以浏览和播放本地存储的音乐文件。
- 播放功能通过 Service 控制,即使应用退到后台也能继续播放。
- 音乐列表展示:
- 使用 ListView 控件展示音乐列表,通过 ContentResolver 访问本地音乐文件。
- 播放控制界面:
- 提供了直观的播放控制界面,包括播放、暂停、上一首、下一首等操作。
- 界面设计美观,提升用户体验。
- 交互提示:
- 使用 Toast 消息提示用户注册、登录、播放等操作的状态。
- 资源管理:
- 所有字符串资源统一管理在 Strings.xml 文件中,使得维护和多语言支持变得更加容易。
2.1.2界面设计
-
MusicPlayer 的界面设计简洁而直观,以下是几个关键界面的分析:
-
登录界面 (
activity_login
):提供了用户名和密码输入框,以及登录按钮,用户可以在此进行账户登录。 -
注册界面:用户可以输入必要信息进行新账户的创建,包括用户名、密码等,并提供验证码增加安全性。
-
音乐播放列表界面 (
activity_main2
):展示用户设备上所有可用的音乐,用户可以在此选择播放。 -
播放控制界面 (
player_layout
):提供了音乐播放的详细控制,包括音量调节、播放进度条、当前播放时间等。
-
2.1.3技术实现
-
MusicPlayer 应用在技术实现上采用了以下关键技术:
-
SQLite 数据库:用于用户信息的持久化存储。
-
ContentResolver API:用于访问设备上的媒体文件。
-
Service 组件:确保音乐播放功能在后台也能正常工作。
-
自定义 Adapter:用于 ListView 的数据绑定和展示。
-
多媒体 API(如 MediaPlayer):用于音乐的播放控制。
-
2.2数据库设计
-
usr表:
字段 数据类型 主键 外键 是否为空 说明 id INTEGER 是 否 否 自动递增(AUTOINCREMENT) username VARCHAR 否 否 否 存储用户的用户名 password VARCHAR 否 否 否 存储用户的密码
2.3调用逻辑
-
用户在
MainActivity
中点击登录或注册按钮,触发对应的服务调用。 -
注册界面
zhuce
在创建时会生成验证码,用户提交注册信息后,通过UserService.register
调用数据库帮助类DatabaseHelper
来插入新用户。 -
登录服务
UserService.login
会查询user
表来验证用户信息。 -
成功登录后,用户可以进入
MainActivity2
,进而使用音乐播放界面player
。 -
player
界面通过SongTools
获取歌曲列表,该工具类查询MediaStore.Audio.Media
来获取设备上的音乐文件。 -
用户注册或登录成功后,相关信息会保存到
SharedPreferences
。
2.4java文件与UI的对应关系
-
MainActivity
是应用程序的入口点,包含登录和注册按钮。 -
用户点击注册按钮时,会触发
zhuce Activity
,该活动显示验证码(由Code
类生成)并注册用户。 -
用户点击登录按钮时,会调用
UserService
的登录验证。 -
UserService
的登录验证成功后,用户会被重定向到MainActivity2
,失败则显示错误提示(Toast
)。 -
MainActivity2
和player Activity
负责音乐播放控制,使用MediaPlayer
。 -
player Activity
还显示歌曲列表,通过MyAdapter
绑定到ListView
。 -
注册和登录的用户数据通过
DatabaseHelper
插入到user Table
。 -
Music Activity
可能是另一个音乐播放界面,使用SongTools
查询本地音乐。 -
SongTools
通过MediaStore.Audio.Media
访问设备上的音乐文件。
3.实践过程
3.1代码编写逻辑
3.1.1用户登录
-
初始化用户名和密码输入框:
EditText etName = findViewById(R.id.et_name); EditText etPwd = findViewById(R.id.et_pwd);
-
设置登录按钮并添加点击事件:
Button btnLogin = findViewById(R.id.btn_login); btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 触发登录操作 } });
-
验证用户名和密码,这里使用MD5加密验证:
String name = etName.getText().toString(); String pwd = etPwd.getText().toString(); if (name.equals("admin") && MD5Utils.encode(pwd).equals(MD5Utils.encode("20212325"))) { Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show(); // 进行后续操作,如跳转到主界面 }
-
记住用户名和密码功能,使用
SharedPreferences
存储:CheckBox cb = findViewById(R.id.remember_me); SharedPreferences sharedPreferences = getSharedPreferences("user_data", MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); if (cb.isChecked()) { editor.putString("username", name); editor.putString("password", pwd); editor.apply(); } else { editor.clear().apply(); }
3.1.2启动画面
-
使用
Timer
和TimerTask
实现启动画面的延时跳转:Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { Intent intent = new Intent(this, MainActivity2.class); startActivity(intent); finish(); } }, 3000); // 3秒后跳转
3.1.3主功能界面
-
初始化主界面,设置各个按钮的点击事件:
public void initMainUI() { Button btnPlay = findViewById(R.id.btn_play); btnPlay.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 播放音乐 } }); // 其他按钮初始化... }
3.1.4音乐播放控制
-
实现音乐播放、暂停、上一首、下一首等控制:
MediaPlayer mediaPlayer = new MediaPlayer(); Button btnPlay = findViewById(R.id.btn_play); btnPlay.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); } else { mediaPlayer.start(); } } });
-
更新歌曲进度条和当前播放时间:
SeekBar seekBar = findViewById(R.id.seek_bar); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { mediaPlayer.seekTo(progress); } } // 其他回调... });
3.1.5数据库设计
-
设计数据库帮助类
DatabaseHelper
,创建和版本管理数据库:public class DatabaseHelper extends SQLiteOpenHelper { public static final String DATABASE_NAME = "musicPlayer.db"; public static final int DATABASE_VERSION = 1; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { // 创建用户表SQL语句 } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 数据库升级操作 } }
-
实现用户注册和登录的数据库操作:
复制public class UserService { private DatabaseHelper dbHelper; public UserService(Context context) { dbHelper = new DatabaseHelper(context); } public boolean login(String username, String password) { // 登录逻辑 } public boolean register(User user) { // 注册逻辑 } }
3.2UI界面编写过程
3.2.1activity_main.xml登录界面
-
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@mipmap/background4" android:orientation="vertical"> <EditText android:id="@+id/et_name" android:layout_width="match_parent" android:layout_height="70dp" android:layout_gravity="center" android:layout_marginLeft="30dp" android:layout_marginTop="350dp" android:layout_marginRight="30dp" android:background="@drawable/blackground" android:textColorHint="@color/color_gray" android:textColor="@color/white" android:gravity="center" android:hint="@string/main_xml1" android:inputType="number" /> <EditText android:id="@+id/et_password" android:layout_width="match_parent" android:layout_height="70dp" android:layout_gravity="center" android:layout_marginLeft="30dp" android:layout_marginTop="10dp" android:layout_marginRight="30dp" android:background="@drawable/blackground" android:cacheColorHint="#00000000" android:textColor="@color/white" android:gravity="center" android:hint="@string/main_xml2" android:textColorHint="@color/color_gray" android:inputType="textPassword" /> <Button android:id="@+id/login" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="60dp" android:layout_marginRight="60dp" android:cacheColorHint="#00000000" android:layout_marginTop="80dp" android:textColorHint="@color/color_gray" android:textColor="@color/color_gray" android:background="#00000000" android:text="@string/main_xml3" android:textSize="20dp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_marginTop="100dp" android:gravity="center_horizontal"> <Button android:id="@+id/btn_register" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="@string/main_xml4" android:textColor="@color/color_gray" android:textStyle="bold" android:background="@color/white" /> </LinearLayout> </LinearLayout>
3.2.2activity_zhuce.xml注册界面
-
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:textSize="20dp" android:background="@mipmap/background1"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:paddingTop="20dp" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal" android:padding="15dp"> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="1dp"> <ImageView style="@style/tvTwo" android:layout_width="150dp" android:layout_marginLeft="180dp" android:layout_height="150dp" android:background="@drawable/zhuceimg" android:gravity="center" android:paddingLeft="50dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="15dp"> <TextView style="@style/tvTwo" android:text="@string/zhuce_xml2" android:textSize="20dp" /> <EditText android:id="@+id/et_name" style="@style/etOne" android:hint="@string/zhuce_xml3" android:paddingLeft="35dp" android:textColorHint="@color/white" android:background="@drawable/blackground" android:textSize="20dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="15dp"> <TextView android:id="@+id/mima1" style="@style/tvTwo" android:text="@string/zhuce_xml4" android:textSize="20dp" /> <EditText android:id="@+id/pwd1" style="@style/etOne" android:paddingLeft="35dp" android:hint="@string/zhuce_xml5" android:textColorHint="@color/white" android:inputType="textPassword" android:background="@drawable/blackground" android:textSize="20dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="15dp"> <TextView android:id="@+id/mima2" style="@style/tvTwo" android:text="密码" android:textSize="20dp" /> <EditText android:id="@+id/pwd2" style="@style/etOne" android:hint="@string/zhuce_xml7" android:inputType="textPassword" android:paddingLeft="35dp" android:background="@drawable/blackground" android:textColorHint="@color/white" android:textSize="20dp" /> </LinearLayout> <!-- 验证码部分 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_marginRight="15dp" android:orientation="horizontal"> <!-- 第四个文本编辑框 输入验证码 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:id="@+id/et_loginactivity_phoneCodes" android:layout_width="0dp" android:layout_height="50dp" android:layout_marginLeft="15dp" android:layout_marginRight="1dp" android:layout_weight="1" android:background="@drawable/blackground" android:hint="@string/zhuce_xml8" android:paddingLeft="20dp" android:textColorHint="@android:color/white" android:textSize="15dp" /> <ImageView android:id="@+id/iv_registeractivity_showCode" android:layout_width="0dp" android:layout_height="70dp" android:layout_marginTop="-10dp" android:onClick="onClick" android:layout_weight="1.5" /> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="15dp"> <!-- <Button--> <!-- android:id="@+id/genghuang"--> <!-- android:layout_width="193dp"--> <!-- android:layout_height="50dp"--> <!-- android:layout_marginLeft="220dp"--> <!-- android:background="@null"--> <!-- android:gravity="center"--> <!-- android:text="看不清,换一张"--> <!-- android:textColor="@android:color/white"--> <!-- android:textSize="18sp" />--> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="15dp"> <TextView style="@style/tvTwo" android:layout_height="wrap_content" android:text="@string/zhuce_xml9" android:textSize="20dp" /> <RadioGroup android:id="@+id/rg_sex" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="50dp" android:orientation="horizontal"> <RadioButton android:id="@+id/rb_boy" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/zhuce_xml10" android:textColor="@android:color/white" android:textSize="20dp" /> <RadioButton android:id="@+id/rb_girl" style="@style/tvTwo" android:text="@string/zhuce_xml11" android:textSize="20dp" /> </RadioGroup> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="15dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/zhuce_xml12" android:textColor="@android:color/white" android:textSize="20dp" /> <CheckBox android:id="@+id/cb_sing" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/zhuce_xml13" android:textColor="@android:color/white" android:textSize="20dp" /> <CheckBox android:id="@+id/cb_dance" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/zhuce_xml14" android:textColor="@android:color/white" android:textSize="20dp" /> <CheckBox android:id="@+id/cb_read" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/zhuce_xml15" android:textColor="@android:color/white" android:textSize="20dp" /> </LinearLayout> </LinearLayout> <View android:id="@+id/v_line" android:layout_width="match_parent" android:layout_height="1dp" android:layout_above="@id/btn_submit" android:background="@android:color/darker_gray" /> <Button android:id="@+id/btn_submit" android:layout_width="match_parent" android:layout_height="50dp" android:layout_alignParentBottom="true" android:background="#00000000" android:gravity="center" android:text="@string/zhuce_xml16" android:textColor="@android:color/white" android:textSize="25dp" /> </RelativeLayout>
3.2.3activity_main2.xml音乐播放列表界面
-
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity2" android:background="@mipmap/background2" android:orientation="vertical"> <LinearLayout android:id="@+id/title" android:layout_width="match_parent" android:layout_height="60dp" android:layout_alignParentTop="true" android:gravity="center_vertical" android:orientation="horizontal" android:paddingLeft="10dp"> <ImageView android:layout_width="35dp" android:layout_height="35dp" android:layout_marginLeft="140dp" android:background="@drawable/music" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:text="@string/main2_xml1" android:textColor="@android:color/white" android:textSize="23sp" /> </LinearLayout> <ListView android:id="@+id/playlist" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="60dp" android:layout_marginBottom="68dp" android:cacheColorHint="#00000000" android:dividerHeight="1dp" android:headerDividersEnabled="true" android:paddingLeft="10dp" android:paddingRight="10dp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="8dp" android:orientation="horizontal" android:layout_alignParentBottom="true" android:id="@+id/now_playing_bar"> <ImageView android:id="@+id/now_playing_songfront" android:layout_width="50dp" android:layout_height="50dp" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:background="@drawable/music" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="50dp" android:padding="5dp"> <TextView android:id="@+id/now_playing_songname_tv" android:layout_width="200dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:singleLine="true" android:text="@string/main2_xml2" android:textColor="@color/white" android:textSize="16sp" /> <Button android:id="@+id/now_playing_pause_btn" android:layout_width="40dp" android:layout_height="40dp" android:layout_alignParentRight="true" android:layout_marginRight="63dp" android:background="@drawable/play_blue" /> <ImageButton android:id="@+id/now_playing_next_btn" android:layout_width="30dp" android:layout_height="30dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="10dp" android:background="@drawable/next" /> </RelativeLayout> </LinearLayout> </RelativeLayout>
3.2.4player_layout.xml音乐播放界面
-
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:id="@+id/player_layout" android:background="@mipmap/background2" android:padding="10dp"> <ImageButton android:layout_width="40dp" android:layout_height="40dp" android:id="@+id/play_go_back" android:background="@drawable/back_blue"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:orientation="horizontal" android:gravity="center"> <ImageView android:layout_width="20dp" android:layout_height="20dp" android:layout_marginRight="300dp" android:background="@drawable/mute"/> <ImageView android:layout_width="20dp" android:layout_height="20dp" android:background="@drawable/max"/> </LinearLayout> <SeekBar android:id="@+id/volume_seekbar" android:layout_width="360dp" android:layout_height="wrap_content" android:layout_marginLeft="38dp" /> <ImageView android:id="@+id/play_song_front" android:layout_width="270dp" android:layout_height="270dp" android:layout_gravity="center" android:layout_marginTop="40dp" android:background="@drawable/guangpan" /> <LinearLayout android:layout_width="392dp" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="horizontal"> <TextView android:id="@+id/play_song_name" android:layout_width="80dp" android:layout_height="30dp" android:paddingLeft="10dp" android:paddingTop="5dp" android:text="@string/player_xml1" android:textColor="@android:color/white" android:textSize="16sp" /> <ImageButton android:id="@+id/btn1" android:layout_width="36dp" android:layout_height="36dp" android:background="@drawable/loveup" android:layout_marginLeft="280dp" /> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/player_xml2" android:textSize="14sp" android:textColor="@android:color/white" android:paddingLeft="10dp" android:id="@+id/play_song_artist"/> <SeekBar android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:id="@+id/play_seekbar"/> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/play_current_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:text="0:00" android:textColor="@android:color/white"/> <TextView android:id="@+id/play_duration" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:textColor="@android:color/white"/> </RelativeLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="25dp" android:gravity="center"> <ImageButton android:id="@+id/model" android:layout_width="31dp" android:layout_height="36dp" android:layout_marginRight="20dp" android:background="@drawable/shunxubofang" /> <ImageButton android:layout_width="50dp" android:layout_height="50dp" android:background="@drawable/pre_ap" android:id="@+id/play_pre"/> <ImageButton android:layout_width="70dp" android:layout_height="70dp" android:layout_marginLeft="40dp" android:layout_marginRight="40dp" android:background="@drawable/pause_blue" android:id="@+id/play_btn"/> <ImageButton android:layout_width="50dp" android:layout_height="50dp" android:background="@drawable/next_ap" android:id="@+id/play_next"/> <ImageButton android:id="@+id/btn2" android:layout_width="31dp" android:layout_height="36dp" android:layout_marginLeft="8dp" android:background="@drawable/fenxiang" /> </LinearLayout> </LinearLayout>
4.学习中遇到的问题及解决
- 问题1:当导入mp3文件后,虚拟机中audio文件夹没有显示出来
- 问题1解决方案:经过查询得知,虽然通过Device Explorer能够将本机文件导入虚拟机,但需要将虚拟机❗重启❗才会正常显示在audio中,被播放器调用。同时,重启不是简单的开关虚拟机,这样只会暂停和回复虚拟机状态,一定要长按虚拟机控制栏电源按钮选择reboot。
- 问题2:程序演示当中没有显示歌曲的专辑作者等信息
- 问题2解决方案:此处错误不是程序上错误导致的,代码当中已经实现了对应信息的读取;此处问题是由于我没有下载正版的mp3文件,而是录屏后转成mp3格式文件,故缺失这些信息。
5.学习感悟和思考
- MusicPlayer 应用是一个功能完整、用户友好的音乐播放解决方案。它不仅提供了基本的音乐播放功能,还集成了用户账户管理,增强了应用的交互性和个性化体验。通过本次实践,我们深入理解了 Android 应用开发中的数据库操作、用户界面设计、后台服务管理以及多媒体播放控制等关键技术点。同时,我们也学习到了如何有效管理和维护项目资源,以及如何通过查阅资料和不断尝试来解决开发过程中遇到的问题。