Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

appWidget小应用----简易音乐播放器

$
0
0

制作一个类似与下图的简易音乐播放器
这里写图片描述

1.创建一个布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:paddingTop="4dp"
              android:paddingBottom="4dp"
              android:paddingLeft="8dp"
              android:paddingRight="8dp"
              android:orientation="horizontal"
              android:weightSum="5"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
<LinearLayout
    android:orientation="vertical"
    android:layout_width="0dp"
    android:layout_weight="3"
    android:layout_height="56dp">
    <TextView
        android:textSize="20sp"
        android:textStyle="bold"
        android:id="@+id/musicTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <TextView
        android:textSize="18sp"
        android:layout_marginTop="3dp"
        android:text="artist"
        android:id="@+id/musicArtist"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>
    <ImageView
        android:src="@drawable/ic_media_play"
        android:id="@+id/musicPlay"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="56dp"/>
    <ImageView
        android:src="@drawable/ic_media_next"
        android:id="@+id/musicNext"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="56dp"/>
</LinearLayout>

布局很简单,两个TextView和两个ImageView。

2.实现AppWidgetProvider

实现一个appWidget一般需要两步,第一步实现实现一个AppWidgetProvider中的onUpdate()方法,有点类似Activity中的onCreate()方法。第二步,在AndroidManifest中声明。

public class MusicWidgetProvider extends AppWidgetProvider{

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        //开启一个服务
        context.startService(new Intent(context,MusicService.class));
        super.onUpdate(context,appWidgetManager,appWidgetIds);
    }

    @Override
    public void onDisabled(Context context) {
        //关闭服务
        context.stopService(new Intent(context, MusicService.class));
        super.onDisabled(context);
    }
}

在MusicWidgetProvider 中只是简单的开启和关闭一个服务,因为在MusicWidgetProvider 中不能很好的实现音乐的播放,将音乐的播放逻辑放在服务中实现。

3.声明appWidget

<receiver android:name=".MusicWidgetProvider">
            <intent-filter >
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                       android:resource="@xml/music_provider_info"
                />
 </receiver>

还需一个xml文件

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
                    android:minWidth="250dp"
                    android:minHeight="56dp"
                    android:updatePeriodMillis="86400000"
                    android:initialLayout="@layout/music_provider">

4.在服务中实现音乐播放

在实现音乐播放前,需要创建一个类用于存放音乐信息

public class SongInfo {
    private String title;//歌曲名
    private String artist;//歌手
    private String data;//歌曲所在路径

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getArtist() {
        return artist;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }
}

还需要一个方法去获取手机中的音乐文件

public class MusicManager {
    /**
     * 获取手机内的所有歌曲信息
     * @param context
     * @return
     */
    public static List<SongInfo> getSongList(Context context)
    {
        List<SongInfo> songList=new ArrayList<>();
        ContentResolver contentResolver=context.getContentResolver();
        //从对应的数据库中获取对应列的歌曲信息
        Cursor cursor=contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                new String[]{
                        MediaStore.Audio.Media.TITLE,
                        MediaStore.Audio.Media.ARTIST,
                        MediaStore.Audio.Media.DATA
                },null,null,MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
        cursor.moveToFirst();
        for (int i = 0; i < cursor.getCount(); i++) {
            SongInfo song=new SongInfo();
            song.setTitle(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)));
            song.setArtist(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)));
            song.setData(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)));
            songList.add(song);
            cursor.moveToNext();
        }
        cursor.close();
        return songList;
    }
}

存放歌曲信息的数据库中还存放了其他信息,如DURATION(歌曲长度),SIZE(大小)。。。在本例中只需要歌曲名,歌手,路径即可。
准备工作完成,开始实现音乐播放。

public class MusicService extends Service{
    private static final String TAG = "MusicService";

    private static final String MUSIC_PLAY_ACTION="appwidget.action.musicplay";
    private static final String MUSIC_NEXT_ACTION="appwidget.action.musicnext";

