Android Studio 实现音乐播放器

这篇具有很好参考价值的文章主要介绍了Android Studio 实现音乐播放器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🍅文章末尾有获取完整项目源码方式🍅

一、引言

        Android初学者开发第一个完整的实例项目应该就属《音乐播放器》了,项目包含SQLlit数据库的使用、listview、Fragment、等。话不多说先上成品:

视频效果展示:

Android Studio 音乐播放器

图片效果展示:

1.启动页效果

androidstudio音乐播放器,android studio,android,ide

2.登录页效果

androidstudio音乐播放器,android studio,android,ide

3.注册页效果

androidstudio音乐播放器,android studio,android,ide

4.歌曲列表页效果

androidstudio音乐播放器,android studio,android,ide

5.播放页效果

androidstudio音乐播放器,android studio,android,ide

 二、详细设计

1.登陆注册功能

        用户进行注册数据使用SQLite存储,用户登录时根据数据库的内容来核对用户名和密码是否正确。

androidstudio音乐播放器,android studio,android,ideandroidstudio音乐播放器,android studio,android,ide

 Login.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="#f9d7e7"
    tools:context=".Login.LoginActivity">

    <ImageView
        android:id="@+id/imageView3"
        android:layout_width="200dp"
        android:layout_height="150dp"
        android:layout_marginTop="24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/logo1" />

    <View
        android:id="@+id/view2"
        android:layout_width="0dp"
        android:layout_height="320dp"
        android:layout_marginTop="24dp"
        android:background="@drawable/login_view"
        app:layout_constraintEnd_toStartOf="@+id/guideline2"
        app:layout_constraintStart_toStartOf="@+id/guideline3"
        app:layout_constraintTop_toBottomOf="@+id/imageView3" />

    <Button
        android:id="@+id/login_button"
        android:layout_width="250dp"
        android:layout_height="55dp"
        android:layout_marginBottom="32dp"
        android:background="@drawable/login"
        android:text="立 即 登 录 "
        android:textColor="#fff"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="@+id/view2"
        app:layout_constraintEnd_toStartOf="@+id/guideline2"
        app:layout_constraintStart_toStartOf="@+id/view2" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.9" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.1" />

    <View
        android:id="@+id/view3"
        android:layout_width="0dp"
        android:layout_height="45dp"
        android:layout_marginTop="40dp"
        android:background="@drawable/login_count"
        app:layout_constraintEnd_toEndOf="@+id/login_button"
        app:layout_constraintStart_toStartOf="@+id/login_button"
        app:layout_constraintTop_toTopOf="@+id/view2" />

    <View
        android:id="@+id/view4"
        android:layout_width="0dp"
        android:layout_height="45dp"
        android:layout_marginTop="24dp"
        android:background="@drawable/login_count"
        app:layout_constraintEnd_toEndOf="@+id/login_button"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="@+id/login_button"
        app:layout_constraintTop_toBottomOf="@+id/view3" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="忘 记 密 码"
        app:layout_constraintStart_toStartOf="@+id/view4"
        app:layout_constraintTop_toBottomOf="@+id/view4" />

    <TextView
        android:id="@+id/login_register"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="立 即 注 册"
        app:layout_constraintBottom_toBottomOf="@+id/textView"
        app:layout_constraintEnd_toEndOf="@+id/view4"
        app:layout_constraintTop_toTopOf="@+id/textView" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="20dp"
        android:layout_height="20dp"
        app:layout_constraintBottom_toBottomOf="@+id/view4"
        app:layout_constraintEnd_toEndOf="@+id/imageView4"
        app:layout_constraintTop_toTopOf="@+id/view4"
        app:srcCompat="@drawable/mima" />

    <ImageView
        android:id="@+id/imageView4"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_marginStart="16dp"
        app:layout_constraintBottom_toBottomOf="@+id/view3"
        app:layout_constraintStart_toStartOf="@+id/view3"
        app:layout_constraintTop_toTopOf="@+id/view3"
        app:srcCompat="@drawable/zhanghao" />

    <View
        android:id="@+id/view5"
        android:layout_width="100dp"
        android:layout_height="1dp"
        android:layout_marginTop="40dp"
        android:background="#fff"
        app:layout_constraintStart_toStartOf="@+id/guideline3"
        app:layout_constraintTop_toBottomOf="@+id/view2" />

    <View
        android:id="@+id/view6"
        android:layout_width="100dp"
        android:layout_height="1dp"
        android:background="#fff"
        app:layout_constraintEnd_toStartOf="@+id/guideline2"
        app:layout_constraintTop_toTopOf="@+id/view5" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="其它方式登陆"
        android:textColor="#fff"
        app:layout_constraintBottom_toBottomOf="@+id/view5"
        app:layout_constraintEnd_toStartOf="@+id/view6"
        app:layout_constraintStart_toEndOf="@+id/view5"
        app:layout_constraintTop_toTopOf="@+id/view5" />

    <ImageView
        android:id="@+id/imageView6"
        android:layout_width="30dp"
        android:layout_height="30dp"
        app:layout_constraintBottom_toBottomOf="@+id/imageView5"
        app:layout_constraintEnd_toStartOf="@+id/imageView7"
        app:layout_constraintStart_toEndOf="@+id/imageView5"
        app:layout_constraintTop_toTopOf="@+id/imageView5"
        app:srcCompat="@drawable/qq" />

    <ImageView
        android:id="@+id/imageView5"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginStart="70dp"
        android:layout_marginTop="24dp"
        app:layout_constraintStart_toStartOf="@+id/guideline3"
        app:layout_constraintTop_toBottomOf="@+id/view5"
        app:srcCompat="@drawable/weixin" />

    <ImageView
        android:id="@+id/imageView7"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginEnd="70dp"
        app:layout_constraintBottom_toBottomOf="@+id/imageView6"
        app:layout_constraintEnd_toStartOf="@+id/guideline2"
        app:layout_constraintTop_toTopOf="@+id/imageView6"
        app:srcCompat="@drawable/weibo" />

    <EditText
        android:id="@+id/user"
        android:layout_width="190dp"
        android:layout_height="0dp"
        android:layout_marginStart="5dp"
        android:ems="10"
        android:background="#eff4f2"
        android:inputType="textPersonName"
        android:hint="请输入账号"
        app:layout_constraintBottom_toBottomOf="@+id/view3"
        app:layout_constraintStart_toEndOf="@+id/imageView4"
        app:layout_constraintTop_toTopOf="@+id/view3" />

    <EditText
        android:id="@+id/pass"
        android:layout_width="190dp"
        android:layout_height="0dp"
        android:layout_marginStart="5dp"
        android:ems="10"
        android:background="#eff4f2"
        android:inputType="textPassword"
        android:hint="请输入密码"
        app:layout_constraintBottom_toBottomOf="@+id/view4"
        app:layout_constraintStart_toEndOf="@+id/imageView"
        app:layout_constraintTop_toTopOf="@+id/view4"
        app:layout_constraintVertical_bias="0.0" />

