您的位置:首页 > 移动开发 > Android开发

android 应用开发-实现简单的音乐播放功能

2017-07-21 18:13 1136 查看
  结合百度搜到的,自己再优化深入,终于实现,结合网上搜的其他大神写的地址找不到了


----------一些细节没有做,主要看大功能咯----------

逻辑思路:

1.书写aidl接口

2.绑定service服务

3.activity实现业务逻辑

上干货不废话:

IServicePlayer.aidl

interface IServicePlayer {
void play();
void pause();
void stop();
int getDuration();
int getCurrentPosition();
void seekTo(int current);
boolean setLoop(boolean loop);
void reset();
void setDataSource(String path);
void prepare();
void release();
boolean isPlaying();
void prepareAsync();
void setPlayingFinish();

}


MusicService.java

public class MusicService extends Service {

public static MediaPlayer mPlayer;

IServicePlayer.Stub stub = new IServicePlayer.Stub() {

@Override
public void play() throws RemoteException {
mPlayer.start();
}

@Override
public void pause() throws RemoteException {
mPlayer.pause();
}

@Override
public void stop() throws RemoteException {
mPlayer.stop();
}

@Override
public int getDuration() throws RemoteException {
return mPlayer.getDuration();
}

@Override
public int getCurrentPosition() throws RemoteException {
return mPlayer.getCurrentPosition();
}

@Override
public void seekTo(int current) throws RemoteException {
mPlayer.seekTo(current);
}

@Override
public boolean setLoop(boolean loop) throws RemoteException {
return false;
}

@Override
public void reset() throws RemoteException {
mPlayer.reset();
}

@Override
public void setDataSource(String path) throws RemoteException {
try {
mPlayer.setDataSource(path);
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void prepare() throws RemoteException {
try {
mPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void release() throws RemoteException {
mPlayer.release();
}

@Override
public boolean isPlaying() throws RemoteException {

return mPlayer.isPlaying();
}

@Override
public void prepareAsync() throws RemoteException {
mPlayer.prepareAsync();
}

@Override
public void setPlayingFinish() throws RemoteException {
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Log.d(Content.TAG,"play finish--------------");
Intent intent = new Intent();
intent.setAction(Content.ACTION_FINISH);
sendBroadcast(intent);
}
});
}

};

@Nullable
@Override
public IBinder onBind(Intent intent) {
return stub;
}

@Override
public void onCreate() {
super.onCreate();
Log.d(Content.TAG, "------onCreate------");
mPlayer = new MediaPlayer();

}

}


   MusicActivity.java

public class MusicActivity extends Activity implements View.OnClickListener,
SeekBar.OnSeekBarChangeListener, AdapterView.OnItemClickListener{

private final static String TAG = "MusicActivity";
protected static final int SEARCH_MUSIC_SUCCESS = 0;// 搜索成功标记
private SeekBar music_progress;
private ImageView pre;
private ImageView play;
private ImageView next;
private ListView music_listview;
private MusicListAdapter mMusicListAdapter;
private TextView total_time, play_time, music_title;
private int currIndex = 0;// 表示当前播放的音乐索引
// 定义当前播放器的状态״̬
private static final int IDLE = 0;
private static final int PAUSE = 1;
private static final int START = 2;
private static final int CURR_TIME_VALUE = 1;

private int currState = IDLE; // 当前播放器的状态
private boolean flag = true;//控制进度条线程标记
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/memoryCat/";
//定义线程池(同时只能有一个线程运行)
ExecutorService mExecutorService = Executors.newSingleThreadExecutor();
List<String> list = new ArrayList<>();
IServicePlayer iPlayer;

private MyBroadcast mMyBroadcast;

private   Handler hander  = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case SEARCH_MUSIC_SUCCESS:
//搜索音乐文件结束时
mMusicListAdapter = new MusicListAdapter();
music_listview.setAdapter(mMusicListAdapter);

break;
case CURR_TIME_VALUE:
//设置当前时间
play_time.setText(msg.obj.toString());

try {
music_progress.setProgress(iPlayer.getCurrentPosition());
music_progress.setMax(iPlayer.getDuration());
total_time.setText(toTime(iPlayer.getDuration()));
} catch (RemoteException e) {
e.printStackTrace();
}
break;

default:
break;
}
}
};

ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "-----onServiceConnected-----");
iPlayer = IServicePlayer.Stub.asInterface(service);
try {
if (iPlayer != null &&iPlayer.isPlaying()){

music_progress.setMax(iPlayer.getDuration());
music_progress.setProgress(iPlayer.getCurrentPosition());

play_time.setText(toTime(iPlayer.getCurrentPosition()));
total_time.setText(toTime(iPlayer.getDuration()));
play.setImageResource(R.drawable.pause);
mExecutorService.execute(new Runnable() {
@Override
public void run() {
runSeekBar();
}
});

}
} catch (RemoteException e) {
e.printStackTrace();
}
}

