博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android桌面小部件AppWidget:音乐播放器桌面控制部件Widget(3)
阅读量:6376 次
发布时间:2019-06-23

本文共 5091 字,大约阅读时间需要 16 分钟。



Android桌面小部件AppWidget:音乐播放器桌面控制部件Widget(3)

Android桌面小部件AppWidget比较常用的场景就是音乐播放器,音乐播放器虽然通常在后台播放,但需要在桌面提供一个可以控制播放状态的APP widget,为用户提供播放、暂停、停止音乐播放器的功能。
在附录文章1、2的基础上,本文以一个简单的例子加以说明,如何通过桌面小部件实现音乐播放器的播放、停止。简单期间,本例只提供对音乐播放器的两种控制功能:播放和停止。播放,进入后台service播放给定的音乐mp3文件;停止,则直接stopService关闭播放服务即可。
为此,需要在桌面的小部件布局中增加两个按钮,这两个按钮暂时就以Android系统默认的播放(@android:drawable/ic_media_play)和暂停(@android:drawable/ic_media_pause)图片作为按钮使用。当按了播放按钮后,就开始启动后台服务播放mp3音乐文件(暂时以我放置在SDCard根目录下名为zhangphil.mp3的音乐文件为音频源文件);当按了停止按钮后,就stopService,即停止播放。
和附录文章1,2相比,本例不需要更新桌面小部件的表现形式,仅需要处理由桌面小部件传导过来的点击事件,这些响应点击事件,均放置在onReceive里面处理。

(1)

在Androidmanifest.xml里面定义的widget:

涉及到res/xml目录下的appwidget.xml代码文件:

(2)service播放音乐。也在Androidmanifest.xml里面定义:

(3)核心关键的AppWidget.java代码文件:

package zhangphil.widget;import android.app.PendingIntent;import android.appwidget.AppWidgetManager;import android.appwidget.AppWidgetProvider;import android.content.Context;import android.content.Intent;import android.util.Log;import android.widget.RemoteViews;public class AppWidget extends AppWidgetProvider {	@Override	public void onReceive(Context context, Intent intent) {		super.onReceive(context, intent);		// Log.d(this.getClass().getName(), "onReceive");		if (intent == null)			return;		String action = intent.getAction();		// 停止播放		if (action.equals(Constants.ACTION_STOP)) {			Intent serviceIntent = new Intent(context, MyService.class);			context.stopService(serviceIntent);		}		// 点击了按钮,启动一个后台服务播放		if (action.equals(Constants.ACTION_PLAY)) {			Intent serviceIntent = new Intent(context, MyService.class);			context.startService(serviceIntent);		}	}	@Override	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {		Log.d(this.getClass().getName(), "onUpdate");		RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.appwidget_layout);		// 播放图片作为按钮,绑定播放事件		Intent intentPlay = new Intent(Constants.ACTION_PLAY);		PendingIntent pendingIntentPlay = PendingIntent.getBroadcast(context, Constants.REQUEST_CODE_PLAY, intentPlay,				PendingIntent.FLAG_UPDATE_CURRENT);		remoteViews.setOnClickPendingIntent(R.id.play, pendingIntentPlay);		// 停止图片作为按钮,绑定停止事件		Intent intentStop = new Intent(Constants.ACTION_STOP);		PendingIntent pendingIntentStop = PendingIntent.getBroadcast(context, Constants.REQUEST_CODE_STOP, intentStop,				PendingIntent.FLAG_UPDATE_CURRENT);		remoteViews.setOnClickPendingIntent(R.id.stop, pendingIntentStop);		// 更新AppWidget		appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);	}	/**	 * 删除AppWidget	 */	@Override	public void onDeleted(Context context, int[] appWidgetIds) {		super.onDeleted(context, appWidgetIds);		Log.d(this.getClass().getName(), "onDeleted");	}	@Override	public void onDisabled(Context context) {		super.onDisabled(context);		Log.d(this.getClass().getName(), "onDisabled");	}	/**	 * AppWidget首次创建调用	 */	@Override	public void onEnabled(Context context) {		super.onEnabled(context);		Log.d(this.getClass().getName(), "onEnabled");	}}

AppWidget.java里面RemoteViews用到的布局文件appwidget_layout.xml:

(4)service后台服务MyService.java,该部分代码将负责在后台播放或者停止音播放:

package zhangphil.widget;import java.io.File;import android.app.Service;import android.content.Intent;import android.media.MediaPlayer;import android.os.Environment;import android.os.IBinder;public class MyService extends Service {	// 播放器	private MediaPlayer mMediaPlayer;	// 音频文件	private File audioFile;	@Override	public void onCreate() {		super.onCreate();		mMediaPlayer = new MediaPlayer();		// 根目录		File sdcard = Environment.getExternalStorageDirectory();		audioFile = new File(sdcard, "zhangphil.mp3");	}	@Override	public int onStartCommand(Intent intent, int flags, int startId) {		// 重置		mMediaPlayer.reset();		// 设置播放器的声音源		try {			mMediaPlayer.setDataSource(audioFile.getAbsolutePath());		} catch (Exception e) {			e.printStackTrace();		}		// 也可以从一个静态资源文件中加载音频数据源		// mMediaPlayer.create(this, R.raw.xxx);		if (!mMediaPlayer.isPlaying()) {			try {				mMediaPlayer.prepare();			} catch (Exception e) {				e.printStackTrace();			}						mMediaPlayer.start();			// 如果设置循环true,那么将循环播放			// mMediaPlayer.setLooping(true);		}				return super.onStartCommand(intent, flags, startId);	}	@Override	public void onDestroy() {		super.onDestroy();		mMediaPlayer.stop();		mMediaPlayer.release();		mMediaPlayer = null;	}	@Override	public IBinder onBind(Intent intent) {		return null;	}}

(5)定义的公共静态变量Constants.java:

package zhangphil.widget;public class Constants {	public static final String ACTION_PLAY = "action_play";	public static final String ACTION_STOP = "action_stop";	public static final int REQUEST_CODE_PLAY = 0xd05;	public static final int REQUEST_CODE_STOP = 0xd06;}

代码运行结果如图所示:

附录文章:
1,《Android桌面小部件AppWidget(1)》链接地址:
2,《Android桌面小部件AppWidget(2)》链接地址:

你可能感兴趣的文章
泛泰A870(高通APQ8064t 600 cpu) Mokee4.4.2(Android4.4) 图赏
查看>>
hdu 2066 一个人的旅行
查看>>
据说有99%的人都会做错的面试题
查看>>
使用history.pushState()和popstate事件实现AJAX的前进、后退功能
查看>>
【JavaScript】一个同步于本地时间的动态时间
查看>>
js---03属性操作
查看>>
HDU 1231——最大连续子序列(DP)
查看>>
P1739 表达式括号匹配
查看>>
3.1.4 模板字符串
查看>>
redis 介绍和常用命令
查看>>
CPU的段寄存器
查看>>
linux 安装nginx
查看>>
Kettle的概念学习系列之Kettle是什么?(一)
查看>>
Qt 3D教程(二)初步显示3D的内容
查看>>
100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)【转】
查看>>
compareTo返回值为-1 、 1 、 0 的排序问题
查看>>
Being a Good Boy in Spring Festival(杭电1850)(尼姆博弈)
查看>>
微服务间如何选择推送和拉取数据
查看>>
RecyclerView 数据刷新的几种方式 局部刷新 notify MD
查看>>
互联网+时代IT管理者的转型
查看>>