</androidx.constraintlayout.widget.ConstraintLayout>

Register.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="#f9d7e7"
    tools:context=".Register.RegisterActivity">

    <ImageView
        android:id="@+id/imageView3"
        android:layout_width="200dp"
        android:layout_height="150dp"
        android:layout_marginTop="40dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/logo1" />

    <View
        android:id="@+id/view2"
        android:layout_width="0dp"
        android:layout_height="270dp"
        android:background="@drawable/login_view"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/guideline4"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="@+id/imageView3"
        app:layout_constraintVertical_bias="0.501" />

    <View
        android:id="@+id/view3"
        android:layout_width="250dp"
        android:layout_height="45dp"
        android:layout_marginTop="32dp"
        android:background="@drawable/login_count"
        app:layout_constraintEnd_toStartOf="@+id/guideline4"
        app:layout_constraintStart_toStartOf="@+id/view2"
        app:layout_constraintTop_toTopOf="@+id/view2" />

    <View
        android:id="@+id/view4"
        android:layout_width="0dp"
        android:layout_height="45dp"
        android:layout_marginTop="32dp"
        android:background="@drawable/login_count"
        app:layout_constraintEnd_toEndOf="@+id/view3"
        app:layout_constraintStart_toStartOf="@+id/view3"
        app:layout_constraintTop_toBottomOf="@+id/view3" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.1" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.9" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_marginStart="8dp"
        app:layout_constraintBottom_toBottomOf="@+id/view3"
        app:layout_constraintStart_toStartOf="@+id/view3"
        app:layout_constraintTop_toTopOf="@+id/view3"
        app:srcCompat="@drawable/mima" />

    <ImageView
        android:id="@+id/imageView4"
        android:layout_width="20dp"
        android:layout_height="20dp"
        app:layout_constraintBottom_toBottomOf="@+id/view4"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        app:layout_constraintTop_toTopOf="@+id/view4"
        app:srcCompat="@drawable/zhanghao" />

    <Button
        android:id="@+id/register_button"
        android:layout_width="250dp"
        android:layout_height="55dp"
        android:text="立 即 注 册"
        android:layout_marginBottom="32dp"
        android:background="@drawable/login"
        app:layout_constraintBottom_toBottomOf="@+id/view2"
        app:layout_constraintEnd_toEndOf="@+id/view2"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="@+id/view2" />

    <EditText
        android:id="@+id/username_edittext"
        android:layout_width="190dp"
        android:layout_height="0dp"
        android:layout_marginStart="5dp"
        android:ems="10"
        android:hint="请输入账号"
        android:background="#eff4f2"
        android:inputType="textPersonName"
        app:layout_constraintBottom_toBottomOf="@+id/view3"
        app:layout_constraintStart_toEndOf="@+id/imageView"
        app:layout_constraintTop_toTopOf="@+id/view3" />

    <EditText
        android:id="@+id/password_edittext"
        android:layout_width="190dp"
        android:layout_height="0dp"
        android:layout_marginStart="5dp"
        android:ems="10"
        android:hint="请输入密码"
        android:background="#eff4f2"
        android:inputType="textPassword"
        app:layout_constraintBottom_toBottomOf="@+id/view4"
        app:layout_constraintStart_toEndOf="@+id/imageView4"
        app:layout_constraintTop_toTopOf="@+id/view4" />

