剖析Android Music Widget播放器

移动开发
Android Music Widget播放器是本文要介绍的内容,主要是来了解并学习Android自带Widget Music播放器的应用,具体内容来看本文详解。

Android Music Widget播放器是本文要介绍的内容,主要是来了解并学习Android自带Widget Music播放器的应用,具体内容来看本文详解。本文剖析Android自带widget-Music,其涉及到众多事件的处理,虽然麻烦,但可看出是如何和服务进行交互的。

首先我们看下music程序中AndroidManifest.xml中有关widgets的定义。

下面是xml/appwidget_info的内容,里面包含了这个widget程序的基本定义。

android:minWidth=”294dip” //最小宽度

android:minHeight=”72dip” //最小高度

android:updatePeriodMillis=”0″ //更新频率

android:initialLayout=”@layout/album_appwidget”> //widget界面布局文件

整个设计还是十分清晰,这里我们就不再做过多的赘述。

  1. public class MediaAppWidgetProvider extends AppWidgetProvider {  
  2.  
  3. public static final String CMDAPPWIDGETUPDATE = “appwidgetupdate”;  
  4.  
  5. static final ComponentName THIS_APPWIDGET =  
  6. new ComponentName(”com.android.music”, “com.android.music.MediaAppWidgetProvider”);  
  7.  
  8. private static MediaAppWidgetProvider sInstance;  
  9.  
  10. static synchronized MediaAppWidgetProvider getInstance() {  
  11. if (sInstance == null) {  
  12. sInstance = new MediaAppWidgetProvider();  
  13. }  
  14. return sInstance;  
  15. }  
  16.  
  17. @Override  
  18. public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {  
  19. defaultAppWidget(context, appWidgetIds);  
  20.  
  21. // 发送一个Intent广播给MediaPlaybackService以便立即更新  
  22.  
  23. Intent updateIntent = new Intent(MediaPlaybackService.SERVICECMD);  
  24. updateIntent.putExtra(MediaPlaybackService.CMDNAME,MediaAppWidgetProvider.CMDAPPWIDGETUPDATE);  
  25. updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);  
  26. updateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);  
  27. context.sendBroadcast(updateIntent);  
  28. }  
  29.  
  30. /*  
  31. * 初始化widget默认状态,如果服务没有运行,我们启动music的时候默认单击隐藏  
  32. */  
  33. private void defaultAppWidget(Context context, int[] appWidgetIds) {  
  34. final Resources res = context.getResources();  
  35. final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.album_appwidget);  
  36.  
  37. views.setViewVisibility(R.id.title, View.GONE);  
  38. views.setTextViewText(R.id.artist, res.getText(R.string.emptyplaylist));  
  39.  
  40. linkButtons(context, views, false /* 没有播放*/);  
  41. pushUpdate(context, appWidgetIds, views);  
  42. }  
  43.  
  44. private void pushUpdate(Context context, int[] appWidgetIds, RemoteViews views) {  
  45. // 更新指定的列表  
  46.  
  47. final AppWidgetManager gm = AppWidgetManager.getInstance(context);  
  48. if (appWidgetIds != null) {  
  49. gm.updateAppWidget(appWidgetIds, views);  
  50. } else {  
  51. gm.updateAppWidget(THIS_APPWIDGET, views);  
  52. }  
  53. }  
  54.  
  55. /**  
  56. * Check against {@link AppWidgetManager} if there are any instances of this widget.  
  57. */  
  58. private boolean hasInstances(Context context) {  
  59. AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);  
  60. int[] appWidgetIds = appWidgetManager.getAppWidgetIds(THIS_APPWIDGET);  
  61. return (appWidgetIds.length > 0);  
  62. }  
  63.  
  64. /**  
  65. * Handle a change notification coming over from {@link MediaPlaybackService}  
  66. */  
  67. void notifyChange(MediaPlaybackService service, String what) {  
  68. if (hasInstances(service)) {  
  69. if (MediaPlaybackService.PLAYBACK_COMPLETE.equals(what) ||  
  70. MediaPlaybackService.META_CHANGED.equals(what) ||  
  71. MediaPlaybackService.PLAYSTATE_CHANGED.equals(what)) {  
  72. performUpdate(service, null);  
  73. }  
  74. }  
  75. }  
  76.  
  77. /**  
  78. * Update all active widget instances by pushing changes  
  79. */  
  80. void performUpdate(MediaPlaybackService service, int[] appWidgetIds) {  
  81. final Resources res = service.getResources();  
  82. final RemoteViews views = new RemoteViews(service.getPackageName(), R.layout.album_appwidget);  
  83.  
  84. final int track = service.getQueuePosition() + 1;  
  85. CharSequence titleName = service.getTrackName();  
  86. CharSequence artistName = service.getArtistName();  
  87. CharSequence errorState = null;  
  88.  
  89. // Format title string with track number, or show SD card message  
  90. String status = Environment.getExternalStorageState();  
  91. if (status.equals(Environment.MEDIA_SHARED) ||  
  92. status.equals(Environment.MEDIA_UNMOUNTED)) {  
  93. errorState = res.getText(R.string.sdcard_busy_title);  
  94. } else if (status.equals(Environment.MEDIA_REMOVED)) {  
  95. errorState = res.getText(R.string.sdcard_missing_title);  
  96. } else if (titleName == null) {  
  97. errorState = res.getText(R.string.emptyplaylist);  
  98. }  
  99.  
  100. if (errorState != null) {  
  101. // Show error state to user  
  102. views.setViewVisibility(R.id.title, View.GONE);  
  103. views.setTextViewText(R.id.artist, errorState);  
  104.  
  105. } else {  
  106. // No error, so show normal titles  
  107. views.setViewVisibility(R.id.title, View.VISIBLE);  
  108. views.setTextViewText(R.id.title, titleName);  
  109. views.setTextViewText(R.id.artist, artistName);  
  110. }  
  111.  
  112. // Set correct drawable for pause state  
  113. final boolean playing = service.isPlaying();  
  114. if (playing) {  
  115. views.setImageViewResource(R.id.control_play, R.drawable.appwidget_pause);  
  116. } else {  
  117. views.setImageViewResource(R.id.control_play, R.drawable.appwidget_play);  
  118. }  
  119.  
  120. // Link actions buttons to intents  
  121. linkButtons(service, views, playing);  
  122.  
  123. pushUpdate(service, appWidgetIds, views);  
  124. }  
  125.  
  126. /**  
  127. * Link up various button actions using {@link PendingIntents}.  
  128. *  
  129. * @param playerActive True if player is active in background, which means  
  130. * widget click will launch {@link MediaPlaybackActivity},  
  131. * otherwise we launch {@link MusicBrowserActivity}.  
  132. */  
  133. private void linkButtons(Context context, RemoteViews views, boolean playerActive) {  
  134. // Connect up various buttons and touch events  
  135. Intent intent;  
  136. PendingIntent pendingIntent;  
  137.  
  138. final ComponentName serviceName = new ComponentName(context, MediaPlaybackService.class);  
  139.  
  140. if (playerActive) {  
  141. intent = new Intent(context, MediaPlaybackActivity.class);  
  142. pendingIntent = PendingIntent.getActivity(context,  
  143. 0 /* no requestCode */, intent, 0 /* no flags */);  
  144. views.setOnClickPendingIntent(R.id.album_appwidget, pendingIntent);  
  145. } else {  
  146. intent = new Intent(context, MusicBrowserActivity.class);  
  147. pendingIntent = PendingIntent.getActivity(context,  
  148. 0 /* no requestCode */, intent, 0 /* no flags */);  
  149. views.setOnClickPendingIntent(R.id.album_appwidget, pendingIntent);  
  150. }  
  151.  
  152. intent = new Intent(MediaPlaybackService.TOGGLEPAUSE_ACTION);  
  153. intent.setComponent(serviceName);  
  154. pendingIntent = PendingIntent.getService(context,  
  155. 0 /* no requestCode */, intent, 0 /* no flags */);  
  156. views.setOnClickPendingIntent(R.id.control_play, pendingIntent);  
  157.  
  158. intent = new Intent(MediaPlaybackService.NEXT_ACTION);  
  159. intent.setComponent(serviceName);  
  160. pendingIntent = PendingIntent.getService(context,  
  161. 0 /* no requestCode */, intent, 0 /* no flags */);  
  162. views.setOnClickPendingIntent(R.id.control_next, pendingIntent);  
  163. }  