    private List<SongInfo> songList;//存放歌曲信息
    private int currentSong=0;//当前播放歌曲的位置
    private MediaPlayer mediaPlayer;


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @Override
    public void onCreate() {
        super.onCreate();
        songList=MusicManager.getSongList(this);
        //注册广播
        IntentFilter filter=new IntentFilter(MUSIC_PLAY_ACTION);
        filter.addAction(MUSIC_NEXT_ACTION);
        registerReceiver(new MusicReceiver(), filter);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //更新appWidget
        updateAppWidget();
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 更新appWidget
     */
    public void updateAppWidget()
    {
        AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(this);

        RemoteViews remoteViews=new RemoteViews(this.getPackageName(),R.layout.music_provider);
        //设置歌曲名和歌手
        remoteViews.setTextViewText(R.id.musicTitle,getCurrentSongTitle());
        remoteViews.setTextViewText(R.id.musicArtist, getCurrentSongArtist());

        Intent playIntent=new Intent(MUSIC_PLAY_ACTION);
        if (mediaPlayer!=null)
        {
            //根据音乐是否播放,更改imageView的图片
            remoteViews.setImageViewResource(R.id.musicPlay, mediaPlayer.isPlaying() ?
                    R.drawable.ic_media_pause : R.drawable.ic_media_play);
        }
        //点击开启广播
        PendingIntent playBroad=PendingIntent.getBroadcast(this,0,playIntent,0);
        remoteViews.setOnClickPendingIntent(R.id.musicPlay, playBroad);

        Intent nextIntent=new Intent(MUSIC_NEXT_ACTION);
        PendingIntent nextBroad=PendingIntent.getBroadcast(this,0,nextIntent,0);
        remoteViews.setOnClickPendingIntent(R.id.musicNext, nextBroad);

        ComponentName componentName=new ComponentName(this,MusicWidgetProvider.class);
        appWidgetManager.updateAppWidget(componentName, remoteViews);
    }

    /**
     * 获取当前歌曲名
     * @return
     */
    public String getCurrentSongTitle()
    {
        return songList==null?"暂无歌曲":songList.get(currentSong).getTitle();
    }

    /**
     * 获取当前歌手
     * @return
     */
    public String getCurrentSongArtist()
    {
        return songList==null?"未知歌手":songList.get(currentSong).getArtist();
    }


    public void play()
    {
        try {
            mediaPlayer=new MediaPlayer();
            mediaPlayer.setDataSource(songList.get(currentSong).getData());
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    //准备完成后,播放音乐并更新appwidget
                    mediaPlayer.start();
                    updateAppWidget();
                }
            });
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    //播放结束,播放下一首
                    playNext();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 播放下一首
     */
    public void playNext()
    {
        if(mediaPlayer!=null)
        {
            Stop();
        }
        //指向下一首,这里需要对是否是最后一首进行判断
        currentSong++;
        play();
    }

    /**
     * 暂停播放,更新appWidget
     */
    public void pause()
    {
        mediaPlayer.pause();
        updateAppWidget();
    }

    /**
     * 播放,更新appWidget
     */
    public void start()
    {
        mediaPlayer.start();
        updateAppWidget();
    }
    /**
     * 音乐停止
     */
    public void Stop()
    {
        if (mediaPlayer!=null)
        {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer=null;
        }
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Stop();
    }

    /**
     * 接收广播,处理对应请求
     */
    public class MusicReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent) {

            if (intent.getAction().equals(MUSIC_PLAY_ACTION))
            {
                //当mediaPlayer为null时,表示当前未播放音乐
                if (mediaPlayer==null)
                {
                    play();
                }else {
                    //当音乐正在播放时,暂停播放
                    if (mediaPlayer.isPlaying())
                    {
                        pause();
                    }else {
                        start();
                    }
                }

            }else if (intent.getAction().equals(MUSIC_NEXT_ACTION))
            {
                playNext();
            }

        }
    }
}

5.运行
这里写图片描述

作者:qq_31244409 发表于2016/10/3 14:26:40 原文链接
阅读:118 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>