服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android开发简易音乐播放器

Android开发简易音乐播放器

2022-11-13 14:53无落 Android

这篇文章主要为大家详细介绍了Android开发简易音乐播放器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

这里介绍一个简易的音乐播放器,供大家参考,具体内容如下

效果图如下:

Android开发简易音乐播放器

但是,由于这是一个简易版的音乐播放器,所播放的音乐只有一首,且被写死,但,操作却十分简单,方便理解!

这是代码的主要设计:

Android开发简易音乐播放器

音乐主要存放在这一个文件中:

Android开发简易音乐播放器

下面就来介绍各部分代码:

activity—main。xml:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<?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:id="@+id/activity_main"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="#696969">
 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="60dp"
 android:layout_marginTop="10dp"
 android:layout_alignParentTop="true"
 android:id="@+id/title"
 android:orientation="horizontal">
 <TextView
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_marginTop="15dp"
  android:layout_marginBottom="3dp"
  android:text="生僻字"
  android:textSize="25dp"
  android:gravity="center"
  android:textColor="#ffffff"/>
 </LinearLayout>
 <TextView
 android:layout_width="match_parent"
 android:layout_height="0.5dp"
 android:background="#afafaf"
 android:layout_below="@+id/title"/>
 <ImageView
 android:id="@+id/disc"
 android:layout_width="280dp"
 android:layout_height="280dp"
 android:layout_centerHorizontal="true"
 android:layout_below="@+id/title"
 android:layout_marginTop="50dp"
 android:src="@drawable/xcvb" />
 <ImageView
 android:id="@+id/needle"
 android:layout_width="120dp"
 android:layout_height="120dp"
 android:layout_below="@+id/title"
 
 android:layout_marginLeft="150dp"/>
 
 <RelativeLayout
 android:id="@+id/music1"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:layout_above="@+id/rl"
 android:layout_marginTop="20dp"
 android:layout_marginBottom="10dp"
 android:gravity="center">
 <SeekBar
  android:id="@+id/music_seek_bar"
  android:layout_width="240dp"
  android:layout_height="wrap_content"/>
 <TextSwitcher
  android:id="@+id/text_switcher"
  android:layout_width="80dp"
  android:layout_height="50dp"
  android:layout_toRightOf="@+id/music_seek_bar">
  <TextView
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:text="00:00/2:00"
  android:textColor="@color/colorAccent"/>
 </TextSwitcher>
 </RelativeLayout>
 
 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="70dp"
 android:gravity="center"
 android:id="@+id/rl"
 android:layout_marginBottom="20dp"
 android:layout_alignParentBottom="true"
 android:orientation="horizontal">
 
 <ImageView
  android:id="@+id/playing_pre"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center_vertical"
  android:src="@drawable/music_previous" />
 
 <ImageView
  android:id="@+id/playing_play"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center_vertical"
  android:src="@drawable/music_play" />
 
 <ImageView
  android:id="@+id/playing_next"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center_vertical"
  android:src="@drawable/music_next" />
 </LinearLayout>
</RelativeLayout>

main。activity部分:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
package com.example.cungu.musicdemo;
 
 
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextSwitcher;
 