小结:剖析Android Music Widget播放器的内容介绍完了,希望通过Android Music Widget内容的学习能对你有所帮助!

责任编辑:zhaolei 来源: 互联网
相关推荐

2011-09-08 13:36:26

Android Wid播放器

2011-06-13 09:33:04

2022-08-16 17:37:06

视频播放器鸿蒙

2015-01-22 15:44:55

Android源码音乐播放器

2010-10-26 09:00:48

Winamp应用

2011-06-27 11:23:21

Qt 音乐播放器

2011-04-06 10:03:45

谷歌云计算Android音

2017-03-01 14:01:31

android多媒体音乐代码

2010-07-30 09:35:47

Flex播放器

2011-07-20 16:21:20

iPhone 视频 播放器

2011-09-05 18:08:01

MTK音频播放器

2015-05-21 15:25:42

VLC播放器

2011-09-08 14:50:51

JavascriptWidget

2012-05-03 09:51:09

HTML5

2014-12-31 16:52:53

音乐播放器源码

2018-05-25 14:37:58

2009-12-17 15:10:31

Linux音乐播放器

2010-06-11 12:53:56

openSUSE播放器

2022-06-21 14:41:38

播放器适配西瓜视频

2023-04-06 13:47:47

点赞
收藏

51CTO技术栈公众号