[置顶] 获取Android手机上音乐播放器状态

最近在公司做锁屏项目,需要在锁屏界面上显示音乐播放器的状态,类似小米的锁屏界面,网上也有类似的功能介绍,我在这里做个总结吧。

首先说下,这个数据信息是音乐播放器中service(com.android.music.MediaPlaybackService)以广播的形式发出来的。

有的第三方播放器也有这个服务,比如天天动听,如果手机上面有多个以上的播放器实现了这个服务,那么会出现混乱现象(小米手机也有此现象)。

主要的数据包括,音乐文件id,作者,等,界面中的专辑图片是从数据查询出来的,后面会介绍。

	public long id;
public String artistName;public String album;public String track;public boolean playing;public long duration;public long position;


再说下播放控制吧,锁屏上可以使用的功能比较简单,播放、暂停、上一曲、下一曲。

这写播放控制都是以启动一个服务,把命令以参数形式,发送过去,然后会服务就会返回一个广播,返回当前音乐播放器的状态。

再说说专辑图片,这个专辑图片是从音乐文件中提取出来的,有类似的协议和算法,这里不做介绍,这些东西Android系统都有实现,我们只需要拿来使用就好了。

完全的拿来主义,鄙视下自己~~~

刚刚上面的实体类中有个id的字段,这样我们可以从安卓的媒体内容提供者中查询(MediaStore),可以根据id查询到 MediaStore.Audio.Media.ALBUM_ID ,在根据ALBUM_ID 打开相应的文件。

		/**
		 * 得到当前音乐播放的专辑图片,如果没有则返回null
		 * @param context
		 * @return
		 */
		public Bitmap getAlbumCover(Context context) {
			Bitmap bmp = null;
			if (id <= 0) {
				return null;
			}
			Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
			Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
			if (cursor != null && cursor.moveToNext()) {
				long albumID = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
				Uri AlbumUriPath = Uri.parse(ALBUM_COVER_URI_PATH);
				Uri albumIDUri = ContentUris.withAppendedId(AlbumUriPath, albumID);
				ParcelFileDescriptor fd = null;
				try {
					fd = context.getContentResolver().openFileDescriptor(albumIDUri, "r");
				} catch (FileNotFoundException e) {
				}
				if (fd != null) {
					FileDescriptor fdc = fd.getFileDescriptor();
					bmp = BitmapFactory.decodeFileDescriptor(fdc);
					try {
						if (fd != null) {
							fd.close();
						}
					} catch (IOException e) {
					}
				}
			}
			return bmp;
		}
	}

下面是完整代码:

import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;

import android.content.BroadcastReceiver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;


/**
 * 远程音乐控制控件
 * Title: RemoteMusicControl.java<br>
 * author:xiaqiulei@gmail.com <br>
 * Date: 2013-5-30<br>
 * Version:v1.0
 */
public class RemoteMusicControl {
	static final String PLAYSTATE_CHANGED = "com.android.music.playstatechanged";
	static final String META_CHANGED = "com.android.music.metachanged";
	static final String QUEUE_CHANGED = "com.android.music.queuechanged";
	static final String PLAYBACK_COMPLETE = "com.android.music.playbackcomplete";
	static final String QUIT_PLAYBACK = "com.android.music.quitplayback";

	static final String SERVICE_ACTION = "com.android.music.MediaPlaybackService";
	static final String SERVICECMD = "com.android.music.musicservicecommand";

	static final String CMDNAME = "command";
	static final String CMDTOGGLEPAUSE = "togglepause";
	static final String CMDSTOP = "stop";
	static final String CMDPAUSE = "pause";
	static final String CMDPLAY = "play";
	static final String CMDPREVIOUS = "previous";
	static final String CMDNEXT = "next";

	private Context mContext;
	private boolean playing = false;
	private boolean mIsRegister = false;
	private OnRemoteMusicControlCallback onRemoteMusicControlCallback;
	private Handler hander;

	public RemoteMusicControl(Context context) {
		mContext = context;
	}

	/**
	 * 注册
	 */
	public void register() {
		hander = new Handler();
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(PLAYSTATE_CHANGED);
		intentFilter.addAction(META_CHANGED);
		// intentFilter.addAction(QUEUE_CHANGED);
		intentFilter.addAction(PLAYBACK_COMPLETE);
		//intentFilter.addAction(QUIT_PLAYBACK);
		mContext.registerReceiver(receiver, intentFilter);

		Intent it = new Intent(SERVICE_ACTION);
		mContext.startService(it);
		mIsRegister = true;
	}

