一个简单的音乐播放器,画面做的比较简洁,适合初学者,其中使用sqlite创建数据库用于存储用户信息,同时还添加了用户信息显示功能,可查看用户信息。
Android Studio音乐播放器设计报告
姓名:阿三 学院:信息工程学院
专业:软件工程 学号:2111111111
任务起止日期:2023.12.27-2024.1.2
课程设计题目:基于Android Studio的音乐播放系统设计与实现
一、问题描述
音视频播放系统包括:使用sqlite创建数据库用于存储用户信息、启动效果、用户注册、用户登录、显示用户信息、音乐播放等功能。
二、功能描述
设计一个音乐播放器app,使之能够实现以下功能:
创建一个数据库用于存储用户信息。
启动效果:该App设计了启动页面,启动后倒计时3s后可进入app。
用户登录注册:该App提供用户登录和注册功能,用户可以创建新账户或使用现有账户登录。当用户注册完成后跳转回到登录页面进行用户登录。用户需要提供有效的用户名和密码进行身份验证。
显示用户信息:用户登录后可点击信息按钮查看用户信息,包括历史登录用户的用户信息。
音乐播放功能:用户登录后,可以通过该App浏览和播放音乐文件。App提供音乐列表,用户可以浏览并选择要播放的音乐。点击音乐后,将跳转到音乐播放页面,可进行音乐的播放、暂停、上一曲和下一曲以及拖动进度条来控制音乐播放。
三、功能实现
项目目录:
1.创建数据库,建立一个用户表,表结构如下:
2.实现app启动页面,页面效果如下:
3.实现用户登录功能,用户需要提供有效的用户名和密码,否侧提示用户名无效或密码无效:
4.实现用户注册功能,点击注册按钮跳转至用户注册页面,用户注册成功跳转回用户登录页面进行用户登录:
5.显示历史登录用户信息功能,登录成功后,点击信息后,跳转至用户信息显示界面,用户可查看历史登录用户信息。
6.实现音乐播放功能,登录成功后,显示音乐列表,点击音乐后,跳转至音乐播放界面,用户可通过点击播放按钮进行音乐的播放、暂停、上一曲和下一曲操作,同时用户也可以通过拖动进度条控制音乐的播放进度。
四、源代码
1.用户类定义User.java
package and.yjg.music_app.Login;
public class User {
public User() {
}
public User(String account, String password, String phone, String address) {
this.account = account;
this.password = password;
this.phone = phone;
this.address = address;
}
public String account;
public String password;
public String phone;
public String address;
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void setAddress(String address){
this.address = address;
}
public String toString () {
return "用户名:" + account + "
" +
"密码:" + password + "
" +
"电话:" + phone + "
" +
"地址:" + address + "
";
}
}
2.UserDao.java
package and.yjg.music_app.Login;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.util.Log;
import and.yjg.music_app.DataBaseHelper;
public class UserDao {
private Context context;
private DataBaseHelper dbHelper;
private SQLiteDatabase db;
public UserDao(Context context) {
this.context = context;
}
public void open() throws SQLiteException {
dbHelper = new DataBaseHelper(context);
try {
db = dbHelper.getWritableDatabase();
} catch (SQLiteException exception) {
db = dbHelper.getReadableDatabase();
}
}
public void close() {
if (db != null) {
db.close();
db = null;
}
}
public void addUser(User user) {
ContentValues values = new ContentValues();
values.put("account", user.account);
values.put("password", user.password);
values.put("phone", user.phone);
values.put("address", user.address);
db.insert("user", null, values);
}
public void deleteUser(User user) {
db.delete("user", "account = ?", new String[]{user.account});
}
public void update(User user) {
ContentValues values = new ContentValues();
values.put("password", user.password);
db.update("user", values, "account = ?", new String[]{user.account});
}
public boolean find(User user) {
Cursor cursor = db.query("user", null, "account = ?", new String[]{user.account}, null, null, null);
if (cursor == null || cursor.getCount() < 1) {
return false;
}
if (cursor.moveToFirst()) {
do {
String acc = cursor.getString(cursor.getColumnIndex("account"));
String pass = cursor.getString(cursor.getColumnIndex("password"));
String pho = cursor.getString(cursor.getColumnIndex("phone"));
String addr = cursor.getString(cursor.getColumnIndex("address"));
Log.d("UserDao", "user account is" + acc);
Log.d("UserDao", "user password is " + pass);
Log.d("UserDao", "user phone is " + pho);
Log.d("UserDao", "user address is " + addr);
} while (cursor.moveToNext());
}
cursor.close();
return true;
}
public boolean isExist(String account) {
Cursor cursor = db.query("user", null, "account = ?", new String[] {account}, null, null, null);
return cursor != null && cursor.getCount() > 0;
}
public String getPassword(String account) {
Cursor cursor = db.query("user", null, "account = ?", new String[] {account}, null, null, null);
cursor.moveToFirst();
String password = cursor.getString(cursor.getColumnIndex("password"));
return password;
}
3.启动效果WelcomeActivity.java
package and.yjg.music_app;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import Login.LoginActivity;
public class WelcomeActivity extends AppCompatActivity {
private TextView tvCountdown;
private CountDownTimer countDownTimer;
private long timeLeftInMillis = 3000;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
tvCountdown = findViewById(R.id.tv_countdown);
startCountdown();
}
private void startCountdown() {
countDownTimer = new CountDownTimer(timeLeftInMillis,1000){
public void onTick(long millisUntilFinished){
timeLeftInMillis = millisUntilFinished;
int secondsRemaining = (int) (millisUntilFinished/1000);
tvCountdown.setText(secondsRemaining+"s");
}
public void onFinish(){
startActivity(new Intent(WelcomeActivity.this, LoginActivity.class));
finish();
}
}.start();
}
protected void onDestroy(){
super.onDestroy();
if (countDownTimer != null){
countDownTimer.cancel();
}
}
}
4.用户登录LoginActivity.java
package Login;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import and.yjg.music_app.MainActivity;
import and.yjg.music_app.R;
public class LoginActivity extends AppCompatActivity {
private Button btn_login;
private Button btn_register;
private EditText et_account;
private EditText et_password;
private UserDao dao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initView();
}
public void initView() {
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.hide();
}
btn_login = findViewById(R.id.btn_login);
btn_register = findViewById(R.id.btn_register);
et_account = findViewById(R.id.et_account);
et_password = findViewById(R.id.et_password);
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String acc = et_account.getText().toString().trim();
String pass = et_password.getText().toString().trim();
dao = new UserDao(getApplicationContext());
dao.open();
if (dao.isExist(acc) == false) {
Toast.makeText(LoginActivity.this,"账号不存在,请重新输入!", Toast.LENGTH_SHORT).show();
} else {
if (dao.getPassword(acc).equals(pass)) {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
} else {
Toast.makeText(LoginActivity.this, "密码错误,请重新输入!", Toast.LENGTH_SHORT).show();
}
}
dao.close();
}
});
btn_register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
startActivityForResult(intent,1);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(data != null){
if(requestCode == 1 && resultCode == 1){
String name = data.getStringExtra("acc");
String password = data.getStringExtra("pass");
et_account.setText(name);
et_password.setText(password);
}
}
五、各类布局文件
activity_welcom.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".WelcomeActivity">
<TextView
android:id="@+id/tv_countdown"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="6dp"
android:layout_marginBottom="89dp"
android:background="@color/Blue"
android:gravity="center"
android:text="3s"
android:textSize="30dp" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@mipmap/action" />
</RelativeLayout>
activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/White"
android:orientation="vertical">
<ImageView
android:id='@+id/iv'
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="0dp"
android:background="@color/Black"/>
<LinearLayout
android:id="@+id/account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/iv"
android:layout_centerVertical="true"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="40dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="账 号"
android:textColor="#000"
android:background="@drawable/text_style"
android:textSize="25sp" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/Gray"/>
<EditText
android:id="@+id/et_account"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/edit_style"
android:hint="请输入账号"
android:textColor="@color/Gray"
android:textSize="20sp"
android:gravity="center"
android:inputType="text"
android:padding="10dp" />
</LinearLayout>
<LinearLayout
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/account"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="密 码"
android:background="@drawable/text_style"
android:textColor="#000"
android:textSize="25sp"/>
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/Gray"/>
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/tv_password"
android:hint="请输入密码"
android:textColor="@color/Gray"
android:textSize="20sp"
android:gravity="center"
android:background="@drawable/edit_style"
android:inputType="textPassword"
android:padding="10dp"/>
</LinearLayout>
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/button_style"
android:gravity="center"
android:text="登录"
android:textColor="#ffffff"
android:textSize="30sp"
android:layout_below="@+id/password"/>
<Button
android:id="@+id/btn_register"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@drawable/button_style"
android:gravity="center"
android:text="注册"
android:textColor="#ffffff"
android:textSize="30sp"
android:layout_below="@+id/btn_login" />
</RelativeLayout>
总结:在这次基于Android Studio的音视频播放系统设计与实现的课程设计中,我不仅掌握了一系列关键技术和工具,还对整个项目开发流程有了更深入的理解。:熟悉并掌握了Android Studio的开发环境,包括如何设置、配置项目,以及使用内置的工具如模拟器进行测试。深入了解了Android SDK和相关API,特别是与音视频播放相关的部分,如MediaPlayer、VideoView等。
此外,这次实验中,我还遇到一些数据传递中断问题,所以我还查看了一些使用断电调试的方法,也是得我掌握了一些关于断点调试的有关用法,这也让我意识到断点调试与良好的代码组织和注释习惯是相辅相成的。一个清晰、有良好注释的代码结构使得断点调试更为有效,因为你可以快速了解每一部分代码的作用和相互关系。
通过这次课程设计,我不仅提高了技术能力,更重要的是学会了如何综合运用这些技术来解决实际问题。
由于篇幅限制,这里只有部分代码,有需要完整代码的小伙伴可以私信我,找我要项目源码。
另外,在另一篇文章中在这个项目的基础上增加了视频播放功能,实现了音频视频播放,有需要的链接奉上:Android Studio音频视频播放器课程设计-CSDN博客