转载请注明出处:http://blog.csdn.net/iwanghang/article/details/51448597

项目源码(打赏5积分请点这边):http://download.csdn.net/detail/iwanghang/9524502

项目源码(免积分下载请点这边):http://download.csdn.net/detail/iwanghang/9682928


觉得博文有用,请点赞,请留言,请关注,谢谢!~

实现功能:
歌曲下载完成后通知主界面更新本地音乐

除了下面说明的一个问题,还有一些BUG有待修复,后续博文将会继续更新

//DownloadDialogFragment回传的是否下载成功的回传值@Overridepublic void downloadSuccessListener(String isDownloadSuccess) {   System.out.println("MainActivity.downloadSuccessListener = " + isDownloadSuccess);   if (isDownloadSuccess.length() > 0){      //Toast.makeText(MainActivity.this, "DownloadDialogFragment.下载成功.回传给.MainActivity = " + isDownloadSuccess, Toast.LENGTH_SHORT).show();      //问题:下载完成后,确实通知媒体库更新了,但是马上初始化数据,可能媒体库还没有更新      //临时解决:在ActionBar上,添加一个刷新按钮      //永久解决:通过mp3Infos.size()的改变,来判断媒体库已经更新      //更新本地音乐列表      myMusicListFragment.loadData();//初始化数据      myMusicListFragment.newInstance();//重新实例化一下本地音乐Fragment,加载新的数据   }}
实现效果如图:


因为,没有自己的服务器,所以网络音乐所有相关功能(包含搜索音乐、下载音乐、下载歌词)均无法保证时效性,建议,尽快下载和练习;如果你下载时候,已经因为我采集的服务器更改规则,请给我留言,如果可以解决,我将在有空的时候献上新的源码。

(最新的,请下载最后一个,本博文对应版本2.5;如果需要逐步实现的过程,请下载所有)
(有兴趣可以看看版本2.4,有时候可以更新本地音乐列表,但是更新后,播放不了本地音乐,2.5在Playservice也有一些改动,本篇博文没有体现,有兴趣可以自己挖掘一下)