@Override
public void onServiceDisconnected(ComponentName name) {

}
};

@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
Log.d(Content.TAG,"onCreate");
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_music);

mMyBroadcast = new MyBroadcast();
IntentFilter mIntentFilter = new IntentFilter();
mIntentFilter.addAction(Content.ACTION_FINISH);
registerReceiver(mMyBroadcast,mIntentFilter);

init();
list.clear();

//是否有外部存储设备
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
new Thread(new Runnable() {
String[] ext = {".mp3"};

File file = new File(path);

public void run() {
search(file, ext);
hander.sendEmptyMessage(SEARCH_MUSIC_SUCCESS);
}
}).start();

} else {
Toast.makeText(this, "请插入外部存储设备..", Toast.LENGTH_LONG).show();
}
}

private void init() {
music_progress = (SeekBar) findViewById(R.id.music_progress);
play = (ImageView) findViewById(R.id.play);
pre = (ImageView) findViewById(R.id.pre);
next = (ImageView) findViewById(R.id.next);
music_listview = (ListView) findViewById(R.id.music_list);
total_time = (TextView) findViewById(R.id.total_time);
play_time = (TextView) findViewById(R.id.play_time);
music_title = (TextView) findViewById(R.id.music_title);
//        setPlayingFinish
bindService(new Intent(this, MusicService.class), conn, Context.BIND_AUTO_CREATE);
startService(new Intent(MusicActivity.this, MusicService.class));

music_progress.setOnSeekBarChangeListener(this);
pre.setOnClickListener(this);
next.setOnClickListener(this);
play.setOnClickListener(this);
music_listview.setOnItemClickListener(this);
}

private String toTime(int time) {
int minute = time / 1000 / 60;
int s = time / 1000 % 60;
String mm = null;
String ss = null;
if (minute < 10) mm = "0" + minute;
else mm = minute + "";

if (s < 10) ss = "0" + s;
else ss = "" + s;

return mm + ":" + ss;
}

@Override
public void onClick(View v) {
try {
iPlayer.setPlayingFinish();

} catch (RemoteException e) {
e.printStackTrace();
}
switch (v.getId()) {
case R.id.play:
try {
play();

} catch (Exception e) {
e.printStackTrace();
}
break;
case R.id.pre:
previous();

break;
case R.id.next:
next();
break;

}
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
try {
if (fromUser) {
iPlayer.seekTo(progress);
}

} catch (RemoteException e) {
e.printStackTrace();
}
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
currIndex = position;
start();
}

private void runSeekBar() {
flag = true;
while (flag) {
try {
if (iPlayer.getCurrentPosition() < music_progress.getMax()) {
music_progress.setProgress(iPlayer.getCurrentPosition());
Message msg = hander.obtainMessage(CURR_TIME_VALUE, toTime(iPlayer.getCurrentPosition()));
hander.sendMessage(msg);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
flag = false;
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}

class MusicListAdapter extends BaseAdapter {
@Override
public int getCount() {
return list.size();
}

@Override
public Object getItem(int position) {
return list.get(position);
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.musiclist_item,
null);
}
TextView tv_music_name = (TextView) convertView.findViewById(R.id.title);

ViewGroup item_bg = (ViewGroup) convertView.findViewById(R.id.item_bg);

if (list.get(currIndex).replace(path, "").replace(".mp3", "") .equals(list.get(position).replace(path, "").replace(".mp3", "")))
{
item_bg.setBackgroundResource(R.drawable.item_bg);
}else {
item_bg.setBackground(null);
}
tv_music_name.setText(list.get(position).replace(path, "").replace(".mp3", ""));
return convertView;
}

}

private void play() throws Exception {
switch (currState) {
case IDLE:
play.setImageResource(R.drawable.pause);
start();
break;
case PAUSE:
iPlayer.pause();
play.setImageResource(R.drawable.play);
currState = START;
break;
case START:
iPlayer.play();
play.setImageResource(R.drawable.pause);
currState = PAUSE;
}
}

//上一首
private void previous() {
if ((currIndex - 1) >= 0) {
currIndex--;
start();
mMusicListAdapter.notifyDataSetChanged();
} else {
Toast.makeText(this, "当前已经是第一首歌曲了", Toast.LENGTH_SHORT).show();
}
}

//下一首
private void next() {
if (currIndex + 1 < list.size()) {
currIndex++;
start();
mMusicListAdapter.notifyDataSetChanged();
} else {
currIndex = 0;
start();
Toast.makeText(this, "当前已经是最后一首歌曲了", Toast.LENGTH_SHORT).show();
}
}

//开始播放
private void start() {
if (list.size() > 0 && currIndex < list.size()) {
String SongPath = list.get(currIndex);
try {
iPlayer.reset();

iPlayer.setDataSource(SongPath);
iPlayer.prepare();
iPlayer.play();
mExecutorService.execute(new Runnable() {
@Override
public void run() {
runSeekBar();
}
});
music_title.setText(list.get(currIndex).replace(path, "").replace(".mp3", ""));
mMusicListAdapter.notifyDataSetChanged();
/*
btnPlay.setImageResource(R.drawable.ic_media_pause);*/
currState = PAUSE;
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(this, "播放列表为空", Toast.LENGTH_SHORT).show();
}
}

// 搜索音乐文件
private void search(final File file, final String[] ext) {
if (file != null) {
if (file.isDirectory()) {
File[] listFile = file.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
search(listFile[i], ext);
}
}
} else {
String filename = file.getAbsolutePath();
for (int i = 0; i < ext.length; i++) {
if (filename.endsWith(ext[i])) {
list.add(filename);
break;
}
}
}
}
}