	/**
	 * 注销
	 */
	public void unRegister() {
		if (receiver != null) {
			mContext.unregisterReceiver(receiver);
		}
		mIsRegister = false;
		hander = null;
	}

	/**
	 * 执行命令
	 * @param cmd
	 */
	void doRemoteMusic(String cmd) {
		Intent intent = new Intent(SERVICECMD);
		intent.putExtra(CMDNAME, cmd);
		mContext.sendBroadcast(intent);
	}

	/**
	 * 下一曲
	 */
	public void doRemoteMusicNext() {
		doRemoteMusic(CMDNEXT);
	}

	/**
	 * 上一曲
	 */
	public void doRemoteMusicPerv() {
		doRemoteMusic(CMDPREVIOUS);
	}

	/**
	 * 播放
	 */
	public void doRemoteMusicPlay() {
		doRemoteMusic(CMDPLAY);
	}

	/**
	 * 暂停
	 */
	public void doRemoteMusicPause() {
		doRemoteMusic(CMDPAUSE);
	}

	/**
	 * 暂停或者播放
	 */
	public void doRemoteMusicPlayOrPause() {
		if (playing) {
			doRemoteMusic(CMDPAUSE);
		} else {
			doRemoteMusic(CMDPLAY);
		}
	}

	/**
	 * 音乐服务接受广播
	 */
	BroadcastReceiver receiver = new BroadcastReceiver() {
		public void onReceive(Context context, Intent intent) {
			final MusicExtra me = new MusicExtra();
			me.id = intent.getLongExtra("id", 0);
			me.artistName = intent.getStringExtra("artist");
			me.album = intent.getStringExtra("album");
			me.track = intent.getStringExtra("track");
			me.playing = intent.getBooleanExtra("playing", false);
			me.duration = intent.getLongExtra("duration", 3000);
			me.position = intent.getLongExtra("position", 1000);

			playing = me.playing;


			if (hander != null) {
				hander.post(new Runnable() {
					public void run() {
						if (onRemoteMusicControlCallback != null) {
							onRemoteMusicControlCallback.onCallback(me);
						}
					}
				});
			}
		}
	};

	/**
	 * 是否注册
	 * @return
	 */
	public boolean isRegister() {
		return mIsRegister;
	}

	public OnRemoteMusicControlCallback getOnRemoteMusicControlCallback() {
		return onRemoteMusicControlCallback;
	}

	public void setOnRemoteMusicControlCallback(OnRemoteMusicControlCallback onRemoteMusicControlCallback) {
		this.onRemoteMusicControlCallback = onRemoteMusicControlCallback;
	}

	/** 
	 * 音乐播放状态
	 */
	public static class MusicExtra {
		static final String ALBUM_COVER_URI_PATH = "content://media/external/audio/albumart";
		public long id;
		public String artistName;
		public String album;
		public String track;
		public boolean playing;
		public long duration;
		public long position;

		public String toString() {
			return "MusicExtra [id=" + id + ", artistName=" + artistName + ", album=" + album + ", track=" + track + ", playing=" + playing + ", duration="
					+ duration + ", position=" + position + "]";
		}

		/**
		 * 得到当前音乐播放的专辑图片,如果没有则返回null
		 * @param context
		 * @return
		 */
		public Bitmap getAlbumCover(Context context) {
			Bitmap bmp = null;
			if (id <= 0) {
				return null;
			}
			Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
			Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
			if (cursor != null && cursor.moveToNext()) {
				long albumID = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
				Uri AlbumUriPath = Uri.parse(ALBUM_COVER_URI_PATH);
				Uri albumIDUri = ContentUris.withAppendedId(AlbumUriPath, albumID);
				ParcelFileDescriptor fd = null;
				try {
					fd = context.getContentResolver().openFileDescriptor(albumIDUri, "r");
				} catch (FileNotFoundException e) {
				}
				if (fd != null) {
					FileDescriptor fdc = fd.getFileDescriptor();
					bmp = BitmapFactory.decodeFileDescriptor(fdc);
					try {
						if (fd != null) {
							fd.close();
						}
					} catch (IOException e) {
					}
				}
			}
			return bmp;
		}
	}

	/**
	 * 远程音乐播放控制空间回调
	 */
	public interface OnRemoteMusicControlCallback {
		public void onCallback(MusicExtra extra);
	}
}

原文地址:https://www.cnblogs.com/liushuibufu/p/3253614.html