import java.text.SimpleDateFormat;
import java.util.Date;
 
 
public class MainActivity extends AppCompatActivity implements View.OnClickListener,
 Runnable, ServiceConnection, SeekBar.OnSeekBarChangeListener {
 private ImageView disc,needle,playingPre,playingPlay,playingNext;
 private ObjectAnimator discAnimation,needleAnimation;//自定义指针和唱盘
 private boolean isPlaying = true;//0,1 判断是否处于播放状态
 
 //声明服务
 private static final String TAG = MainActivity.class.getSimpleName();
 private MediaService.MusicController mMusicController;
 //使用方法:mMusicController.play();播放 mMusicController.pause();暂停
 private boolean running;
 private TextSwitcher mSwitcher;
 private SeekBar mSeekBar;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 //设置透明栏
 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  Window window = getWindow();
  window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
   | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
  window.getDecorView().setSystemUiVisibility(
   View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
  );
  window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
  window.setStatusBarColor(Color.TRANSPARENT);
 }
 //滑动条部分
 mSeekBar = (SeekBar) findViewById(R.id.music_seek_bar);
 mSeekBar.setOnSeekBarChangeListener(this);
 mSwitcher = (TextSwitcher) findViewById(R.id.text_switcher);
 mSwitcher.setInAnimation(this, android.R.anim.fade_in);
 mSwitcher.setOutAnimation(this, android.R.anim.fade_out);
 Intent intent = new Intent(this, MediaService.class);
 //增加StartService,来增加后台播放功能
 startService(intent);
 // 绑定服务,使用context来绑定
 // 那个界面需要绑定 就用哪个 Activity
 // 参数1:Intent  代表需要绑定哪一个Service
 // 参数2:ServiceConnection 回调接口,可以接收到Service连接成功和断开的回调,成功就可以取到对象。
 // 绑定服务 参数2就是服务和指定的对象绑定在一起
 bindService(intent, this, BIND_AUTO_CREATE);
 
 //指针和唱片部分
 initViews();//定义背景图
 setAnimations();
 }
 private void initViews() {
 playingPre = (ImageView) findViewById(R.id.playing_pre);
 playingPlay = (ImageView) findViewById(R.id.playing_play);
 playingNext = (ImageView) findViewById(R.id.playing_next);
 disc = (ImageView) findViewById(R.id.disc);
 needle = (ImageView) findViewById(R.id.needle);
 playingPre.setOnClickListener(this);
 playingPlay.setOnClickListener(this);
 playingNext.setOnClickListener(this);
 }
 //动画设置
 private void setAnimations() {
 discAnimation = ObjectAnimator.ofFloat(disc, "rotation", 0, 360);
 discAnimation.setDuration(20000);
 discAnimation.setInterpolator(new LinearInterpolator());
 discAnimation.setRepeatCount(ValueAnimator.INFINITE);
 
 needleAnimation = ObjectAnimator.ofFloat(needle, "rotation", 0, 25);
 needle.setPivotX(0);
 needle.setPivotY(0);
 needleAnimation.setDuration(800);
 needleAnimation.setInterpolator(new LinearInterpolator());
 }
 
 @Override
 public void onClick(View v) {
 int id = v.getId();
 switch (id) {
  case R.id.playing_pre://前一曲
  if (discAnimation != null) {
   discAnimation.end();
   playing();
  }
  break;
  case R.id.playing_play://播放中
  if (isPlaying){
   playing();
  }else {
   if (needleAnimation != null) {
   needleAnimation.reverse();
   needleAnimation.end();
   mMusicController.pause();
   }
   if (discAnimation != null && discAnimation.isRunning()) {
   discAnimation.cancel();
   mMusicController.pause();
   float valueAvatar = (float) discAnimation.getAnimatedValue();
   discAnimation.setFloatValues(valueAvatar, 360f + valueAvatar);
   }
   playingPlay.setImageResource(R.drawable.music_play);
   isPlaying = true;
  }
  break;
  case R.id.playing_next://下一曲
  if (discAnimation != null) {
   discAnimation.end();
   playing();
  }
  break;
  default:
  break;
 }
 }
 
 //播放:1、播放音乐 2、动画旋转 3、暂停图片切换为播放按钮图片
 private void playing(){
 needleAnimation.start();
 discAnimation.start();
 playingPlay.setImageResource(R.drawable.music_pause);
 mMusicController.play();//播放
 isPlaying = false;
 }