@Override
protected void onDestroy() {
mExecutorService.shutdownNow();
super.onDestroy();
}

public class MyBroadcast extends  BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
next();
}
}

}


  MusicActivity加载的布局 :

    activity_music.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_music">

<RelativeLayout
android:id="@+id/music_title_layout"
android:layout_width="302dp"
android:layout_height="133dp"
android:layout_marginLeft="12dp"
android:layout_marginTop="15dp"
android:background="@drawable/bg_music_title"
android:orientation="vertical">

<TextView
android:id="@+id/music_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/music_title"
android:textSize="14sp"
android:textColor="#FFF57711"
android:layout_marginTop="60dp"/>

<LinearLayout
android:layout_below="@+id/music_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>

<TextView
android:id="@+id/play_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="00:00"
android:textSize="14sp"
android:layout_marginLeft="20dp"
android:textColor="#FF00984F"/>

<SeekBar
android:id="@+id/music_progress"
android:layout_marginTop="7dp"
android:layout_width="180dp"
android:layout_marginLeft="5dp"
android:progressDrawable="@drawable/po_seekbar"
android:thumb="@null"
android:layout_height="6dp"
android:gravity="center_vertical" />

<TextView
android:id="@+id/total_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="00:00"
android:textSize="14sp"
android:layout_marginLeft="5dp"
android:textColor="#FF00984F"/>
</LinearLayout>
</RelativeLayout>

<RelativeLayout
android:id="@+id/play_control_layout"
android:layout_width="250dp"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="15dp"
android:layout_marginLeft="40dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:gravity="center"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ImageView
android:id="@+id/pre"
android:layout_gravity="center"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/pre"
android:scaleType="centerInside"
android:background="@drawable/button_bg"/>
<View
android:layout_width="100dp"
android:layout_height="70dp" />
<ImageView
android:id="@+id/next"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/next"
android:scaleType="centerInside"
android:background="@drawable/button_bg"/>
</LinearLayout>
<ImageView
android:id="@+id/play"
android:layout_width="70dp"
android:layout_height="70dp"
android:src="@drawable/play"
android:layout_gravity="center"
android:scaleType="centerInside"
android:background="@drawable/button_bg"/>

</FrameLayout>

</RelativeLayout>

<FrameLayout
android:layout_alignTop="@id/music_title_layout"
android:layout_alignParentRight="true"
android:layout_marginRight="12dp"
android:layout_width="196dp"
android:layout_height="295dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="295dp"
android:orientation="vertical"
android:background="@drawable/bg_music_list">
<TextView
android:id="@+id/music_list_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:text="@string/music_list_title"
android:textSize="16sp"
android:textColor="#FF00984F" />

<ListView
android:id="@+id/music_list"
android:paddingTop="10dp"
android:paddingBottom="30dp"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:layout_width="match_parent"
android:layout_height="match_parent"></ListView>
</LinearLayout>
<View
android:background="#FF00984F"
android:layout_gravity="center_horizontal"
android:layout_width="150dp"
android:layout_marginTop="50dp"
android:layout_height="1dp" ></View>
</FrameLayout>

</RelativeLayout>


public class Content {
public final static String TAG = "WPTAG";
public final static String ACTION_FINISH = "com.along.memorycat.FINISH";

}


主布局文件:

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen">

<activity
android:name=".MainActivity"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".MusicActivity"
android:screenOrientation="landscape" />
<service android:name=".MusicService"  android:enabled="true"
android:exported="true" />
</application>


   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