失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 基于android的网络音乐播放器-本地音乐的加载和后台播放(一)

基于android的网络音乐播放器-本地音乐的加载和后台播放(一)

时间:2021-07-26 05:09:05

相关推荐

基于android的网络音乐播放器-本地音乐的加载和后台播放(一)

作为android初学者,最近把疯狂android讲义和疯狂Java讲义看了一遍,看到书中介绍的知识点非常多,很难全部记住,为了更好的掌握基础知识点,我将开发一个网络音乐播放器-EasyMusic来巩固下,也当作是练练手。感兴趣的朋友可以看看,有设计不足的地方也欢迎指出。

开发之前首先介绍下该音乐播放器将要开发的功能(需求):

1.本地音乐的加载和播放;

2.网络音乐的搜索,试听和下载;

3.音乐的断点下载;

4.点击播放图标加载专辑图片,点击歌词加载歌词并滚动显示(支持滑动歌词改变音乐播放进度);

5.支持基于popupWindow的弹出式菜单;

6.支持后台任务栏显示和控制。

该篇主要实现本地音乐的加载和播放,主要代码如下:

1. MainActivity.java

package com.sprd.easymusic;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import com.sprd.easymusic.service.PlayMusicService;import android.app.Activity;import android.app.Service;import ponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.database.Cursor;import android.os.Bundle;import android.os.IBinder;import android.provider.MediaStore;import android.util.Log;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity {private String TAG = "MainActivity";//dbMusic保存媒体库中的所有音乐private List<Map<String,Object>> dbMusic = new ArrayList<>();private ListView musicListView;private LayoutInflater inflater;private Context mContext;PlayMusicService playService;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mContext = this;musicListView = (ListView)findViewById(R.id.musicList);getMusicFromDb();bindToService();inflater = LayoutInflater.from(mContext);//音乐列表musicListView的adapter定义SimpleAdapter adapter = new SimpleAdapter(this, dbMusic, R.layout.musiclist_item,new String[] {"title", "artist"}, new int[] {R.id.musicTitle, R.id.musicArtist});musicListView.setAdapter(musicListAdapter);musicListView.setOnItemClickListener(new OnItemClickListener() {public void onItemClick(AdapterView<?> parent, View view, int position, long id) {playMusic(position);Toast.makeText(mContext, "click on position " + position, Toast.LENGTH_LONG).show();}});}//绑定服务时的ServiceConnection参数private ServiceConnection conn = new ServiceConnection() {//绑定成功后该方法回调,并获得服务端IBinder的引用public void onServiceConnected(ComponentName name, IBinder service) {//通过获得的IBinder获取PlayMusicService的引用playService = ((PlayMusicService.MusicBinder)service).getService();Toast.makeText(mContext, "onServiceConnected", Toast.LENGTH_LONG).show();}@Overridepublic void onServiceDisconnected(ComponentName name) {Log.d(TAG, "onServiceDisconnected");}};//绑定服务PlayMusicServiceprivate void bindToService() {bindService(new Intent(mContext, com.sprd.easymusic.service.PlayMusicService.class),conn, Service.BIND_AUTO_CREATE);}//通过获得的PlayMusicService引用调用播放音乐的方法,方法传进去的参数为音乐urlprotected void playMusic(int position) {if (playService != null) {playService.play((String)dbMusic.get(position).get("url"));}}//从媒体库中查询音乐private void getMusicFromDb() {if (dbMusic.size() > 0) dbMusic.clear();Cursor musicCursor1 = this.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);//从外部存储获取getMusic(musicCursor1);Cursor musicCursor2 = this.getContentResolver().query(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);//从内部存储获取getMusic(musicCursor2);}//获取到的音乐以Map的形式存储在dbMusic中private void getMusic(Cursor musicCursor) {while (musicCursor.moveToNext()) {Map<String, Object> item = new HashMap<String, Object>();long id = musicCursor.getLong(musicCursor.getColumnIndex(MediaStore.Audio.Media._ID));String title = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.TITLE));String artist = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));if (artist != null && artist.equals("<unknown>")) {continue;}long duration = musicCursor.getLong(musicCursor.getColumnIndex(MediaStore.Audio.Media.DURATION));long size = musicCursor.getLong(musicCursor.getColumnIndex(MediaStore.Audio.Media.SIZE));String url = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA));int isMusic = musicCursor.getInt(musicCursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));if (isMusic != 0) {item.put("id", id);item.put("title", title);item.put("artist", artist);item.put("duration", formatDuration(duration));item.put("size", size);item.put("url", url);Log.d("MainActivity", "MusicTitle = " + title);Log.d("MainActivity", "MusicArtist = " + artist);Log.d("MainActivity", "MusicUrl = " + url);dbMusic.add(item);}} }//将音乐时长转换为00:00格式private String formatDuration(long dur) {long totalSecond = dur / 1000;String minute = totalSecond / 60 + "";if (minute.length() < 2) minute = "0" + minute ;String second = totalSecond % 60 + "";if (second.length() < 2) second = "0" + second;return minute + ":" + second;}private BaseAdapter musicListAdapter = new BaseAdapter() {@Overridepublic int getCount() {return dbMusic.size();}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {View view = convertView;Map<String, Object> item = dbMusic.get(position);if (convertView == null) {view = inflater.inflate(R.layout.musiclist_item, null);}TextView musicTitle = (TextView)view.findViewById(R.id.musicTitle);TextView musicArtist = (TextView)view.findViewById(R.id.musicArtist);musicTitle.setText((String)item.get("title"));musicTitle.setText((String)item.get("artist"));return view;}};@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();if (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);}}

布局文件就一个ListView就不贴出来了,这里贴一下musicListAdapter的item布局:

musiclist_item.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/apk/res/android"android:id="@+id/RelativeLayout1"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center_vertical"android:orientation="horizontal"android:padding="5dp" ><ImageView android:id="@+id/musicTag"android:layout_width="50dp"android:layout_height="40dp"android:layout_alignParentLeft="true"android:layout_alignParentTop="true"android:layout_centerVertical="true"android:src="@drawable/music" /><TextView android:id="@+id/musicTitle"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentTop="true"android:layout_toRightOf="@id/musicTag"android:text="TextView" /><TextView android:id="@+id/musicArtist"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toRightOf="@id/musicTag"android:layout_below="@+id/musicTitle"android:text="TextView" /><ImageView android:id="@+id/love"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignBaseline="@+id/musicTag"android:layout_alignParentRight="true"android:src="@android:drawable/btn_star_big_off" /></RelativeLayout>

2 PlayMusicService.java 这是后台播放音乐的服务

package com.sprd.easymusic.service;import java.io.IOException;import java.util.Timer;import java.util.TimerTask;import android.app.Service;import android.content.Intent;import android.media.MediaPlayer;import android.media.MediaPlayer.OnCompletionListener;import android.os.Binder;import android.os.IBinder;import android.util.Log;import android.widget.Toast;public class PlayMusicService extends Service {private final String TAG = "PlayMusicService";private MediaPlayer mPlayer = new MediaPlayer();//后台播放音乐的线程private PlayThread myPlayThread = new PlayThread(); @Overridepublic void onCreate() {super.onCreate();Log.d(TAG, "onCreate");}/** MainActivity调用bindService后该方法回调,紧接着MainActivity的ServiceConnection的* onServiceConnected方法回调,onBind回调的返回值传递给onServiceConnected中的参数service* 从而MainActivity就可以通过Binder的getService方法获得PlayMusicService的引用,后续的音乐播放* 控制就简单了*/public IBinder onBind(Intent intent) {Toast.makeText(this, "onBind", Toast.LENGTH_LONG).show();return new MusicBinder();}public class MusicBinder extends Binder {public PlayMusicService getService() {return PlayMusicService.this;}}public void play(String url) {myPlayThread.setUrl(url);myPlayThread.start();}//后台播放音乐的线程定义private class PlayThread extends Thread {//歌曲的urlprivate String url = null;public PlayThread() {}public PlayThread(String url) {this.url = url;}public void setUrl(String url) {this.url = url;}public void run() {if (mPlayer.isPlaying()) {mPlayer.stop();}try {mPlayer.reset();Log.d("MusicService", "play reset ");mPlayer.setDataSource(url);Log.d("MusicService", "play setDataSource ");mPlayer.prepare();Log.d("MusicService", "play prepare ");mPlayer.start();Log.d("MusicService", "play start ");mPlayer.setOnCompletionListener(new OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer player) {}});} catch (Exception e) {e.printStackTrace();}}}}

然后不要忘了在manifest文件里面注册service和添加权限(媒体库查询外部存储的音乐)

<service android:name="com.sprd.easymusic.service.PlayMusicService"></service><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

该文章只介绍这些内容,后续会更新进度;代码有问题或错误的地方欢迎指出和给出修改意见。

音乐播放器已完成,下载地址:

Android音乐播放器

如果觉得《基于android的网络音乐播放器-本地音乐的加载和后台播放(一)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。