实现代码如下:
DownloadDialogFragment如下:
package com.iwanghang.drmplayer;import android.app.AlertDialog;import android.app.Dialog;import android.content.Intent;import android.net.Uri;import android.os.Environment;import android.provider.MediaStore;import android.support.v4.app.DialogFragment;import android.content.Context;import android.content.DialogInterface;import android.os.Bundle;import android.widget.Toast;import com.iwanghang.drmplayer.adapter.MyMusicListAdapter;import com.iwanghang.drmplayer.utils.Constant;import com.iwanghang.drmplayer.utils.DownloadUtils;import com.iwanghang.drmplayer.utils.MediaUtils;import com.iwanghang.drmplayer.vo.Mp3Info;import com.iwanghang.drmplayer.vo.SearchResult;import java.io.File;import java.util.ArrayList;/** * Created by iwanghang on 16/5/3. * DownloadDialogFargment */public class DownloadDialogFragment extends DialogFragment {    private MyMusicListFragment myMusicListFragment;    private ArrayList mp3Infos;    private MyMusicListAdapter myMusicListAdapter;    private SearchResult searchResult;//当前要下载的歌曲对象    private MainActivity mainActivity;    public static DownloadDialogFragment newInstance(SearchResult searchResult){        DownloadDialogFragment downloadDialogFragment = new DownloadDialogFragment();        downloadDialogFragment.searchResult = searchResult;        return downloadDialogFragment;    }    private String[] items;    @Override    public void onAttach(Context context) {        super.onAttach(context);        mainActivity = (MainActivity) getActivity();        //items = new String[]{"下载","取消"};        items = new String[]{getString(R.string.download),getString(R.string.cancel)};    }    // 回调接口    //public interface DownloadSelectListener { // 是否选择(点击)下载.监听.按钮回调接口    //    void downloadSelectListener(int isDownload); // 回传一个int,是否选择(点击)下载按钮 ; 回传0,表示下载;回传1,表示取消    //}    //创建对话框的事件方法    @Override    public Dialog onCreateDialog(Bundle savedInstanceState) {        final AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity);        builder.setCancelable(true);//返回键可以取消        builder.setItems(items,new DialogInterface.OnClickListener(){            @Override            public void onClick(DialogInterface dialog, int which) {                switch (which) {                    case 0:                        //执行下载                        downloadMusic();                        break;                    case 1://取消                        dialog.dismiss();                        break;                }                //DownloadSelectListener listener = (DownloadSelectListener) getActivity(); // 回调接口                //listener.downloadSelectListener(which);//回传0,表示下载;回传1,表示取消            }        });        return builder.show();    }    // 回调接口    public interface DownloadSuccessListener { // 下载是否成功.监听.按钮回调接口        void downloadSuccessListener(String isDownloadSuccess); // 回传一个字符串    }    //下载音乐    private void downloadMusic() {        Toast.makeText(mainActivity, "正在下载:" + searchResult.getMusicName(), Toast.LENGTH_LONG).show();        DownloadUtils.getsInstance().setListener(new DownloadUtils.OnDownloadListener() {            @Override            public void onDowload(String mp3Url) { //下载成功                Toast.makeText(mainActivity, "下载成功", Toast.LENGTH_SHORT).show();                System.out.println("DownloadDialogFragment.downloadMusic @ = " + Environment.getExternalStorageDirectory()+Constant.DIR_MUSIC + "/" + mp3Url);                //更新媒体库                scanFile(mainActivity,Environment.getExternalStorageDirectory()+Constant.DIR_MUSIC + "/" + mp3Url);                //更新 本地音乐列表 , 这个功能放在MainActivity实现                //DownloadSuccessListener listener = (DownloadSuccessListener) getActivity(); // 空指针异常,因为Fragment已经销毁,所以getActivity()==null,需要使用下面的写法                DownloadSuccessListener listener = mainActivity; // 回调接口                System.out.println("DownloadDialogFragment.downloadMusic.listener = " + listener);                listener.downloadSuccessListener(mp3Url); // 回传一个字符串 ,回传什么都行 ,只是告诉MainActivity ,已经下载成功了新的歌曲            }            @Override            public void onFailed(String error) { //下载失败                Toast.makeText(mainActivity, error, Toast.LENGTH_SHORT).show();            }        }).download(searchResult);    }    /**     * 通知媒体库更新文件     * @param context     * @param filePath 文件全路径     *     * */    public void scanFile(Context context, String filePath) {        Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);        scanIntent.setData(Uri.fromFile(new File(filePath)));        context.sendBroadcast(scanIntent);    }    /**     * 更新本地音乐列表     */    //private void loadDataAndChangeUI() {    //    if(myMusicListFragment==null){    //        myMusicListFragment = MyMusicListFragment.newInstance();    //    }    //    //mp3Infos = MediaUtils.getMp3Infos(mainActivity);    //    //myMusicListAdapter = new MyMusicListAdapter(mainActivity,mp3Infos);    //    //listView_my_music.setAdapter(myMusicListAdapter);    //    myMusicListFragment.loadData();//初始化数据    //    myMusicListFragment.changeUIStatusOnPlay(0);    //}}


MainActivity如下:
package com.iwanghang.drmplayer;import android.content.Intent;import android.content.SharedPreferences;import android.graphics.BitmapFactory;import android.graphics.BitmapFactory.Options;import android.graphics.Color;import android.graphics.drawable.ColorDrawable;import android.graphics.drawable.Drawable;import android.graphics.drawable.LayerDrawable;import android.graphics.drawable.TransitionDrawable;import android.os.Build;import android.os.Bundle;import android.os.Handler;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.ViewPager;import android.util.TypedValue;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.ListView;import android.widget.Toast;import com.astuetz.PagerSlidingTabStrip;import com.astuetz.viewpager.extensions.sample.QuickContactFragment;import com.iwanghang.drmplayer.utils.MediaUtils;import com.iwanghang.drmplayer.vo.Mp3Info;import java.nio.charset.CoderMalfunctionError;import java.util.ArrayList;public class MainActivity extends BaseActivity implements DownloadDialogFragment.DownloadSuccessListener {//private final Handler handler = new Handler();private PagerSlidingTabStrip tabs;private ViewPager pager;private MyPagerAdapter adapter;public DRMPlayerApp app;//取出全局对象 方便调用//private Drawable oldBackground = null;//private int currentColor = 0xFFC74B46;private MyMusicListFragment myMusicListFragment;private NetMusicListFragment netMusicListFragment;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//取出全局对象 方便调用app = (DRMPlayerApp) getApplication();setContentView(R.layout.activity_main);tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);pager = (ViewPager) findViewById(R.id.pager);adapter = new MyPagerAdapter(getSupportFragmentManager());pager.setAdapter(adapter);/** android TypedValue.applyDimension()的作用 这个方法是转变为标准尺寸的一个函数,例如 int size =(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20,context.getResources().getDisplayMetrics()); 这里COMPLEX_UNIT_SP是单位,20是数值,也就是20sp。 */final int pageMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources().getDisplayMetrics());pager.setPageMargin(pageMargin);tabs.setViewPager(pager);//修改主界面颜色,稍后修复功能,暂时使用默认颜色//changeColor(currentColor);//绑定服务//服务在加载SplashActivity(欢迎页面)的时候,已经启动//bindPlayService();//这里,我在MyMusicListFragment里面绑定,而没有在MainActivity里绑定}@Overridepublic void publish(int progress) {//更新进度条}@Overridepublic void change(int position) {//更新歌曲位置.按钮的状态等信息/** * 本地音乐的播放UI实际上在MyMusicListFragment中,所以要 * 先在MyMusicListFragmen中,写入public void changeUIStatus(int position){} * 然后,传参过去 */if (pager.getCurrentItem()==0){//如果页面等于0,则说明选中的是第一个页面,我的音乐页面System.out.println("MainActivity.change.pager.getCurrentItem()==0");myMusicListFragment.loadData();//初始化数据myMusicListFragment.changeUIStatusOnPlay(position);}else if (pager.getCurrentItem()==1){System.out.println("MainActivity.change.pager.getCurrentItem()==1");}}//DownloadDialogFragment回传的是否点击下载按钮的回传值//@Override//public void downloadSelectListener(int isDownload) {//if (isDownload == 0){//Toast.makeText(MainActivity.this, "DownloadDialogFragment.下载点击事件.回传给.MainActivity", Toast.LENGTH_SHORT).show();////}else if (isDownload == 1){//Toast.makeText(MainActivity.this, "DownloadDialogFragment.取消点击事件.回传给.MainActivity", Toast.LENGTH_SHORT).show();////MyMusicListFragment.newInstance();//}//}//DownloadDialogFragment回传的是否下载成功的回传值@Overridepublic void downloadSuccessListener(String isDownloadSuccess) {System.out.println("MainActivity.downloadSuccessListener = " + isDownloadSuccess);if (isDownloadSuccess.length() > 0){//Toast.makeText(MainActivity.this, "DownloadDialogFragment.下载成功.回传给.MainActivity = " + isDownloadSuccess, Toast.LENGTH_SHORT).show();//问题:下载完成后,确实通知媒体库更新了,但是马上初始化数据,可能媒体库还没有更新//临时解决:在ActionBar上,添加一个刷新按钮//永久解决:通过mp3Infos.size()的改变,来判断媒体库已经更新//更新本地音乐列表myMusicListFragment.loadData();//初始化数据myMusicListFragment.newInstance();//重新实例化一下本地音乐Fragment,加载新的数据}}//@Override//public boolean onCreateOptionsMenu(Menu menu) {//getMenuInflater().inflate(R.menu.main, menu);//return true;//}////@Override//public boolean onOptionsItemSelected(MenuItem item) {////switch (item.getItemId()) {////case R.id.action_contact://QuickContactFragment dialog = new QuickContactFragment();//dialog.show(getSupportFragmentManager(), "QuickContactFragment");//return true;////}////return super.onOptionsItemSelected(item);//}//private void changeColor(int newColor) {////tabs.setIndicatorColor(newColor);////// change ActionBar color just if an ActionBar is available//if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {////Drawable colorDrawable = new ColorDrawable(newColor);//Drawable bottomDrawable = getResources().getDrawable(R.drawable.actionbar_bottom);//LayerDrawable ld = new LayerDrawable(new Drawable[] { colorDrawable, bottomDrawable });////if (oldBackground == null) {////if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {//ld.setCallback(drawableCallback);//} else {//getActionBar().setBackgroundDrawable(ld);//}////} else {////TransitionDrawable td = new TransitionDrawable(new Drawable[] { oldBackground, ld });////// workaround for broken ActionBarContainer drawable handling on//// pre-API 17 builds//// https://github.com/android/platform_frameworks_base/commit/a7cc06d82e45918c37429a59b14545c6a57db4e4//if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {//td.setCallback(drawableCallback);//} else {//getActionBar().setBackgroundDrawable(td);//}////td.startTransition(200);////}////oldBackground = ld;////// http://stackoverflow.com/questions/11002691/actionbar-setbackgrounddrawable-nulling-background-from-thread-handler//getActionBar().setDisplayShowTitleEnabled(false);//getActionBar().setDisplayShowTitleEnabled(true);////}////currentColor = newColor;////}//public void onColorClicked(View v) {////int color = Color.parseColor(v.getTag().toString());//changeColor(color);////}//@Override//protected void onSaveInstanceState(Bundle outState) {//super.onSaveInstanceState(outState);//outState.putInt("currentColor", currentColor);//}//@Override//protected void onRestoreInstanceState(Bundle savedInstanceState) {//super.onRestoreInstanceState(savedInstanceState);//currentColor = savedInstanceState.getInt("currentColor");//changeColor(currentColor);//}//private Drawable.Callback drawableCallback = new Drawable.Callback() {//@Override//public void invalidateDrawable(Drawable who) {//getActionBar().setBackgroundDrawable(who);//}////@Override//public void scheduleDrawable(Drawable who, Runnable what, long when) {//handler.postAtTime(what, when);//}////@Override//public void unscheduleDrawable(Drawable who, Runnable what) {//handler.removeCallbacks(what);//}//};public class MyPagerAdapter extends FragmentPagerAdapter {private final String[] TITLES = { "本地音乐", "网络音乐"};public MyPagerAdapter(FragmentManager fm) {super(fm);}@Overridepublic CharSequence getPageTitle(int position) {return TITLES[position];}@Overridepublic int getCount() {return TITLES.length;}@Overridepublic Fragment getItem(int position) {//return SuperAwesomeCardFragment.newInstance(position);if(position==0){System.out.println("MainActivity.MyPagerAdapter.position==0");if(myMusicListFragment==null){myMusicListFragment = MyMusicListFragment.newInstance();}return myMusicListFragment;}else if (position == 1){System.out.println("MainActivity.MyPagerAdapter.position==1");if(netMusicListFragment==null){netMusicListFragment = NetMusicListFragment.newInstance();}return netMusicListFragment;}return null;//return MyMusicListFragment.newInstance();}}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {//填充菜单getMenuInflater().inflate(R.menu.main_menu,menu);return true;}public boolean onOptionsItemSelected(MenuItem item){//菜单中事件switch (item.getItemId()){case R.id.newMyMusic:myMusicListFragment.loadData();//初始化数据myMusicListFragment.newInstance();//重新实例化一下本地音乐Fragment,加载新的数据System.out.println("刷新");break;case R.id.ilove:Intent intent = new Intent(this,MyLoveMusicActivity.class);startActivity(intent);System.out.println("我的收藏");break;case R.id.near_play:Intent intent2 = new Intent(this,MyRecordMusicActivity.class);startActivity(intent2);System.out.println("最近播放");break;}return true;}@Overrideprotected void onDestroy() {super.onDestroy();//保存当前播放的一些状态值DRMPlayerApp app = (DRMPlayerApp) getApplication();SharedPreferences.Editor editor = app.sp.edit();//保存 当前正在播放的歌曲的位置editor.putInt("currentPosition",playService.getCurrentPosition());//保存 播放模式editor.putInt("play_mode",playService.getPlay_mode());//保存 提交editor.commit();//创建DRMPlayerApp继承Application,同时需要在把AndroidManiFest中的public换成DRMPlayerApp//在DRMPlayerApp的onCreate中 实例化 SharedPreferences//在MainActivity的onDestroy中 保存状态值//在PlayService的onCreate中 恢复状态值}}



欢迎移动开发爱好者交流
沈阳或周边城市公司有意开发Android,请与我联系
联系方式

微信:iwanghang
QQ:413711276
邮箱:iwanghang@qq.com




转载请注明出处:http://blog.csdn.net/iwanghang/article/details/51448597

项目源码(打赏5积分请点这边):http://download.csdn.net/detail/iwanghang/9524502

项目源码(免积分下载请点这边):http://download.csdn.net/detail/iwanghang/9682928


Android开发本地及网络Mp3音乐播放器系列博文汇总:
Android开发本地及网络Mp3音乐播放器(一)前言
Android开发本地及网络Mp3音乐播放器(二)SplashActivity(欢迎界面)
Android开发本地及网络Mp3音乐播放器(三)MainActivity(主界面)
Android开发本地及网络Mp3音乐播放器(四)实现音乐播放
Android开发本地及网络Mp3音乐播放器(五)实现专辑封面图片
Android开发本地及网络Mp3音乐播放器(六)实现独立音乐播放界面
Android开发本地及网络Mp3音乐播放器(七)循环模式与专辑倒影
Android开发本地及网络Mp3音乐播放器(八)状态存取与界面滑动
Android开发本地及网络Mp3音乐播放器(九)音乐收藏与列表切换
Android开发本地及网络Mp3音乐播放器(十)最近播放界面与数据保存更新
Android开发本地及网络Mp3音乐播放器(十一)使用Jsoup组件请求网络,并解析音乐数据
Android开发本地及网络Mp3音乐播放器(十二)创建NetMusicListAdapter、SearchResult显示网络音乐列表
Android开发本地及网络Mp3音乐播放器(十三)网络音乐搜索功能实现,歌名歌手专辑名搜索
Android开发本地及网络Mp3音乐播放器(十四)网络音乐下载功能实现
Android开发本地及网络Mp3音乐播放器(十五)网络音乐及歌词下载功能实现
Android开发本地及网络Mp3音乐播放器(十六)歌词显示及滚动事件实现、ViewPager使用
Android开发本地及网络Mp3音乐播放器(十七)已存在歌曲歌词下载
Android开发本地及网络Mp3音乐播放器(十八)新下载歌曲加载准备SdcardSearchToList
Android开发本地及网络Mp3音乐播放器(十九)通知媒体库更新刚下载的MP3
Android开发本地及网络Mp3音乐播放器(二十)歌曲下载完成后通知主界面更新本地音乐


觉得博文有用,请点赞,请留言,请关注,谢谢!~

更多相关文章

  1. Android(安卓)kotlin网络请求框架fuel(简单方便的使用,提供项目中
  2. Android(安卓)多语言开发
  3. 开发者掌握Windows Phone的贴心工具
  4. Android开发适配器系列:AutoCompleteTextView和MultiAutoComplete
  5. andoid小游戏开发
  6. Android网络通信(1):Android网络基础
  7. Android版网络办公系统应用客户端+服务端
  8. Android(安卓)下载图片并显示在ImageView中
  9. Android(安卓)Studio 2.3.2 下载 - 百度网盘

随机推荐

  1. Android手机软件汉化教程---第五课 打包
  2. android 2.0发布
  3. 经典Android(安卓)人脸识别案例解析
  4. Android游戏开发一些心得(多个SurfaceView
  5. Android-下拉列表框Spinner的使用
  6. Android轻松搭建MVVM + Retrofit + RxJav
  7. 如何从oat文件中提取内嵌的dex文件
  8. 谷歌Java专利案面临败北:Android居然要考
  9. Android(安卓)NDK开发: 通过C/C++调用第
  10. android开发入门网站和书籍推荐