按照前几篇博客的步骤,应该能看到自己手机里的音乐列表了,但是现在还只能看,不能点,还需要再给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;
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);
}
});
/*
音乐列表的点击监听器
点击后调用的方法,是一个回调方法,用来告诉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);
}
}
});
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中再次重写一遍
}
}
上面的监听器注册完毕之后,就换到MainActivity.java中去对点击时间做出处理,启动一个service.我们需要先在MainActivity中写一个初始化service的方法,MainActivity代码如下,红色部分为修改的部分:
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{
private boolean isPause; //记录当前播放器的状态
private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
private MyMusicFragment myMusicFragment;
private MainFragment mainFragment;
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();
}
}
public void onMyMusicFragmentInteraction(int msg,int position){
if(msg == AppConstant.PlayerMsg.LIST_CLICK){
if (mp3Infos != null) {
isPause = false;
initService(position);
}
}
}
@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);
}
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);
}
}
上面的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(); //
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();
}
}
上面的函数命名也都很简单,相信大家能够看懂,如果有什么问题,直接给我留言把,我会解答的哈......
做到了这一步,现在的播放器就可以点击并且播放歌曲了,点什么唱什么有木有,但是还是觉得怪怪的对不对,因为还不能暂停和切歌,不要担心,下一篇的博客中,将继续介绍如何把按钮的监听事件给加上去,到时候播放器的功能就差不多咯.今天就说这么多了,88

7864

被折叠的 条评论
为什么被折叠?



