您的位置:首页 > 移动开发 > Android开发

课堂笔记3

2016-08-08 15:10 127 查看
制作简单的音乐播放器

    使用service后台播放音乐,制作widget和Activity播放界面,通过BroadcastReceiver进行数据传输

1.Widget

首先创建appwidget-provider布局文件,minWidth和minHeight为widget的最小宽高,系统会根据此宽高自动调节widget在主屏中的大小

previewImage是选择widget时的预览图,如果没有设置会默认为应用图标

initialLayout 初始化weidget,appwidget-provider只是一个布局里面的具体内容由这里提供

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="100dp"
android:minHeight="60dp"
android:previewImage="@drawable/ic_notification"
android:initialLayout="@layout/widget_layout">

</appwidget-provider>

新建WidgetBroadcast继承于AppWidgetProvider在manifests文件中注册,设置intent-filter,在meta-data中添加android.appwidget.provider以及上面建立的widget布局文件

<receiver android:name=".WidgetBroadcast">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
<action android:name="com.example.music_service.MUSIC_DATA"/>
<action android:name="com.example.music_widget.PLAY_ANY"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@layout/widget"
/>
</receiver>

现在widget已经有了接下来设置点击事件

在WidgetBroadcast中重写onUpdate,设置RemoteView以及PendingIntent,再使用appWidgetManager更新Widget

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);

Intent intentService=new Intent(context,MusicService.class);
context.startService(intentService);
RemoteViews views=new RemoteViews(context.getPackageName(),R.layout.widget_layout);

views.setOnClickPendingIntent(R.id.music_start,getIntentForRemoteView(context,WIDGET_START));
views.setOnClickPendingIntent(R.id.music_next,getIntentForRemoteView(context,WIDGET_NEXT));
views.setOnClickPendingIntent(R.id.music_previous,getIntentForRemoteView(context,WIDGET_PREVIOUS));

appWidgetManager.updateAppWidget(appWidgetIds,views);

}

WidgetBroadcast继承的AppWidgetProvider是BroadeReceiver的子类,当Widget点击时会调用onReveive并传递intent,在onRecieve里面发生广播开启服务播放音乐

@Override
public void onReceive(Context context, Intent intent) {
// boolean state=false;
super.onReceive(context, intent);

RemoteViews remoteViews=new RemoteViews(context.getPackageName(),R.layout.widget_layout);

//收到widget的开始或暂停点击事件后发送广播给service,state为false为暂停反之为开始
if(TextUtils.equals(intent.getAction(),WIDGET_START)){
if(!state) {
context.sendBroadcast(getIntentForService(MusicService.SERVICE_PLAY,state));
remoteViews.setImageViewResource(R.id.music_start,R.drawable.ic_pause_white_24dp);
Log.d(TAG,"start");
state=true;
}else{
Log.d(TAG,"pause");
context.sendBroadcast(getIntentForService(MusicService.SERVICE_PLAY,state));
remoteViews.setImageViewResource(R.id.music_start,R.drawable.ic_play_arrow_white_24dp);
state=false;
}
}

2.Service

在service内新建BroadcastReciver当接受到广播时使用MediaPlayer播放音乐

public  BroadcastReceiver receiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(intent!=null) {
if (TextUtils.equals(intent.getAction(), SERVICE_PLAY)) {
if(!intent.getBooleanExtra("state",true))
{
Log.d(TAG,"play");
mMusic.mMusicPlayer.start();
MusicService.this.sendBroadcast(mMusic.getMusicIntent());
}
else if( mMusic.mMusicPlayer.isPlaying()){
mMusic.mMusicPlayer.pause();
}
}

在onStartCommand中注册BroadcastReciver

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG,"onStartCommand");
IntentFilter filter=new IntentFilter();
filter.addAction(SERVICE_NEXT);
filter.addAction(SERVICE_PREViOUS);
filter.addAction(SERVICE_PLAY);
filter.addAction(MainActivity.PLAY_ANY);
registerReceiver(receiver,filter);
return super.onStartCommand(intent, flags, startId);
}

在onDisdroy中unregisterReceiver

@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
mMusic.mMusicPlayer.stop();
}


3.音乐文件的读取

新建一个Music类,在构造器中读取assets中music文件夹下的音乐文件名

Music( Context context){
//得到音乐文件名数组
am=context.getAssets();
try {
musicFileName=am.list("music");
Log.d(TAG, Arrays.toString(musicFileName));
currentPlaying=musicFileName[0];
mMusicPlayer=new MediaPlayer();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(context,"没有找到音乐文件",Toast.LENGTH_SHORT).show();
}
}

在prepare方法中设置MediaPlayer通过setDataSource读取音乐文件

public void prepare(int fileName){

if(mMusicPlayer.isPlaying()){
mMusicPlayer.stop();
}
mMusicPlayer.reset();
Log.d(TAG, "media player reset");
try {
mMusicPlayer.setDataSource(getFileDescriptor(),getAssetFD().getStartOffset(),
getAssetFD().getLength());
Log.d(TAG, "setDataSource");
mMusicPlayer.prepare();
Log.d(TAG, "media prepare");
} catch (IOException e) {
e.printStackTrace();
}
}

开始方法

public void start(){
mMusicPlayer.start();
}


Activity中的的设置也类似通过广播来传递消息,主要在于和Widget保持同步这里不在赘述

下面是运行结果



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android Widget