课堂笔记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只是一个布局里面的具体内容由这里提供
新建WidgetBroadcast继承于AppWidgetProvider在manifests文件中注册,设置intent-filter,在meta-data中添加android.appwidget.provider以及上面建立的widget布局文件
现在widget已经有了接下来设置点击事件
在WidgetBroadcast中重写onUpdate,设置RemoteView以及PendingIntent,再使用appWidgetManager更新Widget
WidgetBroadcast继承的AppWidgetProvider是BroadeReceiver的子类,当Widget点击时会调用onReveive并传递intent,在onRecieve里面发生广播开启服务播放音乐
2.Service
在service内新建BroadcastReciver当接受到广播时使用MediaPlayer播放音乐
在onStartCommand中注册BroadcastReciver
在onDisdroy中unregisterReceiver
3.音乐文件的读取
新建一个Music类,在构造器中读取assets中music文件夹下的音乐文件名
在prepare方法中设置MediaPlayer通过setDataSource读取音乐文件
开始方法
Activity中的的设置也类似通过广播来传递消息,主要在于和Widget保持同步这里不在赘述
下面是运行结果
使用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保持同步这里不在赘述
下面是运行结果
相关文章推荐