桌面widget详解(二)—— 基本的与service通信
来源:互联网 发布:java导出excel表格逻辑 编辑:程序博客网 时间:2024/05/03 23:04
前言:发现只有让自己忙起来,内心才会感到舒畅,才没有罪恶感,男人好像也有大姨妈,一个月总想懒那么几天,懒到极限的时候就又开始继续前行。哈哈
相关文章:
1、《桌面widget详解(一)——基本demo构建》
2、《桌面widget详解(二)—— 基本的与service通信》
3、《桌面widget详解(三)——桌面widget中的控件交互方法》
4、《桌面widget详解(四)——桌面音乐播放器(实战)》
因为我们的widget是没有办法像Activity一样根据ID获取到View对象的,所以根本没有办法在widget代码中直接操作,只能通过Service来间接交互操作(看不懂没关系,下篇会具体讲);如果我一上来就讲如何与Service交互,大家可能一头雾水。因为Service本身就不是个简单的东东。所以我先岔开话题,讲讲我们如何在MainActivity中实现一个音乐播放器的雏形。这篇主要在于理解Service的机制与如何与Service交互的问题。
看一下效果图:
点击开始btn,开始播放歌曲,并显示当前播放歌曲的id号,然后点击上一首,下一首按钮时播放序列中的上一首或者下一首歌,并实时更新当前的歌曲ID;
一、播放歌曲的Service(MusicManageService)
首先,我们先放工程里九首歌,放在res/raw文件夹下。
现在有的音乐文件以后,我们要在service里实现一个歌曲文件的列表,以及播放上一首,一下首的功能。
先贴出完整的代码,然后再逐步讲解。
public class MusicManageService extends Service {private MediaPlayer mPlayer;private int mIndex = 4;// 从中间开始放private int[] mArrayList = new int[9];@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();initList();mediaPlayerStart();}private void initList() {mArrayList[0] = R.raw.dui_ni_ai_bu_wan;mArrayList[1] = R.raw.fei_yu;mArrayList[2] = R.raw.gu_xiang_de_yun;mArrayList[3] = R.raw.hen_ai_hen_ai_ni;mArrayList[4] = R.raw.new_day;mArrayList[5] = R.raw.shi_jian_li_de_hua;mArrayList[6] = R.raw.ye_gui_ren;mArrayList[7] = R.raw.yesterday_once_more;mArrayList[8] = R.raw.zai_lu_shang;}private void mediaPlayerStart(){mPlayer = new MediaPlayer();mPlayer = MediaPlayer.create(getApplicationContext(), mArrayList[mIndex]);mPlayer.start();}@Overridepublic void onDestroy() {super.onDestroy();mPlayer.stop();}/** * 播放下一首 * * @param context */public void playNext(Context context) {if (++mIndex > 8) {mIndex = 0;}playSong(context, mArrayList[mIndex]);}/** * 播放上一首 * * @param context */public void playPrev(Context context) {if (--mIndex < 0) {mIndex = 8;}playSong(context, mArrayList[mIndex]);}/* * 继续播放 */public void play(Context context) {mPlayer.start();}/** * 暂停播放 * * @param context */public void pause(Context context) {mPlayer.pause();}/** * 播放指定的歌曲 * * @param context * @param resid */private void playSong(Context context, int resid) {AssetFileDescriptor afd = context.getResources().openRawResourceFd(mArrayList[mIndex]);try {mPlayer.reset();mPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getDeclaredLength());mPlayer.prepare();mPlayer.start();afd.close();} catch (Exception e) {Log.e("harvic","Unable to play audio queue do to exception: "+ e.getMessage(), e);}}}首先要清楚的一点是,我们播放歌曲是利用系统内置的MediaPlayer来做的。
1、OnCreate()
我们先看有关初始化的部分。因为我们要有上一首,下一首的功能,所以首先我们要做的是做一个链表,以找到当前播放歌曲的上一首,下一首歌曲的ID值。下面,就是代码,我利用一个整型数组(private int[] mArrayList = new int[9])来存储所有歌曲的资源ID;然后利用一个变量mIndex来标识当前播放歌曲的位置。初始化为4,即默认从中间的歌曲开始放,即R.raw.new_day;
private void initList() {mArrayList[0] = R.raw.dui_ni_ai_bu_wan;mArrayList[1] = R.raw.fei_yu;mArrayList[2] = R.raw.gu_xiang_de_yun;mArrayList[3] = R.raw.hen_ai_hen_ai_ni;mArrayList[4] = R.raw.new_day;mArrayList[5] = R.raw.shi_jian_li_de_hua;mArrayList[6] = R.raw.ye_gui_ren;mArrayList[7] = R.raw.yesterday_once_more;mArrayList[8] = R.raw.zai_lu_shang;}在OnCreate()函数中,初了始始化部分,我们还应该让歌曲开始播放,因为用户start我们的service的目的就是播放歌曲,所以在OnCreate()中应该初始化MedaiPlayer然后播放默认的的歌曲。即:
private void mediaPlayerStart(){mPlayer = new MediaPlayer();mPlayer = MediaPlayer.create(getApplicationContext(), mArrayList[mIndex]);mPlayer.start();}2、OnDestroy()
在用户销毁我们的Service时,应该让MediaPlayer停止,所以在OnDestroy()中有下面的代码:
@Overridepublic void onDestroy() {super.onDestroy();mPlayer.stop();}3、播放、暂停
这两个功能是最简单的,直接调用MediaPlayer的函数就能实现,代码如下 ,不再细讲
public void play(Context context) {mPlayer.start();}public void pause(Context context) {mPlayer.pause();}4、上一首、下一首
这部分应该是有些难度的,首先,我们要实现根据歌曲资源ID,播放歌曲,代码如下:
private void playSong(Context context, int resid) {AssetFileDescriptor afd = context.getResources().openRawResourceFd(mArrayList[mIndex]);try {mPlayer.reset();mPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getDeclaredLength());mPlayer.prepare();mPlayer.start();afd.close();} catch (Exception e) {Log.e("harvic","Unable to play audio queue do to exception: "+ e.getMessage(), e);}}在mPlayer换歌曲时,先Reset()一下,把MediaPlayer中的资源重置,然后再利用setDataSource()来设置歌曲资源。一定 要注意的是在Start()之前,要调用Prepare()一下。
然后是上一首的实现:
public void playPrev(Context context) {if (--mIndex < 0) {mIndex = 8;}playSong(context, mArrayList[mIndex]);}因为我们是利用mIndex来标识当前歌曲的索引,所以当mIndex等于0时,就表示到了第一首歌,那我们就给他循环一下,把它置到最后一首;然后播放。
下一首也是同理,当歌曲索引mIndex到了最后一首时,我们将其置为第一首,代码如下:
public void playNext(Context context) {if (++mIndex > 8) {mIndex = 0;}playSong(context, mArrayList[mIndex]);}好了,到这里,初级的歌曲播放的所有基本功能我们算是实现了。
注册Service
上面我们就把Service的雏形写好了,下面要想将Service能启动起来,就必须在AndroidManifest.xml中注册,注册代码如下:
<service android:name="com.example.trywidgetsimplest.MusicManageService" ></service> <!-- 注意service名称,必须是从包定位到类名 -->一定要注意的是android:name的值一定要从包名开始,一直定位到类名。完整的AndroidManifest.xml代码如下:
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 声明widget对应的AppWidgetProvider --> <receiver android:name=".ExampleAppWidgetProvider" > <intent-filter><action android:name="android.appwidget.action.APPWIDGET_UPDATE" /><action android:name="com.skywang.widget.UPDATE_ALL"/></intent-filter><meta-data android:name="android.appwidget.provider"android:resource="@xml/example_appwidget_info" /> </receiver> <service android:name="com.example.trywidgetsimplest.MusicManageService" ></service> <!-- 注意service名称,必须是从包定位到类名 --> </application>
二、MainActivity雏形构建
从最上头的演示界面也可以看到我们要做的界面是什么样子的,下面列出MainAcitivity的布局代码(activity_main.xml)<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#33000000" > <TextView android:id="@+id/song_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dip" android:gravity="center_horizontal" android:textSize="14sp" android:text="song name"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="60dp" android:gravity="center_horizontal" android:orientation="horizontal" > <TextView android:id="@+id/prev_song" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dip" android:background="@drawable/car_musiccard_up" /> <TextView android:id="@+id/play_pause" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="8dip" android:background="@drawable/car_musiccard_play" /> <TextView android:id="@+id/next_song" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/car_musiccard_down" /> </LinearLayout></FrameLayout>下面就是控件的响应实现了,实现的逻辑是:当我们第一次点击播放按钮时startService(),然后在onDestroy()的时候stopService();完整的代码如下,然后再细讲:
public class MainActivity extends Activity {private TextView btn_pre, btn_play_pause, btn_next,songID_tv;private int i = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initCtrls();}private void initCtrls() {btn_pre = (TextView) findViewById(R.id.prev_song);btn_play_pause = (TextView) findViewById(R.id.play_pause);btn_next = (TextView) findViewById(R.id.next_song);songID_tv = (TextView)findViewById(R.id.song_name);btn_pre.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub}});btn_play_pause.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubi++;if (i == 1) {Intent startIntent = new Intent(MainActivity.this,MusicManageService.class);startService(startIntent);}}});btn_next.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub}});}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubIntent startIntent = new Intent(MainActivity.this,MusicManageService.class);stopService(startIntent);super.onDestroy();}}对于初始化控件及按钮的onClick响应这些东东就没必要讲了,关键在于这段代码:
btn_play_pause.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubi++;if (i == 1) {Intent startIntent = new Intent(MainActivity.this,MusicManageService.class);startService(startIntent);}}});我们这里定义一个变量i,初始化为0,用户每次点击都会加1,但只有用户第一次点击时才会启动StartService。下面看看stopService的代码:
@Overrideprotected void onDestroy() {// TODO Auto-generated method stubIntent startIntent = new Intent(MainActivity.this,MusicManageService.class);stopService(startIntent);super.onDestroy();}在MainActivity销毁时,利用stopService来停止Service;到这里,我们MainActivity的基本雏形就完成了,下面就是如何与Service交互的问题了。
三、MainActivity控制MusicManageService播放状态
从这里开始就开始涉及MainActivity与MusicManageService交互的内容了,交互分为两部分,第一部分就MainActivity的按钮控制MusicManageService的播放状态。第二部分是MusicManageService将最新的播放状态回送给MainActivity让它更新当前的播放状态和当前播放歌曲的id值。这里先讲如何通过MainActivity的按钮控制MusicManageService的播放状态。
我们与Service通信,一般使用BroadcastReciver,当然也可以使用以前我曾经讲过的EventBus,其实使用EventBus是最好的选择,考虑到很多同学对EventBus不太清楚,这里选择使用BroadcastReciver来实现通信。有关BroadcastReciver的基础使用部分,参见:《BroadcastReceiver详解》 如果想延伸了解EventBus,请看这两篇:《EventBus使用详解(一)——初步使用EventBus》和《EventBus使用详解(二)——EventBus使用进阶》 ,好了,就啰嗦到这,下面开整。
1、MusicManageService中注册及接收处理消息
首先,我们要在MusicManageService接收MainActivity发送来的消息,所以我们在MusicManageService就要注册BroadcastReciver(这里使用动态注册),然后接收消息并处理,代码如下:写贴出完整代码,然后再细讲:
public class MusicManageService extends Service {private MediaPlayer mPlayer;private int mIndex = 4;// 从中间开始放private int[] mArrayList = new int[9];public static String USR_ACTION = "usr_action_to_service";public static String KEY_USR_ACTION = "key_usr_action";public static final int ACTION_PRE = 0, ACTION_PLAY_PAUSE = 1, ACTION_NEXT = 2;private boolean mPlayState = false;private BroadcastReceiver receiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (USR_ACTION.equals(action)) {int widget_action = intent.getIntExtra(KEY_USR_ACTION, -1);switch (widget_action) {case ACTION_PRE:playPrev(context);break;case ACTION_PLAY_PAUSE:if (mPlayState) {pause(context);}else{play(context);}break;case ACTION_NEXT:playNext(context);break;default:break;}}}};@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(USR_ACTION);registerReceiver(receiver, intentFilter);initList();mediaPlayerStart();mPlayState = true;}private void initList() {mArrayList[0] = R.raw.dui_ni_ai_bu_wan;mArrayList[1] = R.raw.fei_yu;mArrayList[2] = R.raw.gu_xiang_de_yun;mArrayList[3] = R.raw.hen_ai_hen_ai_ni;mArrayList[4] = R.raw.new_day;mArrayList[5] = R.raw.shi_jian_li_de_hua;mArrayList[6] = R.raw.ye_gui_ren;mArrayList[7] = R.raw.yesterday_once_more;mArrayList[8] = R.raw.zai_lu_shang;}private void mediaPlayerStart(){mPlayer = new MediaPlayer();mPlayer = MediaPlayer.create(getApplicationContext(), mArrayList[mIndex]);mPlayer.start();}@Overridepublic void onDestroy() {super.onDestroy();mPlayer.stop();}/** * 播放下一首 * * @param context */public void playNext(Context context) {if (++mIndex > 8) {mIndex = 0;}playSong(context, mArrayList[mIndex]);mPlayState = true;}/** * 播放上一首 * * @param context */public void playPrev(Context context) {if (--mIndex < 0) {mIndex = 8;}playSong(context, mArrayList[mIndex]);mPlayState = true;}/* * 继续播放 */public void play(Context context) {mPlayer.start();mPlayState = true;}/** * 暂停播放 * * @param context */public void pause(Context context) {mPlayer.pause();mPlayState = false;}/** * 播放指定的歌曲 * * @param context * @param resid */private void playSong(Context context, int resid) {AssetFileDescriptor afd = context.getResources().openRawResourceFd(mArrayList[mIndex]);try {mPlayer.reset();mPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getDeclaredLength());mPlayer.prepare();mPlayer.start();afd.close();} catch (Exception e) {Log.e("harvic","Unable to play audio queue do to exception: "+ e.getMessage(), e);}}}
首先是定义几个变量:
public static String USR_ACTION = "usr_action_to_service";public static String KEY_USR_ACTION = "key_usr_action";public static final int ACTION_PRE = 0, ACTION_PLAY_PAUSE = 1, ACTION_NEXT = 2;private boolean mPlayState = false;USR_ACTION 用来标识发送来的Action;
KEY_USR_ACTION:用来标识发送来的动作的key;
ACTION_PRE = 0, ACTION_PLAY_PAUSE = 1, ACTION_NEXT = 2;是定义的用户动作,是点的暂停播放按钮,还是上一首,下一首按钮。
mPlayState是用来标识当前歌曲是播放状态还是暂停状态。因为我们只有一个按钮来操作播放暂停,用户在点击播放暂停按钮时发来消息都是ACTION_PLAY_PAUSE,所以我们要标识当前的状态是播放的还是暂停的,如果是暂停,在收到ACTION_PLAY_PAUSE消息时就播放歌曲,如果是播放,就暂停。
然后是接收器:
private BroadcastReceiver receiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (USR_ACTION.equals(action)) {int widget_action = intent.getIntExtra(KEY_USR_ACTION, -1);switch (widget_action) {case ACTION_PRE:playPrev(context);break;case ACTION_PLAY_PAUSE:if (mPlayState) {pause(context);}else{play(context);}break;case ACTION_NEXT:playNext(context);break;default:break;}}}};这接收器中,先判断当前发来的action是不是我们所需要的USR_ACTION,如果是就进一步判断当前的用户动作,并根据用户动作调用不同的播放函数如play(),pause()等。
最后一步就是注册接收器,注册接收器当然是在OnCreate()函数中,即当我们的service被start起来,就开始接收用户动作消息。这里还有个问题就是,当我们StartService的时候就已经开始播放歌曲了,所以要在OnCreate()中在mediaPlayerStart()后将mPlayState赋为true;
2、MainActivity中发送消息
发送消息就比较简单了,就是根据在各个按钮的onClickListener中根据不同的按钮点击发送不同的消息就是了,代码如下:
public class MainActivity extends Activity {private TextView btn_pre, btn_play_pause, btn_next,songID_tv;private int i = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initCtrls();}private void initCtrls() {btn_pre = (TextView) findViewById(R.id.prev_song);btn_play_pause = (TextView) findViewById(R.id.play_pause);btn_next = (TextView) findViewById(R.id.next_song);songID_tv = (TextView)findViewById(R.id.song_name);btn_pre.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {postAction(MainActivity.this, MusicManageService.ACTION_PRE);}});btn_play_pause.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {i++;if (i == 1) {Intent startIntent = new Intent(MainActivity.this,MusicManageService.class);startService(startIntent);}postAction(MainActivity.this,MusicManageService.ACTION_PLAY_PAUSE);}});btn_next.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {postAction(MainActivity.this, MusicManageService.ACTION_NEXT);}});}private void postAction(Context context, int usr_action) {Intent actionIntent = new Intent(MusicManageService.USR_ACTION);actionIntent.putExtra(MusicManageService.KEY_USR_ACTION, usr_action);context.sendBroadcast(actionIntent);}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubIntent startIntent = new Intent(MainActivity.this,MusicManageService.class);stopService(startIntent);super.onDestroy();}}这部分其实没什么好讲的,要讲的话也就说说这个postAction函数吧:
private void postAction(Context context, int usr_action) {Intent actionIntent = new Intent(MusicManageService.USR_ACTION);actionIntent.putExtra(MusicManageService.KEY_USR_ACTION, usr_action);context.sendBroadcast(actionIntent);}首先构建一个intent,然后把用户当前的操作利用pustExtra传进去,最后利用context.sendBroadcast(actionIntent);发送出去,无比简单。就不再讲了。
到这里呢,有关控制播放的部分就讲完了,下面就是更新MainActivity的界面了,同样也还是利用BroadcastReceiver,由于多个BroadcastReceiver会让人搞的有些迷,所以这里我给出上面的所有代码的工程。这个工程虽然不能实时更新UI,但已经可以控件歌曲了。
源码放在文章最后。
四、MusicManageService回送消息更新MainActivity的界面
这部分也是利用BroadcastReceiver,只不过变成了接收方,而MusicManageService成为了发送方;
1、MainActivity接收消息
新代码如下 ,无外乎也就是注册接收器,接收消息,处理消息,就不再细讲了.难度不大.
public class MainActivity extends Activity {private TextView btn_pre, btn_play_pause, btn_next,songID_tv;private int i = 0;public static String MAIN_ACTIVITY_UPDATE_UI = "main_activity_update_ui";public static String KEY_MAIN_ACTIVITY_UI_BTN = "main_activity_ui_btn_key";public static String KEY_MAIN_ACTIVITY_UI_TEXT = "main_activity_ui_text_key";public static final int VAL_UPDATE_UI_PLAY = 1,VAL_UPDATE_UI_PAUSE =2;BroadcastReceiver receiver = new BroadcastReceiver(){public void onReceive(Context context, Intent intent) {if (intent == null) {return;}String action = intent.getAction();if (MAIN_ACTIVITY_UPDATE_UI.equals(action)) {int play_pause = intent.getIntExtra(KEY_MAIN_ACTIVITY_UI_BTN, -1);int text = intent.getIntExtra(KEY_MAIN_ACTIVITY_UI_TEXT, -1);switch (play_pause) {case VAL_UPDATE_UI_PLAY:btn_play_pause.setBackgroundResource(R.drawable.car_musiccard_pause);songID_tv.setText("current sond id:"+text);Log.d("harvic","received play");break;case VAL_UPDATE_UI_PAUSE:btn_play_pause.setBackgroundResource(R.drawable.car_musiccard_play);songID_tv.setText("current sond id:" + text);Log.d("harvic","received pause");break;default:break;}}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(MAIN_ACTIVITY_UPDATE_UI);registerReceiver(receiver, intentFilter);initCtrls();}……………………//其它代码一样,就不再列出
2、MusicManageService发送消息
这块就是在播放歌曲,暂停歌曲,上一首,下一首时都要发消息给MainActivity,让它更新UIpublic class MusicManageService extends Service {private MediaPlayer mPlayer;private int mIndex = 4;// 从中间开始放private int[] mArrayList = new int[9];public static String USR_ACTION = "usr_action_to_service";public static String KEY_USR_ACTION = "key_usr_action";public static final int ACTION_PRE = 0, ACTION_PLAY_PAUSE = 1, ACTION_NEXT = 2;private boolean mPlayState = false;private BroadcastReceiver receiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (USR_ACTION.equals(action)) {int widget_action = intent.getIntExtra(KEY_USR_ACTION, -1);switch (widget_action) {case ACTION_PRE:playPrev(context);break;case ACTION_PLAY_PAUSE:if (mPlayState) {pause(context);}else{play(context);}break;case ACTION_NEXT:playNext(context);break;default:break;}}}};@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(USR_ACTION);registerReceiver(receiver, intentFilter);initList();mediaPlayerStart();mPlayState = true;}private void initList() {mArrayList[0] = R.raw.dui_ni_ai_bu_wan;mArrayList[1] = R.raw.fei_yu;mArrayList[2] = R.raw.gu_xiang_de_yun;mArrayList[3] = R.raw.hen_ai_hen_ai_ni;mArrayList[4] = R.raw.new_day;mArrayList[5] = R.raw.shi_jian_li_de_hua;mArrayList[6] = R.raw.ye_gui_ren;mArrayList[7] = R.raw.yesterday_once_more;mArrayList[8] = R.raw.zai_lu_shang;}private void mediaPlayerStart(){mPlayer = new MediaPlayer();mPlayer = MediaPlayer.create(getApplicationContext(), mArrayList[mIndex]);mPlayer.start();postState(getApplicationContext(), MainActivity.VAL_UPDATE_UI_PLAY,mIndex);}@Overridepublic void onDestroy() {super.onDestroy();mPlayer.stop();}/** * 播放下一首 * * @param context */public void playNext(Context context) {if (++mIndex > 8) {mIndex = 0;}playSong(context, mArrayList[mIndex]);mPlayState = true;postState(context, MainActivity.VAL_UPDATE_UI_PLAY,mIndex);}/** * 播放上一首 * * @param context */public void playPrev(Context context) {if (--mIndex < 0) {mIndex = 8;}playSong(context, mArrayList[mIndex]);mPlayState = true;postState(context, MainActivity.VAL_UPDATE_UI_PLAY,mIndex);}/* * 继续播放 */public void play(Context context) {mPlayer.start();mPlayState = true;postState(context, MainActivity.VAL_UPDATE_UI_PLAY,mIndex);}/** * 暂停播放 * * @param context */public void pause(Context context) {mPlayer.pause();mPlayState = false;postState(context, MainActivity.VAL_UPDATE_UI_PAUSE,mIndex);}/** * 播放指定的歌曲 * * @param context * @param resid */private void playSong(Context context, int resid) {AssetFileDescriptor afd = context.getResources().openRawResourceFd(mArrayList[mIndex]);try {mPlayer.reset();mPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getDeclaredLength());mPlayer.prepare();mPlayer.start();afd.close();} catch (Exception e) {Log.e("harvic","Unable to play audio queue do to exception: "+ e.getMessage(), e);}}private void postState(Context context, int state,int songid) {Intent actionIntent = new Intent(MainActivity.MAIN_ACTIVITY_UPDATE_UI);actionIntent.putExtra(MainActivity.KEY_MAIN_ACTIVITY_UI_BTN,state);actionIntent.putExtra(MainActivity.KEY_MAIN_ACTIVITY_UI_TEXT, songid);context.sendBroadcast(actionIntent);}}新增的就是PostState ()函数来发送消息,然后在不同的位置调用而已,难度不大,就不再讲了,下面给出源码了。
本文源码包含两部分:
1、part1《MainActivity控制MusicManageService播放状态---源码》 :这是截止到第三部分的所有源码,即BroadCastReceiver仅仅是MainActivity控制MusicManageService播放状态的部分。这里虽然功能不全面,但便于大家理解。
2、Part2 《MusicManageService回送消息更新MainActivity的界面-----源码》:这是完整的代码,运行效果与文章开头的效果展示一致。
如果本文有帮到你,记得关注哦
源码下载地址:
part1《MainActivity控制MusicManageService播放状态---源码》:http://download.csdn.net/detail/harvic880925/8207697
Part2 《MusicManageService回送消息更新MainActivity的界面-----源码》:http://download.csdn.net/detail/harvic880925/8207707
请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/41553177 谢谢!
- 桌面widget详解(二)—— 基本的与service通信
- 桌面widget详解(二)—— 基本的与service通信
- 桌面widget详解(一)——基本demo构建
- 桌面widget详解(一)——基本demo构建
- 桌面widget详解(一)——基本demo构建
- 桌面widget详解(一)——基本demo构建
- 桌面widget详解(三)——桌面widget中的控件交互方法
- 桌面widget详解(三)——桌面widget中的控件交互方法
- android的一些总结——service(二)之activity与service之间的通信
- 桌面widget详解(四)——桌面音乐播放器(实战)
- 桌面widget详解(四)——桌面音乐播放器(实战)
- Widget与service利用BroadcastReceiver通信
- Android Widget 开发详解(二)——支持listView滑动的widget
- Android Service(服务)详解·(二)Service基本用法
- Binder与Service 通信机制详解二 (Binder与Service理解)
- 桌面widget的大小
- android widget 开发实例 : 桌面便签程序的实现详解和源码 (上)
- android widget 开发实例 : 桌面便签程序的实现详解和源码 (下)
- 如何让button点一下凹进去效果
- Unity新UI系统概述——Visual Components
- Android中shape中的属性大全
- LINUX学习经历
- Java中Runnable和Thread的区别
- 桌面widget详解(二)—— 基本的与service通信
- 用jrebel实现 jvm热部署,修改类不用重启tomcat
- apktool+dex2jar+xjad反编译android程序
- JAVA 编程规范
- 如何编写无法维护的代码(现实中有的程序员就是这么干的)
- 解析Qt中QThread使用方法
- volatile修饰变量的用法。
- [SDOI2010]猪国杀
- 宏定义,条件编译,const static