</androidx.constraintlayout.widget.ConstraintLayout>

LoginActivity完整代码:

package com.example.music.Login;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.music.MainActivity;
import com.example.music.R;
import com.example.music.Register.RegisterActivity;
import com.example.music.Data.DatabaseHelper;

public class LoginActivity extends AppCompatActivity {
    private TextView loginRegister;
    private EditText user;
    private EditText pass;
    private Button mLoginButton;
    private DatabaseHelper mDatabaseHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        user = findViewById(R.id.user);
        pass = findViewById(R.id.pass);
        mLoginButton = findViewById(R.id.login_button);
        loginRegister = findViewById(R.id.login_register);
        mDatabaseHelper = new DatabaseHelper(this);
        loginRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
                startActivity(intent);
            }
        });
        mLoginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String username = user.getText().toString().trim();
                String password = pass.getText().toString().trim();

                if (username.isEmpty() || password.isEmpty()) {
                    Toast.makeText(getApplicationContext(), "请输入账号或密码", Toast.LENGTH_SHORT).show();
                    return;
                }

                boolean result = mDatabaseHelper.checkUser(username, password);
                if (result) {
                    Toast.makeText(getApplicationContext(), "登陆成功", Toast.LENGTH_SHORT).show();
                    Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                    startActivity(intent);
                } else {
                    Toast.makeText(getApplicationContext(), "账号或密码错误", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

RegisterActivity完整代码:

package com.example.music.Register;

import androidx.appcompat.app.AppCompatActivity;

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 com.example.music.Login.LoginActivity;
import com.example.music.R;
import com.example.music.Data.DatabaseHelper;

public class RegisterActivity extends AppCompatActivity {
    private EditText mUserNameEditText;
    private EditText mPasswordEditText;
    private Button registerButton;
    private DatabaseHelper mDatabaseHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        mUserNameEditText = findViewById(R.id.username_edittext);
        mPasswordEditText = findViewById(R.id.password_edittext);
        registerButton = findViewById(R.id.register_button);
        mDatabaseHelper = new DatabaseHelper(this);
        registerButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String username = mUserNameEditText.getText().toString().trim();
                String password = mPasswordEditText.getText().toString().trim();

                if (username.isEmpty() || password.isEmpty()) {
                    Toast.makeText(getApplicationContext(), "请输入账号或密码", Toast.LENGTH_SHORT).show();
                    return;
                }
                boolean result = mDatabaseHelper.insertData(username, password);
                if (result) {
                    Toast.makeText(getApplicationContext(), "注册成功", Toast.LENGTH_SHORT).show();
                    Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);
                    startActivity(intent);
                    finish();
                } else {
                    Toast.makeText(getApplicationContext(), "注册失败", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

2.音乐列表页面

         主要用于音乐的显示以及点击对应的音乐跳转到对应的音乐播放页面。

androidstudio音乐播放器,android studio,android,ide

 Activity完整代码:

package com.example.music;

import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import androidx.fragment.app.Fragment;

import com.example.music.Music.MusicActivity;


public class SongPage extends Fragment {
    //声明视图变量view
    private View view;
    //在这里添加歌曲名
    public String[] songname = {"Innocence", "刚刚好","不用去猜"};
    private String[] name={"A R L","薛之谦","Jony J"};
    //在这里添加歌曲图片
    public static int[] icons = {R.drawable.img_01, R.drawable.img_02, R.drawable.img_03};

    @Override
    public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.music_list, null);
        //1、创建并绑定列表
        ListView listView = view.findViewById(R.id.lv);
        //2、创建适配器对象
        MyBaseAdapter adapter = new MyBaseAdapter();
        //3、给列表设置适配器
        listView.setAdapter(adapter);
        //设置列表条目监听器
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //创建Intent对象,启动音乐播放界面
                Intent intent = new Intent(SongPage.this.getContext(), MusicActivity.class);
                //将数据存入Intent对象,利用键值对
                intent.putExtra("name", name[position]);
                intent.putExtra("songname", songname[position]);
                intent.putExtra("position", String.valueOf(position));
                //开启意图,进行跳转
                startActivity(intent);
            }
        });
        return view;
    }

    class MyBaseAdapter extends BaseAdapter {
        @Override
        public int getCount() {
            return name.length;
        }

        @Override
        public Object getItem(int i) {
            return name[i];
        }

        @Override
        public long getItemId(int i) {
            return i;
        }

        @Override
        public View getView(int i, View convertView, ViewGroup parent) {
            //绑定视图,并且显示歌曲名和歌曲图片
            View view = View.inflate(SongPage.this.getContext(), R.layout.item_music, null);
            TextView songName = view.findViewById(R.id.song_name);
            ImageView songPic = view.findViewById(R.id.song_pic);
            TextView name1=view.findViewById(R.id.name);
            songName.setText(songname[i]);
            name1.setText(name[i]);

            songPic.setImageResource(icons[i]);
            return view;
        }
    }


}

