MusicPlayer音乐播放器Android
【音频采集】
你可以使用手机进行现场录音,实现步骤如下:
第一步:在功能清单文件AndroidManifest.xml中添加音频刻录权限:
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
第二步:编写音频刻录代码:
1
2
3
4
5
6
7
8
9
10
11MediaRecorder recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//从麦克风采集声音 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//内容输出格式 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//音频编码方式 recorder.setOutputFile("/mnt/sdcard/glsite.amr"); recorder.prepare();//预期准备 recorder.start(); //开始刻录 ... recorder.stop();//停止刻录 recorder.reset(); //重设 recorder.release(); //刻录完成一定要释放资源
在Android开发中我们经常使用MediaPlayer来播放音频文件,但是MediaPlayer存在一些不足,例如:资源占用量较高、延迟时间较长、不支持多个音频同时播放等。这些缺点决定了MediaPlayer在某些场合的使用情况不会很理想,例如在对时间精准度要求相对较高的游戏开发中。
在游戏开发中我们经常需要播放一些游戏音效(比如:子弹爆炸,物体撞击等),这些音效的共同特点是短促、密集、延迟程度小。在这样的场景下,我们可以使用SoundPool代替MediaPlayer来播放这些音效。
SoundPool(android.media.SoundPool),顾名思义是声音池的意思,主要用于播放一些较短的声音片段,支持从程序的资源或文件系统加载。与MediaPlayer相比,SoundPool的优势在于CPU资源占用量低和反应延迟小。另外,SoundPool还支持自行设置声音的品质、音量、播放比率等参数,支持通过ID对多个音频流进行管理。
就现在已知的资料来说,SoundPool有一些设计上的BUG,从固件版本1.0开始有些还没有修复,我们在使用中应该小心再小心。相信将来Google会修复这些问题,但我们最好还是列出来:
1. SoundPool最大只能申请1M的内存空间,这就意味着我们只能用一些很短的声音片段,而不是用它来播放歌曲或者做游戏背景音乐。
2. SoundPool提供了pause和stop方法,但这些方法建议最好不要轻易使用,因为有些时候它们可能会使你的程序莫名其妙的终止。建议使用这两个方法的时候尽可能多做测试工作,还有些朋友反映它们不会立即中止播放声音,而是把缓冲区里的数据播放完才会停下来,也许会多播放一秒钟。
3. SoundPool的效率问题。其实SoundPool的效率在这些播放类中算是很好的了,但是有的朋友在G1中测试它还是有100ms左右的延迟,这可能会影响用户体验。也许这不能怪SoundPool本身,因为到了性能比较好的Droid中这个延迟就可以让人接受了。
在现阶段SoundPool有这些缺陷,但也有着它不可替代的优点,基于这些我们建议大在如下情况中多使用SoundPool:1.应用程序中的声效(按键提示音,消息等)2.游戏中密集而短暂的声音(如多个飞船同时爆炸)
【SoundPool】
开发步骤:
1> 往项目的res/raw目录中放入音效文件。
2> 新建SoundPool对象,然后调用SoundPool.load()加载音效,调用SoundPool.play()方法播放指定音效文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public class AudioActivity extends Activity { private SoundPool pool; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //指定声音池的最大音频流数目为10,声音品质为5 pool = new SoundPool(10, AudioManager.STREAM_SYSTEM, 5); final int sourceid = pool.load(this, R.raw.pj, 0);//载入音频流,返回在池中的id Button button = (Button)this.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { //播放音频,第二个参数为左声道音量;第三个参数为右声道音量;第四个参数为优先级;第五个参数为循环次数,0不循环,-1循环;第六个参数为速率,速率最低0.5最高为2,1代表正常速度 pool.play(sourceid, 1, 1, 0, -1, 1); } }); } }
demo:
1. AndroidManifest.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<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.glsite.musicplayer"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <service android:name=".MusicPlayerService" android:enabled="true" android:exported="true"></service> <activity android:name=".SettingActivity" /> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
2. MusicPlayerappsrcmainresmenuactivity_main.xml 菜单
1
2
3
4
5
6
7<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/item_setting" android:title="设置界面"/> <item android:id="@+id/item_exit" android:title="关闭播放器"/> </menu>
3.MusicPlayerappsrcmainreslayout
3.1activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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" tools:context=".MainActivity"> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent"></ListView> </android.support.constraint.ConstraintLayout>
3.2 activity_setting.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<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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=".SettingActivity" android:orientation="vertical"> <RadioGroup android:id="@+id/rg_mode" android:layout_width="wrap_content" android:layout_height="wrap_content" > <RadioButton android:id="@+id/rb_cycle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="单曲循环" /> <RadioButton android:id="@+id/rb_next" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="播放下一曲" /> <RadioButton android:id="@+id/rb_stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="播放后停止" /> </RadioGroup> </LinearLayout>
3.3 item_music.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<?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" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_item_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginTop="5dp" android:paddingTop="5dp" android:paddingBottom="5dp" android:text="歌曲名称" android:textColor="#99ff0000" android:textSize="20sp" /> <ImageView android:id="@+id/imageView" android:layout_width="25dp" android:layout_height="25dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="5dp" app:srcCompat="@mipmap/ic_launcher" /> </RelativeLayout>
4.MusicPlayerappsrcmainjavacomglsitemusicplayer
4.1BaseActivity 运行时权限
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
156package com.glsite.musicplayer; import android.content.DialogInterface; import android.content.pm.PackageManager; import android.os.Build; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.widget.Toast; /** * @author Admin * @version $Rev$ * @des ${TODO} * @updateAuthor $Author$ * @updateDes ${TODO} */ public class BaseActivity extends AppCompatActivity { //**************** Android M Permission (Android 6.0权限控制代码封装) private int permissionRequestCode = 88; private PermissionCallback permissionRunnable; public interface PermissionCallback { void hasPermission(); void noPermission(); } /** * Android M运行时权限请求封装 * * @param permissionDes 权限描述 * @param runnable 请求权限回调 * @param permissions 请求的权限(数组类型),直接从Manifest中读取相应的值,比如Manifest.permission.WRITE_CONTACTS */ public void performCodeWithPermission(@NonNull String permissionDes, PermissionCallback runnable, @NonNull String... permissions) { if (permissions == null || permissions.length == 0) return; // this.permissionrequestCode = requestCode; this.permissionRunnable = runnable; if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.M) || checkPermissionGranted(permissions)) { if (permissionRunnable != null) { permissionRunnable.hasPermission(); permissionRunnable = null; } } else { //permission has not been granted. requestPermission(permissionDes, permissionRequestCode, permissions); } } private boolean checkPermissionGranted(String[] permissions) { boolean flag = true; for (String p : permissions) { if (ActivityCompat.checkSelfPermission(this, p) != PackageManager.PERMISSION_GRANTED) { flag = false; break; } } return flag; } private void requestPermission(String permissionDes, final int requestCode, final String[] permissions) { if (shouldShowRequestPermissionRationale(permissions)) { /*1. 第一次请求权限时,用户拒绝了,下一次:shouldShowRequestPermissionRationale() 返回 true,应该显示一些为什么需要这个权限的说明 2.第二次请求权限时,用户拒绝了,并选择了“不在提醒”的选项时:shouldShowRequestPermissionRationale() 返回 false 3. 设备的策略禁止当前应用获取这个权限的授权:shouldShowRequestPermissionRationale() 返回 false*/ // Provide an additional rationale to the user if the permission was not granted // and the user would benefit from additional context for the use of the permission. // For example, if the request has been denied previously. // Snackbar.make(getWindow().getDecorView(), requestName, // Snackbar.LENGTH_INDEFINITE) // .setAction(R.string.common_ok, new View.OnClickListener() { // @Override // public void onClick(View view) { // ActivityCompat.requestPermissions(BaseAppCompatActivity.this, // permissions, // requestCode); // } // }) // .show(); //如果用户之前拒绝过此权限,再提示一次准备授权相关权限 new AlertDialog.Builder(this) .setTitle("提示") .setMessage(permissionDes) .setPositiveButton("授权", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ActivityCompat.requestPermissions(BaseActivity.this, permissions, requestCode); } }).show(); } else { // Contact permissions have not been granted yet. Request them directly. ActivityCompat.requestPermissions(BaseActivity.this, permissions, requestCode); } } private boolean shouldShowRequestPermissionRationale(String[] permissions) { boolean flag = false; for (String p : permissions) { if (ActivityCompat.shouldShowRequestPermissionRationale(this, p)) { flag = true; break; } } return flag; } /** * Callback received when a permissions request has been completed. */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == permissionRequestCode) { if (verifyPermissions(grantResults)) { if (permissionRunnable != null) { permissionRunnable.hasPermission(); permissionRunnable = null; } } else { Toast.makeText(this, "暂无权限执行相关操作!", Toast.LENGTH_SHORT).show(); if (permissionRunnable != null) { permissionRunnable.noPermission(); permissionRunnable = null; } } } else { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } public boolean verifyPermissions(int[] grantResults) { // At least one result must be checked. if (grantResults.length < 1) { return false; } // Verify that each required permission has been granted, otherwise return false. for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } //********************** END Android M Permission **************************************** }
4.2MainActivity.java
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
144package com.glsite.musicplayer; import android.Manifest; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Environment; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import java.io.File; import java.util.ArrayList; public class MainActivity extends BaseActivity { private ListView mLv; private IMusicService mIMusicService; public static final String MP3DIR = Environment.getExternalStorageDirectory() + "/Download/"; private ArrayList<String> mMp3List; private MyConn mConn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLv = findViewById(R.id.lv); performCodeWithPermission("读取SD卡需要用到的权限", new PermissionCallback() { @Override public void hasPermission() { initPlayList(); } @Override public void noPermission() { } }, Manifest.permission.READ_EXTERNAL_STORAGE); Intent intent = new Intent(this, MusicPlayerService.class); startService(intent); mConn = new MyConn(); bindService(intent, mConn, BIND_AUTO_CREATE); mLv.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (mIMusicService != null) { mIMusicService.callPlay(mMp3List, position); } else { Toast.makeText(MainActivity.this,"还没有绑定服务吧", Toast.LENGTH_SHORT).show(); } } }); } private class MyConn implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { mIMusicService = (IMusicService) service; } @Override public void onServiceDisconnected(ComponentName name) { } } /** * 初始化播放列表 */ private void initPlayList() { File file = new File(MP3DIR); File[] files = file.listFiles(); mMp3List = new ArrayList<>(); for (File f : files) { if (f.getName().endsWith(".mp3")) { mMp3List.add(f.getAbsolutePath()); System.out.println(f.getAbsolutePath()); } } mLv.setAdapter(new MusicListAdapter()); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = new MenuInflater(this); inflater.inflate(R.menu.activity_main, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.item_setting) { // 启动一个设置界面 Intent intent = new Intent(this, SettingActivity.class); startActivity(intent); } else if (item.getItemId() == R.id.item_exit){ // 停止播放并且退出 playerExit(); } return super.onOptionsItemSelected(item); } /** * 停止播放并退出 */ private void playerExit() { if (mIMusicService != null) { mIMusicService.callStop(); } if (mConn != null) { unbindService(mConn); mConn = null; } Intent intent = new Intent(this, MusicPlayerService.class); stopService(intent); finish(); } @Override protected void onDestroy() { playerExit(); super.onDestroy(); } private class MusicListAdapter extends BaseAdapter { @Override public int getCount() { return mMp3List.size(); } @Override public Object getItem(int position) { return mMp3List.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = View.inflate(MainActivity.this, R.layout.item_music, null); TextView tv_name = (TextView) view.findViewById(R.id.tv_item_name); String path = mMp3List.get(position); tv_name.setText(path.substring(path.lastIndexOf("/") + 1)); return view; } } }
4.3IMusicService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package com.glsite.musicplayer; import java.util.List; /** * @author glsite.com * @version $Rev$ * @des ${TODO} * @updateAuthor $Author$ * @updateDes ${TODO} */ public interface IMusicService { /** * 调用服务里面的播放逻辑 * * @param playList * 音乐资源的路径集合 * @param position */ public void callPlay(List<String> playList, int position); /** * 调用停止播放的方法 */ public void callStop(); }
4.4MusicPlayerService 音乐服务
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
142package com.glsite.musicplayer; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.Service; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.BitmapFactory; import android.media.AudioManager; import android.media.MediaPlayer; import android.os.Binder; import android.os.IBinder; import java.io.IOException; import java.util.List; public class MusicPlayerService extends Service { public static final int MUSIC_STOP = 0; public static final int MUSIC_PLAYING = 1; public static final int MUSIC_PAUSE = 2; private SharedPreferences mSp; private MediaPlayer mMediaPlayer; public static int playingStatus = 0; public MusicPlayerService() { } @Override public IBinder onBind(Intent intent) { return new MyBinder(); } @Override public void onCreate() { System.out.println("音乐播放器服务开启了"); mSp = getSharedPreferences("config", MODE_PRIVATE); mMediaPlayer = new MediaPlayer(); super.onCreate(); } @Override public void onDestroy() { System.out.println("音乐播放服务关闭了"); super.onDestroy(); } private class MyBinder extends Binder implements IMusicService { @Override public void callPlay(List<String> playList, int position) { play(playList, position); } @Override public void callStop() { stopPlayer(); } } /** * 停止播放 */ private void stopPlayer() { if (mMediaPlayer != null) { mMediaPlayer.stop(); mMediaPlayer.release(); mMediaPlayer = null; } NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); nm.cancelAll(); } /** * 播放音乐 * * @param playList * 所有音频列表 * @param position * 当前的位置 */ private void play(final List<String> playList, final int position) { try { if (mMediaPlayer.isPlaying()) { mMediaPlayer.stop(); } mMediaPlayer.reset(); mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); System.out.println(playList.get(position)); mMediaPlayer.setDataSource(playList.get(position)); mMediaPlayer.prepare(); mMediaPlayer.start(); String path = playList.get(position); System.out.println(path.substring(path.lastIndexOf("/") + 1)); showNotification(path.substring(path.lastIndexOf("/") + 1)); mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { int mode = mSp.getInt("mode", 0); if (mode == SettingActivity.CYCLE) { play(playList, position); } else if (mode == SettingActivity.NEXT){ // 播放下一曲 int newPosition = position + 1; if (newPosition >= playList.size()) { newPosition = 0; } play(playList, newPosition); } else if (mode == SettingActivity.STOP) { // 设置状态为停止 playingStatus = MUSIC_STOP; } } }); } catch (Exception e) { e.printStackTrace(); playingStatus = MUSIC_STOP; } } /** * 显示播放音乐的通知提醒 * * @param filename * 音乐名 */ private void showNotification(String filename) { // 判断如果当前的SDK版本>=8.0 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { String id = "channel_1"; int importance = NotificationManager.IMPORTANCE_LOW; NotificationChannel channel = new NotificationChannel(id, "123", importance); Notification noti = new Notification.Builder(this, id).setContentTitle("酷狗音乐正在播放") .setContentText(filename) .setSmallIcon(R.mipmap.ic_launcher) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)) .build(); NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); nm.createNotificationChannel(channel); nm.notify(1, noti);// 添加channel } else {// 如果当前的SDK版本<8.0 Notification noti = new Notification.Builder(this).setContentTitle("酷狗音乐正在播放") .setContentText(filename) .setSmallIcon(R.mipmap.ic_launcher) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)) .build(); NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); nm.notify(1, noti); } } }
4.5SettingActivity.java
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
60package com.glsite.musicplayer; import android.content.SharedPreferences; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.RadioButton; import android.widget.RadioGroup; public class SettingActivity extends AppCompatActivity { public static final int CYCLE = 1; public static final int NEXT = 2; public static final int STOP = 3; private RadioGroup mRgMode; private SharedPreferences mSp; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_setting); mRgMode = findViewById(R.id.rg_mode); mSp = getSharedPreferences("config", MODE_PRIVATE); int mode = mSp.getInt("mode", 0); RadioButton rb; switch (mode) { case CYCLE: rb = findViewById(R.id.rb_cycle); rb.setChecked(true); break; case NEXT: rb = findViewById(R.id.rb_next); rb.setChecked(true); break; case STOP: rb = findViewById(R.id.rb_stop); rb.setChecked(true); break; default: break; } mRgMode.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { SharedPreferences.Editor editor = mSp.edit(); switch (checkedId) { case R.id.rb_cycle: editor.putInt("mode", CYCLE); break; case R.id.rb_next: editor.putInt("mode", NEXT); break; case R.id.rb_stop: editor.putInt("mode", STOP); break; default: break; } editor.commit(); } }); } }
最后
以上就是碧蓝巨人最近收集整理的关于MusicPlayer音乐播放器Android MusicPlayer音乐播放器Androiddemo:的全部内容,更多相关MusicPlayer音乐播放器Android 内容请搜索靠谱客的其他文章。
发表评论 取消回复