Android 音乐播放器的开发教程(六)service的运用及音乐列表点击播放 ----- 小达
来源:互联网 发布:jsp个人博客系统源码 编辑:程序博客网 时间:2024/05/16 06:12
service的运用及音乐列表点击播放
按照前几篇博客的步骤,应该能看到自己手机里的音乐列表了,但是现在还只能看,不能点,还需要再给ListView添加点击事件的监听,接着启动一个Service来播放音乐,service是android四大组件之一,在官方的文档上是这样解释的:
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.
也就是说,Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。另外,一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content provider)交互,所有这些活动都是在后台进行。
我们先来给列表注册监听器,由于列表是显示在MyMusicFragment上面的,故注册监听器也应该在MyMusicFragment.java这个文件里面注册了,下面给出代码,红色部分为改动的地方:
package com.example.dada.myapplication;import android.app.Activity;import android.net.Uri;import android.os.Bundle;import android.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.ListView;import java.util.List;public class MyMusicFragment extends Fragment { private FindSongs finder; //查找歌曲的类的实例 private Activity MyActivity; private List<Mp3Info> mp3Infos; private MusicListAdapter musicListAdapter; private OnFragmentInteractionListener mListener;
<span style="color:#222222;"> public static MyMusicFragment newInstance() { MyMusicFragment fragment = new MyMusicFragment(); Bundle args = new Bundle(); fragment.setArguments(args); return fragment; } public MyMusicFragment() { // Required empty public constructor } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyActivity = getActivity(); finder = new FindSongs(); mp3Infos = finder.getMp3Infos(MyActivity.getContentResolver()); musicListAdapter = new MusicListAdapter(MyActivity.getApplicationContext(),mp3Infos); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { finder = new FindSongs(); View rootView = inflater.inflate(R.layout.fragment_my_music, container, false); /* 切换至我的音乐Fragment按钮监器 调用了在activity中已经重写了的方法onMyMusicFragmentInteraction */ rootView.findViewById(R.id.top_layout_right_ImageView). setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mListener.onMyMusicFragmentInteraction(AppConstant.PlayerMsg.BACK_TO_MAIN_FRAGMENT); } }); </span><span style="color:#ff0000;">/* 音乐列表的点击监听器 点击后调用的方法,是一个回调方法,用来告诉activity 列表里面的哪个项被点击了 让activity做出反应 */ ((ListView)rootView.findViewById(R.id.music_list)). setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (mp3Infos != null) { mListener.onMyMusicFragmentInteraction(AppConstant.PlayerMsg.LIST_CLICK, position); } } });</span><span style="color:#222222;"> finder.setListAdpter(MyActivity.getApplicationContext(), mp3Infos,(ListView)rootView.findViewById(R.id.music_list)); return rootView; } // TODO: Rename method, update argument and hook method into UI event public void onButtonPressed() { if (mListener != null) { } } @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (OnFragmentInteractionListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener"); } } @Override public void onDetach() { super.onDetach(); mListener = null; } public interface OnFragmentInteractionListener { public void onMyMusicFragmentInteraction(int msg); </span><span style="color:#ff0000;"> public void onMyMusicFragmentInteraction(int msg,int position); //这个方法要在MainActivity中再次重写一遍</span><span style="color:#222222;"> }}</span>
package com.example.dada.myapplication;import android.app.FragmentManager;import android.app.FragmentTransaction;import android.content.Intent;import android.net.Uri;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.widget.ImageButton;import java.util.List;public class MainActivity extends ActionBarActivity implements MainFragment.OnFragmentInteractionListener, MyMusicFragment.OnFragmentInteractionListener{ <span style="color:#ff0000;">private boolean isPause; //记录当前播放器的状态</span> private FragmentManager fragmentManager; private FragmentTransaction fragmentTransaction; private MyMusicFragment myMusicFragment; private MainFragment mainFragment; <span style="color:#ff0000;">private FindSongs finder; //查找歌曲的类 public static List<Mp3Info> mp3Infos; //歌曲列表 public static int music_position; //音乐的位置 private ImageButton play_button; //播放按钮控件</span> /* 这个方法是activity和fragment通信的一种方法 在MainFragment中调用这个方法,可以在activity中做出相应的反应 */ public void onMainFragmentInteraction(int msg){ /* 对其中的参数msg做出判断,如果为CHANGE_TO_MY_MUSIC_FRAGMENT 则执行跳转 */ if(msg == AppConstant.PlayerMsg.CHANGE_TO_MY_MUSIC_FRAGMENT){ /* 在这里并没有直接切换Fragment 而是调用了activity实现MyMusicFragment的那个接口 对后面的开发能带来一点便利之处 */ onMyMusicFragmentInteraction(AppConstant.PlayerMsg.CHANGE_TO_MY_MUSIC_FRAGMENT); } } public void onMyMusicFragmentInteraction(int msg){ myMusicFragment = new MyMusicFragment(); //创建了MyMusicFragment的实例 FragmentManager fragmentManager = getFragmentManager(); //得到FragmentManager FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); //得到fragmentTransaction if(msg == AppConstant.PlayerMsg.CHANGE_TO_MY_MUSIC_FRAGMENT){ fragmentTransaction.replace(R.id.fragment_layout, myMusicFragment);
fragmentTransaction.addToBackStack(null); //这句话是将被替换的MainFragment加入到一个专门存放fragment的栈中,在回退的时候显示上一个Fragment fragmentTransaction.commit(); } if(msg == AppConstant.PlayerMsg.BACK_TO_MAIN_FRAGMENT){ fragmentTransaction.replace(R.id.fragment_layout, mainFragment); fragmentTransaction.addToBackStack(null); fragmentTransaction.commit(); } } <span style="color:#ff0000;">public void onMyMusicFragmentInteraction(int msg,int position){ if(msg == AppConstant.PlayerMsg.LIST_CLICK){ if (mp3Infos != null) { isPause = false; initService(position); } } }</span> @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); music_position = 0; finder = new FindSongs(); mp3Infos = finder.getMp3Infos(getContentResolver()); play_button = (ImageButton)findViewById(R.id.play_button); mainFragment = new MainFragment(); //创建了刚才定义的MainFragment实例 fragmentManager = getFragmentManager(); //得到FragmentManager fragmentTransaction = fragmentManager.beginTransaction(); //得到fragmentTransaction,用于管理fragment的切换 fragmentTransaction.replace(R.id.fragment_layout, mainFragment).commit(); //将MainActivity里的布局模块fragment_layout替换为mainFragment } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public 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(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } <span style="color:#ff0000;">private void initService(int position) { music_position = position; Mp3Info mp3Info = mp3Infos.get(position); /* 这里新建了一个Intent 里面存放各种即将传给Service的数据 要启动自定义PlayerService类 还需要在AndroidManifest中加入如下代码 <service android:name="com.example.dada.myapplication.PlayerService" android:exported="false" > </service> */ Intent intent = new Intent("com.example.communication.MSG_ACTION"); play_button.setImageResource(R.drawable.pause_photo); intent.putExtra("url", mp3Info.getUrl()); intent.putExtra("title", mp3Info.getTitle()); intent.putExtra("artist", mp3Info.getArtist()); intent.putExtra("album", mp3Info.getAlbum()); intent.putExtra("album_id", mp3Info.getAlbum_id()); intent.putExtra("MSG", AppConstant.PlayerMsg.PLAY_MSG); intent.setClass(MainActivity.this, PlayerService.class); startService(intent); }</span>}
上面的startService(intent)是启动service的一种方法,将intent传给新启动的PlayerService,接下来就是自定义的一个PlayerService类,里面对传进来的intent进行各种判断和处理.新建一个java类,名为PlayerService.java,代码如下:
package com.example.dada.myapplication;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.media.MediaPlayer;import android.os.Handler;import android.os.IBinder;import android.os.Looper;import android.os.Message;import android.view.animation.AnimationUtils;import android.widget.RemoteViews;import java.io.IOException;import java.util.ArrayList;import java.util.List;public class PlayerService extends Service implements AppConstant { private int current_position; private String musicPath; private String music_artist; private String music_title; private String notification_msg; @Override public IBinder onBind(Intent intent) { return null; }
/*
onStartCommand()方法就是刚启动service时调用的一个方法
里面第一个参数intent就是在activity中的那个intent
因此里面包含着被点击的歌曲相关信息
*/ public int onStartCommand(Intent intent, int flags, int startId) {
public static MediaPlayer mediaPlayer = new MediaPlayer(); //MediaPlayer是android中自带的一个播放器类,直接实例化后使用即可
try { int msg = intent.getIntExtra("MSG", 0); musicPath = intent.getStringExtra("url"); //从intent中拿出歌曲的路径 if (msg == AppConstant.PlayerMsg.PLAY_MSG) { playMusic(0); } } catch (Exception e) { e.printStackTrace(); } return 0; } private void playMusic(int position) { try { mediaPlayer.reset(); mediaPlayer.setDataSource(musicPath); mediaPlayer.prepare(); mediaPlayer.setOnPreparedListener(new MyPreparedListener(position)); } catch (IOException e) { e.printStackTrace(); } } private class MyPreparedListener implements MediaPlayer.OnPreparedListener { private int position; public MyPreparedListener(int position) { this.position = position; } public void onPrepared(MediaPlayer mp) { if (position > 0) mediaPlayer.seekTo(position); mediaPlayer.start(); } } private void stopMusic() { if (mediaPlayer != null) { mediaPlayer.pause(); } } public void onDestory() { if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.release(); } }}
上面的函数命名也都很简单,相信大家能够看懂,如果有什么问题,直接给我留言把,我会解答的哈.......2333333
做到了这一步,现在的播放器就可以点击并且播放歌曲了,点什么唱什么有木有,但是还是觉得怪怪的对不对,,因为还不能暂停和切歌,不要担心,下一篇的博客中,将继续介绍如何把按钮的监听事件给加上去,到时候播放器的功能就差不多咯.今天就说这么多了,88
- Android 音乐播放器的开发教程(六)service的运用及音乐列表点击播放 ----- 小达
- Android 音乐播放器的开发教程(七)运用Broadcast实现service与activity的通信 ----- 小达
- Android 音乐播放器的开发教程(五)本地音乐的获取及显示 ----- 小达
- Android 音乐播放器的开发教程(十一)SQLite的使用及最近播放的实现 ----- 小达
- Android 音乐播放器的开发教程(三) 小卷毛播放器的主界面开发 ---- 小达
- Android 音乐播放器的开发教程(九) 歌词的显示----- 小达
- Android 音乐播放器的开发教程(十)通知栏Notification的使用 ----- 小达
- Android 音乐播放器的开发教程(一) ----- 小达
- Android 音乐播放器的开发教程(二)反编译apk ----- 小达
- Android的音乐播放器使用service
- Android开发之基于Service的音乐播放器
- Android开发之基于Service的音乐播放器
- Android开发之基于Service的音乐播放器
- Android 音乐播放器的开发教程(四)Activity和Fragment的通信以及Fragment的切换 ----- 小达
- Android 音乐播放器的开发教程(八)歌曲的切换和进度条的拖动 ----- 小达
- Android 音乐播放器的开发教程(十二)SQLite的使用及我的最爱歌曲的实现 ----- 小达
- 自己动手开发音乐播放器《六》播放方式的实现
- Android开发本地及网络Mp3音乐播放器(六)实现独立音乐播放界面
- 01背包 页面布局
- 栈的简单操作(顺序结构存储)
- C语言中extern的用法
- 在连接到SQL Server2005时,在默认的设置下SQL Server不允许进行远程连接可能会导致此失败--的解决
- Linux xhost命令详解
- Android 音乐播放器的开发教程(六)service的运用及音乐列表点击播放 ----- 小达
- 消息队列技术终结者(三)—ActiveMQ的特性及优势
- UVA 409-Excuses, Excuses!(模拟)
- 移动支付sdk技术总结-2(混淆打包)
- UVA 620 Cellular Structure(dfs)
- 黑马程序员—Java入门学习日记基础篇-面向对象总结3
- JUnit4 使用进阶一
- 韩顺平php视频笔记35 php运行过程
- GVIM主题配置文件_vimrc