相关的xml代码:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="wrap_content"
    android:padding="15dp">

    <ImageView
        android:id="@+id/song_pic"
        android:layout_width="86dp"
        android:layout_height="86dp"
        android:src="@drawable/img_01"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/song_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:text="歌曲"
        android:textColor="#000"
        android:textSize="20sp"
        app:layout_constraintStart_toEndOf="@+id/song_pic"
        app:layout_constraintTop_toTopOf="@+id/song_pic" />

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="歌曲"
        android:textColor="#000"
        android:textSize="14sp"
        app:layout_constraintStart_toStartOf="@+id/song_name"
        app:layout_constraintTop_toBottomOf="@+id/song_name" />

    <ImageView
        android:id="@+id/song_enter"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginEnd="8dp"
        android:src="@drawable/song_play"
        app:layout_constraintBottom_toBottomOf="@+id/song_pic"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@+id/song_pic" />

</androidx.constraintlayout.widget.ConstraintLayout>

2.音乐播放功能

       用于播放音乐,对音乐进行暂停,上一首、下一首功能的实现。

androidstudio音乐播放器,android studio,android,ide

        该类是一个音乐播放器的活动,包含了播放、暂停、继续播放、上一首、下一首、退出等功能。以下是该类的一些关键点:

成员变量:

musicName:存储歌曲名称的字符串数组。
sb:进度条 SeekBar 对象。
tv_progress、tv_total、name_song:显示播放进度、总时长和歌曲名的 TextView 对象。
animator:旋转动画对象,用于旋转歌手图片框。
musicControl:音乐控制类的对象。
初始化方法 initView():

初始化各个控件,并设置点击事件监听器。
创建意图对象 intent2,并创建 MyServiceConn 服务连接对象 conn。
绑定服务,将音乐控制类的对象 musicControl 与服务绑定。
消息处理器 handler:

用于在主线程中处理从子线程发送过来的消息。
处理音乐播放进度的更新,通过更新进度条和显示当前播放时长和总时长。
服务连接类 MyServiceConn:

实现 ServiceConnection 接口,用于连接服务。
在 onServiceConnected() 方法中获取音乐控制类的对象。
在 onServiceDisconnected() 方法中处理服务断开连接的情况。
onClick() 方法:

        处理按钮的点击事件,根据点击的按钮执行相应的操作,如播放、暂停、继续播放、上一首、下一首、退出等。
在点击播放按钮时,隐藏播放按钮,开始播放音乐,并启动旋转动画。
在点击暂停按钮时,隐藏暂停按钮,显示继续播放按钮,并暂停音乐播放和旋转动画。
在点击继续播放按钮时,隐藏继续播放按钮,显示暂停按钮,并继续音乐播放和旋转动画。
在点击上一首按钮时,切换到上一首歌曲,并更新歌手图片和歌曲名。
在点击下一首按钮时,切换到下一首歌曲,并更新歌手图片和歌曲名。
在点击退出按钮时,解除服务绑定并关闭活动。
onDestroy() 方法:

在活动销毁时解除服务绑定。

 具体MusicActivity代码:

public class MusicActivity extends AppCompatActivity implements View.OnClickListener{
    //定义歌曲名称的数组
    public String[] musicName={"Innocence", "刚刚好","不用去猜"};
    private static SeekBar sb;//定义进度条
    private static TextView tv_progress, tv_total, name_song;//定义开始和总时长,歌曲名控件
    private ObjectAnimator animator;//定义旋转的动画
    private MusicService.MusicControl musicControl;//音乐控制类

    private Button play;        //播放按钮
    private Button pause;       //暂停按钮
    private Button con;         //继续播放按钮
    private Button pre;         //上一首按钮
    private Button next;        //下一首按钮
    private ImageView exit;        //退出按钮
    private ImageView iv_music; //歌手图片框

