我要说的是在Android Studio创建一个音乐播放器所遇到的问题
我借鉴的是《Android移动开发基础案例教程》这本书,因为我也是刚学Android的,但我在音乐播放器这里卡了很久大概一个多月左右吧,后来得到了源码,我发现我把书上的源代码打上去也不对,查找网上的资料,发现资料也比较老了,说的不太清楚吧。于是,我自己摸索了数天,终于找到原因了,所以我决定分享一下我的经验吧,其实也就书上一个小小的错误,哈哈。
一个是activity_main.xml文件,一个是MusicService.java文件,一个是MainActivity。java文件
<LinearLayout 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"
android:background="@drawable/bg"
android:orientation="vertical">
<EditText
android:id="@+id/et_inputpath"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Music/a.mp3" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_play"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawablePadding="3dp"
android:drawableTop="@drawable/play"
android:gravity="center"
android:text="播放" />
<TextView
android:id="@+id/tv_pause"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawablePadding="3dp"
android:drawableTop="@drawable/pause"
android:gravity="center"
android:text="暂停" />
</LinearLayout>
</LinearLayout>
代码中有一个地方需要注意:
android:drawableTop="@drawable/play"
androyid:drawableTop="@drawable/pause"
这两个图片都是系统里面的,自带的,也就是说在drawable
或者mipmap
文件里没有。这么说应该懂吧
package cn.itcast.musicplayer;
import android.app.Service;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
public class MusicService extends Service {
private static final String TAG = "MusicService";
public MediaPlayer mediaPlayer;
class MyBinder extends Binder {
// 播放音乐
public void play(String path) {
try {
if (mediaPlayer == null) {
// 创建一个MediaPlayer播放器
mediaPlayer = new MediaPlayer();
// 指定参数为音频文件
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
// 指定播放的路径
mediaPlayer.setDataSource(path);
// 准备播放
mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
// 开始播放
mediaPlayer.start();
}
});
} else {
int position = getCurrentProgress();
mediaPlayer.seekTo(position);
try {
mediaPlayer.prepare();
} catch (Exception e) {
e.printStackTrace();
}
mediaPlayer.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 暂停播放
public void pause() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause(); // 暂停播放
} else if (mediaPlayer != null && (!mediaPlayer.isPlaying())) {
mediaPlayer.start();
}
}
}
public void onCreate() {
super.onCreate();
}
// 获取当前进度
public int getCurrentProgress() {
if (mediaPlayer != null & mediaPlayer.isPlaying()) {
return mediaPlayer.getCurrentPosition();
} else if (mediaPlayer != null & (!mediaPlayer.isPlaying())) {
return mediaPlayer.getCurrentPosition();
}
return 0;
}
public void onDestroy() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
// 第一步执行onBind方法
return new MyBinder();
}
}
package cn.itcast.musicplayer;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Environment;
import android.os.IBinder;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.File;
public class MainActivity extends AppCompatActivity implements
View.OnClickListener {
private EditText path;
private Intent intent;
private myConn conn;
MusicService.MyBinder binder;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
path = (EditText) findViewById(R.id.et_inputpath);
findViewById(R.id.tv_play).setOnClickListener(this);
findViewById(R.id.tv_pause).setOnClickListener(this);
conn = new myConn();
intent = new Intent(this, MusicService.class);
bindService(intent, conn, BIND_AUTO_CREATE);
}
private class myConn implements ServiceConnection {
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (MusicService.MyBinder) service;
}
public void onServiceDisconnected(ComponentName name) {
}
}
public void onClick(View v) {
String pathway = path.getText().toString().trim();
File SDpath = Environment.getExternalStorageDirectory();
File file = new File(SDpath, pathway);
String path = file.getAbsolutePath();
switch (v.getId()) {
case R.id.tv_play:
if (file.exists() && file.length() > 0) {
binder.play (path);
} else {
Toast.makeText(this, "找不到音乐文件", Toast.LENGTH_SHORT).show();
}
break;
case R.id.tv_pause:
binder.pause();
break;
default:
break;
}
}
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}
做完这些准备工作后,还要有一首歌,并且名字叫做***a.mp3***(当然自己也能改名字)原因在activity_main.xml
文件与MainActivity.java
文件中:
<EditText
android:id="@+id/et_inputpath"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Music/a.mp3" />
path = (EditText) findViewById(R.id.et_inputpath);
......
String pathway = path.getText().toString().trim();
File SDpath = Environment.getExternalStorageDirectory();
File file = new File(SDpath, pathway);
String path = file.getAbsolutePath();
还要多说一句,怎么把a.mp3
传到Device File Explorer
上呢?
这个比较重要,首先选定一个文件,然后点击upload
,选择前面下载好的a.mp3
,最后点击就行了,这里我也花了很长时间才知道的呢
其实我写这个博客也就是想说下这里的错误
也就是MainActivity.java
文件中的错误
(书上和网上的资料都是这样说的:File SDpath = Environment.getExternalStorageDirectory();
这段代码表示的是SDpath的路径:/mnt/sdcard
)
当我运行程序后,总是一个结果: 找不到音乐文件
一个偶然的机会,算是突发奇想吧,我在onClick方法中,写了一句代码:
Log.i("2313413",path);
Log.i("2313413",pathway);
然后就有了巨大的发现,我发现path()的路径并不是/mnt/sdcard/Music/a.mp3
输出的结果而是这样的:
2019-11-16 19:36:09.355 13275-13275/com.example.mydemo I/2313413: /storage/emulated/0/Music/a.mp3
2019-11-16 19:36:09.355 13275-13275/com.example.mydemo I/2313413: Music/a.mp3
File file = new File(SDpath, pathway);
file的路径是 SDpath+pathway(父路径 + 子路径)
说到这里,你们应该都知道了吧,File SDpath = Environment.getExternalStorageDirectory();
表示的路径是
/storage/emulated/0
而不是
/mnt/sdcard
所以需要在/storage/emulated/0
路径下upload(上传)音乐a.mp3。
最后的最后,还需要在在模拟器上打开该应用的权限,也就是存储权限
另外在AndroidManifest.xml文件加上这句话准没错
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
好了,就是这样了。