展会信息港展会大全

Android自带Widget – Music播放器分析
来源:互联网   发布日期:2015-10-03 10:39:38   浏览:2473次  

导读:今天我们继续android自带widget剖析,相对于alarmclock而言music程序稍微复杂些,主要是涉 及到众多事件的处理,不过可以看出如何是和服务进行交互的。继续按照昨天的分析步骤和过程,首先我们看下music程序中 ......

今天我们继续android自带widget剖析,相对于alarmclock而言music程序稍微复杂些,主要是涉 及到众多事件的处理,不过可以看出如何是和服务进行交互的。继续按照昨天的分析步骤和过程,首先我们看下music程序中 AndroidManifest.xml中有关widgets的定义。

<receiver android:name= MediaAppWidgetProvider >

<intent-filter>

<action android:name= android.appwidget.action.APPWIDGET_UPDATE/>

</intent-filter>

<meta-data android:name= android.appwidget.providerandroid:resource= @xml/appwidget_info/>

</receiver>

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

<appwidget-provider xmlns:android= http://schemas.android.com/apk/res/android

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

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

android:updatePeriodMillis= 0//更新频率

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

</appwidget-provider>

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

public class MediaAppWidgetProvider extends AppWidgetProvider {

public static final String CMDAPPWIDGETUPDATE =appwidgetupdate ;

static final ComponentName THIS_APPWIDGET =

new ComponentName( com.android.music ,com.android.music.MediaAppWidgetProvider );

private static MediaAppWidgetProvider sInstance;

static synchronized MediaAppWidgetProvider getInstance() {

if (sInstance == null) {

sInstance = new MediaAppWidgetProvider();

}

return sInstance;

}

@Override

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

defaultAppWidget(context, appWidgetIds);

// 发送一个Intent广播给MediaPlaybackService以便立即更新

Intent updateIntent = new Intent(MediaPlaybackService.SERVICECMD);

updateIntent.putExtra(MediaPlaybackService.CMDNAME,MediaAppWidgetProvider.CMDAPPWIDGETUPDATE);

updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);

updateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);

context.sendBroadcast(updateIntent);

}

/**

* 初始化widget默认状态,如果服务没有运行,我们启动music的时候默认单击隐藏

*/

private void defaultAppWidget(Context context, int[] appWidgetIds) {

final Resources res = context.getResources();

final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.album_appwidget);

views.setViewVisibility(R.id.title, View.GONE);

views.setTextViewText(R.id.artist, res.getText(R.string.emptyplaylist));

linkButtons(context, views, false /** 没有播放*/);

pushUpdate(context, appWidgetIds, views);

}

private void pushUpdate(Context context, int[] appWidgetIds, RemoteViews views) {

// 更新指定的列表

final AppWidgetManager gm = AppWidgetManager.getInstance(context);

if (appWidgetIds != null) {

gm.updateAppWidget(appWidgetIds, views);

} else {

gm.updateAppWidget(THIS_APPWIDGET, views);

}

}

/**

* Check against {@link AppWidgetManager} if there are any instances of this widget.

*/

private boolean hasInstances(Context context) {

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

int[] appWidgetIds = appWidgetManager.getAppWidgetIds(THIS_APPWIDGET);

return (appWidgetIds.length > 0);

}

/**

* Handle a change notification coming over from {@link MediaPlaybackService}

*/

void notifyChange(MediaPlaybackService service, String what) {

if (hasInstances(service)) {

if (MediaPlaybackService.PLAYBACK_COMPLETE.equals(what) ||

MediaPlaybackService.META_CHANGED.equals(what) ||

MediaPlaybackService.PLAYSTATE_CHANGED.equals(what)) {

performUpdate(service, null);

}

}

}

/**

* Update all active widget instances by pushing changes

*/

void performUpdate(MediaPlaybackService service, int[] appWidgetIds) {

final Resources res = service.getResources();

final RemoteViews views = new RemoteViews(service.getPackageName(), R.layout.album_appwidget);

final int track = service.getQueuePosition() + 1;

CharSequence titleName = service.getTrackName();

CharSequence artistName = service.getArtistName();

CharSequence errorState = null;

// Format title string with track number, or show SD card message

String status = Environment.getExternalStorageState();

if (status.equals(Environment.MEDIA_SHARED) ||

status.equals(Environment.MEDIA_UNMOUNTED)) {

errorState = res.getText(R.string.sdcard_busy_title);

} else if (status.equals(Environment.MEDIA_REMOVED)) {

errorState = res.getText(R.string.sdcard_missing_title);

} else if (titleName == null) {

errorState = res.getText(R.string.emptyplaylist);

}

if (errorState != null) {

// Show error state to user

views.setViewVisibility(R.id.title, View.GONE);

views.setTextViewText(R.id.artist, errorState);

} else {

// No error, so show normal titles

views.setViewVisibility(R.id.title, View.VISIBLE);

views.setTextViewText(R.id.title, titleName);

views.setTextViewText(R.id.artist, artistName);

}

// Set correct drawable for pause state

final boolean playing = service.isPlaying();

if (playing) {

views.setImageViewResource(R.id.control_play, R.drawable.appwidget_pause);

} else {

views.setImageViewResource(R.id.control_play, R.drawable.appwidget_play);

}

// Link actions buttons to intents

linkButtons(service, views, playing);

pushUpdate(service, appWidgetIds, views);

}

/**

* Link up various button actions using {@link PendingIntents}.

*

* @param playerActive True if player is active in background, which means

*widget click will launch {@link MediaPlaybackActivity},

*otherwise we launch {@link MusicBrowserActivity}.

*/

private void linkButtons(Context context, RemoteViews views, boolean playerActive) {

// Connect up various buttons and touch events

Intent intent;

PendingIntent pendingIntent;

final ComponentName serviceName = new ComponentName(context, MediaPlaybackService.class);

if (playerActive) {

intent = new Intent(context, MediaPlaybackActivity.class);

pendingIntent = PendingIntent.getActivity(context,

0 /* no requestCode */, intent, 0 /* no flags */);

views.setOnClickPendingIntent(R.id.album_appwidget, pendingIntent);

} else {

intent = new Intent(context, MusicBrowserActivity.class);

pendingIntent = PendingIntent.getActivity(context,

0 /* no requestCode */, intent, 0 /* no flags */);

views.setOnClickPendingIntent(R.id.album_appwidget, pendingIntent);

}

intent = new Intent(MediaPlaybackService.TOGGLEPAUSE_ACTION);

intent.setComponent(serviceName);

pendingIntent = PendingIntent.getService(context,

0 /* no requestCode */, intent, 0 /* no flags */);

views.setOnClickPendingIntent(R.id.control_play, pendingIntent);

intent = new Intent(MediaPlaybackService.NEXT_ACTION);

intent.setComponent(serviceName);

pendingIntent = PendingIntent.getService(context,

0 /* no requestCode */, intent, 0 /* no flags */);

views.setOnClickPendingIntent(R.id.control_next, pendingIntent);

}

}

赞助本站

人工智能实验室

相关热词: Widget 播放器

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港