    Intent intent1, intent2;    //定义两个意图
    MyServiceConn conn;         //服务连接
    private boolean isUnbind = false;//记录服务是否被解绑
    public int change = 0;      //记录下标的变化值
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_music);
        //去除标题栏
        ActionBar actionBar = getSupportActionBar();
        if(actionBar!= null){
            actionBar.hide();
        }
        //获得意图
        intent1 = getIntent();
        //初始化
        initView();
    }
    //初始化
    private void initView(){
        //依次绑定控件
        tv_progress = findViewById(R.id.tv_progress);
        tv_total = findViewById(R.id.tv_total);
        sb = findViewById(R.id.sb);
        name_song = findViewById(R.id.song_name);
        iv_music = findViewById(R.id.iv_music);

        play = findViewById(R.id.btn_play);
        pause = findViewById(R.id.btn_pause);
        con = findViewById(R.id.btn_continue_play);
        pre = findViewById(R.id.btn_pre);
        next = findViewById(R.id.btn_next);
        exit = findViewById(R.id.btn_exit);

        //依次设置监听器
        play.setOnClickListener(this);
        pause.setOnClickListener(this);
        con.setOnClickListener(this);
        pre.setOnClickListener(this);
        next.setOnClickListener(this);
        exit.setOnClickListener(this);

        //创建意图对象
        intent2 = new Intent(this, MusicService.class);
        conn = new MyServiceConn();//创建服务连接对象
        bindService(intent2, conn,BIND_AUTO_CREATE);//绑定服务

        //从歌曲列表传过来的歌曲名
        String name = intent1.getStringExtra("songname");
        //设置歌曲名显示
        name_song.setText(name);
        //定义歌曲列表传过来的下标position
        String position = intent1.getStringExtra("position");
        //将字符串转化为整型i
        int i = parseInt(position);
        //图像框设置为frag1里面的图标数组,下标为i
        iv_music.setImageResource(SongPage.icons[i]);
        //为滑动条添加事件监听
        sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @RequiresApi(api = Build.VERSION_CODES.KITKAT)
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                //当滑动条到末端时,将message对象发送出去
                if (progress == sb.getMax()){
                }
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {//滑动条开始滑动时调用
            }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {//滑动条停止滑动时调用
                //根据拖动的进度改变音乐播放进度
                int progress = seekBar.getProgress();//获取seekBar的进度
                musicControl.seekTo(progress);//改变播放进度
            }
        });

        animator= ObjectAnimator.ofFloat(iv_music,"rotation",0f,360.0f);
        animator.setDuration(10000);//动画旋转一周的时间为10秒
        animator.setInterpolator(new LinearInterpolator());//匀速
        animator.setRepeatCount(-1);//-1表示设置动画无限循环

    }
    //歌曲进度条的消息机制
    public static Handler handler = new Handler(){//创建消息处理器对象
        //在主线程中处理从子线程发送过来的消息
        @Override
        public void handleMessage(Message msg){
            Bundle bundle = msg.getData();//获取从子线程发送过来的音乐播放进度
            int duration = bundle.getInt("duration");
            int currentPosition = bundle.getInt("currentPosition");
            sb.setMax(duration);
            sb.setProgress(currentPosition);
            //歌曲总时长,单位为毫秒
            int minute = duration/1000/60;
            int second = duration/1000%60;
            String strMinute = null;
            String strSecond = null;
            if(minute < 10){//如果歌曲的时间中的分钟小于10
                strMinute = "0" + minute;//在分钟的前面加一个0
            }else{
                strMinute = minute + "";
            }
            if (second < 10){//如果歌曲中的秒钟小于10
                strSecond = "0" + second;//在秒钟前面加一个0
            }else{
                strSecond = second + "";
            }
            tv_total.setText(strMinute + ":" + strSecond);
            //歌曲当前播放时长
            minute = currentPosition/1000/60;
            second = currentPosition/1000%60;
            if(minute < 10){//如果歌曲的时间中的分钟小于10
                strMinute = "0" + minute;//在分钟的前面加一个0
            }else{
                strMinute=minute + " ";
            }
            if (second < 10){//如果歌曲中的秒钟小于10
                strSecond = "0" + second;//在秒钟前面加一个0
            }else{
                strSecond = second + " ";
            }
            tv_progress.setText(strMinute + ":" + strSecond);
        }
    };
    //用于实现连接服务
    class MyServiceConn implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service){
            musicControl=(MusicService.MusicControl) service;
        }
        @Override
        public void onServiceDisconnected(ComponentName name){

        }
    }
    //未解绑则解绑
    private void unbind(boolean isUnbind){
        if(!isUnbind){//判断服务是否被解绑
            musicControl.pausePlay();//暂停播放音乐
            unbindService(conn);//解绑服务
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public void onClick(View v) {
        //获取歌曲名的下标字符串
        String index = intent1.getStringExtra("position");
        //将字符串转为整数
        int i = parseInt(index);

        switch (v.getId()){

            case R.id.btn_play://播放按钮点击事件
                play.setVisibility(View.INVISIBLE);
                musicControl.play(i);
                animator.start();
                break;

            //这里musicName.length-1表示的最后一首歌的下标,即歌曲总数-1
            case R.id.btn_pre://播放上一首
                if((i + change) < 1) {
                    change = musicName.length - 1 - i;
                    iv_music.setImageResource(SongPage.icons[i + change]);
                    name_song.setText(musicName[i + change]);
                    musicControl.play(i + change);
                    pause.setVisibility(View.VISIBLE);
                    animator.start();
                    break;
                } else {
                    change--;
                    iv_music.setImageResource(SongPage.icons[i + change]);
                    name_song.setText(musicName[i + change]);
                    musicControl.play(i + change);
                    pause.setVisibility(View.VISIBLE);
                    animator.start();
                    break;
                }

            case R.id.btn_next://播放下一首
                if((i + change) == musicName.length - 1) {
                    change = -i;
                    iv_music.setImageResource(SongPage.icons[i + change]);
                    name_song.setText(musicName[i + change]);
                    musicControl.play(i + change);
                    pause.setVisibility(View.VISIBLE);
                    animator.start();
                    break;
                } else {
                    change++;
                    iv_music.setImageResource(SongPage.icons[i + change]);
                    name_song.setText(musicName[i + change]);
                    musicControl.play(i + change);
                    pause.setVisibility(View.VISIBLE);
                    animator.start();
                    break;
                }

            case R.id.btn_pause://暂停按钮点击事件
                pause.setVisibility(View.INVISIBLE);
                con.setVisibility(View.VISIBLE);
                musicControl.pausePlay();
                animator.pause();
                break;

            case R.id.btn_continue_play://继续播放按钮点击事件
                con.setVisibility(View.INVISIBLE);
                pause.setVisibility(View.VISIBLE);
                musicControl.continuePlay();
                animator.start();
                break;

            case R.id.btn_exit://退出按钮点击事件
                unbind(isUnbind);
                isUnbind = true;
                finish();
                break;
        }
    }
    @Override
    protected void onDestroy(){
        super.onDestroy();
        unbind(isUnbind);//解绑服务
    }
}

相关的xml文件代码:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="#f9d7e7"
    android:orientation="vertical"
    tools:context=".Music.MusicActivity">

    <ImageView
        android:id="@+id/btn_exit"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="24dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/back" />

    <TextView
        android:id="@+id/song_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="光年之外"
        android:textColor="#000"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="@+id/btn_exit"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/btn_exit" />

    <ImageView
        android:id="@+id/iv_music"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:layout_marginTop="80dp"
        android:src="@drawable/img_01"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_exit" />

    <SeekBar
        android:id="@+id/sb"
        android:layout_width="250dp"
        android:layout_height="20dp"
        android:layout_marginTop="80dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/iv_music" />

    <TextView
        android:id="@+id/tv_progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="5dp"
        android:text="00:00"
        app:layout_constraintBottom_toBottomOf="@+id/sb"
        app:layout_constraintEnd_toStartOf="@+id/sb"
        app:layout_constraintTop_toTopOf="@+id/sb" />

    <TextView
        android:id="@+id/tv_total"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="5dp"
        android:text="00:00"
        app:layout_constraintBottom_toBottomOf="@+id/sb"
        app:layout_constraintStart_toEndOf="@+id/sb"
        app:layout_constraintTop_toTopOf="@+id/sb" />

    <Button
        android:id="@+id/btn_continue_play"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="@drawable/play"
        app:layout_constraintBottom_toBottomOf="@+id/btn_pre"
        app:layout_constraintEnd_toStartOf="@+id/btn_next"
        app:layout_constraintStart_toEndOf="@+id/btn_pre"
        app:layout_constraintTop_toTopOf="@+id/btn_pre" />

    <Button
        android:id="@+id/btn_pause"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="@drawable/pause"
        app:layout_constraintBottom_toBottomOf="@+id/btn_next"
        app:layout_constraintEnd_toStartOf="@+id/btn_next"
        app:layout_constraintStart_toEndOf="@+id/btn_pre"
        app:layout_constraintTop_toTopOf="@+id/btn_next" />

    <Button
        android:id="@+id/btn_pre"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginStart="24dp"
        android:background="@drawable/pre"
        app:layout_constraintBottom_toBottomOf="@+id/btn_next"
        app:layout_constraintStart_toStartOf="@+id/tv_progress"
        app:layout_constraintTop_toTopOf="@+id/btn_next" />

    <Button
        android:id="@+id/btn_next"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginTop="100dp"
        android:layout_marginEnd="24dp"
        android:background="@drawable/next"
        app:layout_constraintEnd_toEndOf="@+id/tv_total"
        app:layout_constraintTop_toBottomOf="@+id/tv_total" />

    <Button
        android:id="@+id/btn_play"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:background="@drawable/play"
        app:layout_constraintBottom_toBottomOf="@+id/btn_pre"
        app:layout_constraintEnd_toStartOf="@+id/btn_next"
        app:layout_constraintStart_toEndOf="@+id/btn_pre"
        app:layout_constraintTop_toTopOf="@+id/btn_pre" />


</androidx.constraintlayout.widget.ConstraintLayout>

三、获取源码

关注公众号《编程乐学》,后台回复:23031701

👇​​​​​​​👇​​​​​​​👇​​​​​​​快捷获取方式👇👇👇文章来源地址https://www.toymoban.com/news/detail-739372.html

到了这里,关于Android Studio 实现音乐播放器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android开发之音乐播放器

    我们大家平时长时间打代码的时候肯定会感到疲惫和乏味,这个时候一边播放自己喜欢的音乐,一边继续打代码,心情自然也愉快很多。音乐带给人的听觉享受是无可比拟的,动听的音乐可以愉悦人的身心,让人更加积极地去热爱生活。接下来就教大家如何用Android Studio自己

    2024年02月08日
    浏览(35)
  • 零基础用Android Studio实现简单的本地视频播放器

    本文将讲解如何使用Android视频播放器VideoView组件来播放本地视频和网络视频,实现起来还是比较简单的。VideoView组件的作用与ImageView类似,只是ImageView用于显示图片,VideoView用于播放视频。 (本文章的代码参考: https://www.jb51.net/article/122051.htm) 实现效果: 用Android Studio做的

    2024年02月02日
    浏览(51)
  • 基于android音乐播放器的设计

    本科毕业论文(设计)诚信声明 本人郑重声明:所呈交的毕业论文(设计),题目《………基于android音乐播放器的设计……………………………》是本人在指导教师的指导下,进行研究工作所取得的成果。对本文的研究作出重要贡献的个人和集体,均已在文章以明确方式注

    2024年02月03日
    浏览(34)
  • Android课程设计大作业-音乐播放器

    1)使用Service播放音乐 Android SDK提供了Service。Service有两种类型: 本地服务(Local Service):用于应用程序内部 远程服务(Remote Sercie):用于Android系统内部的应用程序之间前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单

    2024年02月10日
    浏览(32)
  • 小项目开发——Android 音乐播放器

    ◼ 音乐播放器 . ◼ 要求 : Activity 编程、 ListView 编程、 SeekBar 编程、 ExoPlayer 编程( 播放 、 暂停 、 停止 、 上一首 、 下一首 ),音乐文件放在 assets/music 目录下,界面自拟. ◼ 期望最终效果: ◼ 分别对应 activity_music_list.xml 、 activity_my_music_player.xml 的视图. ◼ 点击列表任

    2024年01月21日
    浏览(32)
  • Android手机开发课程设计之音乐播放器

    一、音乐播放器概述与分析 目前手机的音乐播放功能已经是大家比较关注的一个部分,不少在人在购买手机的时候都会关心手机的音乐播放的能力,这也足以看出目前大家对音乐播放功能的重视,所以一款性能良好的手机音乐播放器软件一定会受到欢迎。和传统的音乐播放器

    2024年02月05日
    浏览(40)
  • Qt实现本地音乐播放器

     mainwindow.h mainwindow.cpp qss: 源码:Qt与学习通页面: 记录与Qt相关的代码 - Gitee.com

    2024年02月12日
    浏览(32)
  • Python轻松实现音乐播放器

    来个新玩意就是教大家如何用python来制作一个音乐播放器 希望对大家有所帮助哈哈 你们也可以尝试自己做做 先给你们展示展示最简单的,只需要九行代码 知识点和所需模块 python基础知识 requests库 time pygame tkinter 线程 环境 windows pycharm 2021.2 python 3.8 ok,直接说上完整代码 !

    2024年02月11日
    浏览(40)
  • Android Studio——简单视频播放器

            三个界面:主界面,视频列表界面,视频播放界面,如下图所示:         (1)主界面设计            很简单,就一个背景和一个控件,然后为控件设置点击事件,然后跳转到视频列表界面    activity_main.xml界面  MainActivity.java类           (2)视频列表界面

    2024年02月07日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包