//===================================播放歌曲服务开启、停止、结束===============================
 @Override
 protected void onStart() {
 super.onStart();
 Thread thread = new Thread(this);
 thread.start();
 }
 
 @Override
 protected void onStop() {
 running = false;
 super.onStop();
 }
 
 @Override
 protected void onDestroy() {
 // 解除绑定
 unbindService(this);
 super.onDestroy();
 }
 
 //---------------------播放到当前音乐的滑动条及时间设置--------------------------
 @Override
 public void run() {
 running = true;
 try {
  while (running) {
  if (mMusicController != null) {
   long musicDuration = mMusicController.getMusicDuration();
   final long position = mMusicController.getPosition();
   final Date dateTotal = new Date(musicDuration);
   final SimpleDateFormat sb = new SimpleDateFormat("mm:ss");
   mSeekBar.setMax((int) musicDuration);
   mSeekBar.setProgress((int) position);
   mSwitcher.post(
    new Runnable() {
    @Override
    public void run() {
     Date date = new Date(position);
     String time = sb.format(date) + "/" + sb.format(dateTotal);
     mSwitcher.setCurrentText(time);
    }
    }
   );
  }
 
  Thread.sleep(500);
  }
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 }
 
 //-----------------------------
 //服务绑定与解除绑定的回调
 
 /**
 * 当服务与当前绑定对象,绑定成功,服务onBind方法调用并且返回之后
 * 回调给这个方法
 *
 * @param name
 * @param service IBinder 就是服务 onBind 返回的对象
 */
 @Override
 public void onServiceConnected(ComponentName name, IBinder service) {
 mMusicController = ((MediaService.MusicController) service);
 }
 
 @Override
 public void onServiceDisconnected(ComponentName name) {
 mMusicController = null;
 }
 
 public void btnStopService(View view) {
 Intent intent = new Intent(this, MediaService.class);
 stopService(intent);
 }
 
 @Override
 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
 }
 
 @Override
 public void onStartTrackingTouch(SeekBar seekBar) {
 }
 
 @Override
 public void onStopTrackingTouch(SeekBar seekBar) {
 mMusicController.setPosition(seekBar.getProgress());
 }
}

mediaserver部分的代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.example.cungu.musicdemo;
 
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.Environment;
import android.os.IBinder;
 
 
public class MediaService extends Service {
 private MediaPlayer mPlayer;
 /* 绑定服务的实现流程:
 * 1.服务 onCreate, onBind, onDestroy 方法
 * 2.onBind 方法需要返回一个 IBinder 对象
 * 3.如果 Activity 绑定,Activity 就可以取到 IBinder 对象,可以直接调用对象的方法
 */
 // 相同应用内部不同组件绑定,可以使用内部类以及Binder对象来返回。
 public class MusicController extends Binder {
 public void play() {
  mPlayer.start();//开启音乐
 }
 public void pause() {
  mPlayer.pause();//暂停音乐
 }
 public long getMusicDuration() {
  return mPlayer.getDuration();//获取文件的总长度
 }
 public long getPosition() {
  return mPlayer.getCurrentPosition();//获取当前播放进度
 }
 public void setPosition (int position) {
  mPlayer.seekTo(position);//重新设定播放进度
 }
 }
 /**
 * 当绑定服务的时候,自动回调这个方法
 * 返回的对象可以直接操作Service内部的内容
 * @param intent
 * @return
 */
 @Override
 public IBinder onBind(Intent intent) {
 return new MusicController();
 }
 @Override
 public void onCreate() {
 super.onCreate();
 mPlayer = MediaPlayer.create(this, R.raw.yinyue1);
 }
 /**
 * 任意一次unbindService()方法,都会触发这个方法
 * 用于释放一些绑定时使用的资源
 * @param intent
 * @return
 */
 @Override
 public boolean onUnbind(Intent intent) {
 return super.onUnbind(intent);
 }
 @Override
 public void onDestroy() {
 if (mPlayer.isPlaying()) {
  mPlayer.stop();
 }
 mPlayer.release();
 mPlayer = null;
 super.onDestroy();
 }
}

到此,这一个简易的音乐播放器,就完成了。

但是一个音乐播放器,至少播放的音乐不会只有一首,所以,可以考虑试做一个本地音乐播放器,读取本地的音乐!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_43433255/article/details/88084420

延伸 · 阅读

精彩推荐