Android第四次作业

一.团队

季澈    1600802044

张文君  1600802069

郭守杰  1600802041

二.apk下载链接

https://coding.net/u/mozhileixi/p/music/git/raw/master/app-debug.apk

三.代码链接

https://git.coding.net/mozhileixi/music.git

四.团队项目

运行效果视频:https://coding.net/u/mozhileixi/p/music/git/raw/master/Screen%20Record_2019-01-03-18-06-39.mp4

1.项目总体效果

进入界面(进入app前显示界面,借用网易云页面)

主界面(想实现网络搜索歌曲,但是实现,因此仅制作了UI界面,底部的功能均未实现)

歌曲列表

播放界面

 2.项目效果描述及功能

  点击app,先弹出进入界面,借鉴于网易云图片,首页为各功能显示,共有两个功能,网络搜索和本地搜索,由于下载歌曲连接的权限问题,暂未实现;本地搜索功能会搜集设备上所有MP3文件,点击本地音乐,会显示所有搜集到的歌曲,点击其中一首歌曲后跳转到播放界面,在播放界面有上一曲,下一曲,开始暂停,顺序播放,随机播放,单首播放,音量的控制,进度条,歌词,可以删除歌曲。

五.关键代码

获取歌词:对获取到的歌词进行解析。

 public static List<LrcRow> createRows(String standardLrcLine){
        try{
            if (standardLrcLine.indexOf("[") == 0){
                if (standardLrcLine.indexOf("]") == 6 ||standardLrcLine.indexOf("]") == 9 ){

                }else{
                    if (standardLrcLine.indexOf(".") == 6){

                    }else {
                        return null;
                    }
                }
            }else{
                return null ;
            }
            int lastIndexOfRightBracket = standardLrcLine.lastIndexOf("]");
            String content = standardLrcLine.substring(lastIndexOfRightBracket + 1, standardLrcLine.length());
            String times = standardLrcLine.substring(0,lastIndexOfRightBracket + 1).replace("[", "-").replace("]", "-");
            String arrTimes[] = times.split("-");
            List<LrcRow> listTimes = new ArrayList<LrcRow>();
            for(String temp : arrTimes){
                if(temp.trim().length() == 0){
                    continue;
                }
                LrcRow lrcRow = new LrcRow(temp, timeConvert(temp), content);
                listTimes.add(lrcRow);
            }
            return listTimes;
        }catch(Exception e){
            Log.e(TAG,"createRows exception:" + e.getMessage());
            return null;
        }
    }

获取本地歌曲:

    public List<Song> getLocalMusci(Context context) {
        List<Song> list1 = new ArrayList<Song>();
        int position = 0;
        Cursor cursor = context.getContentResolver()
                .query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null,null,null,MediaStore.Audio.AudioColumns.IS_MUSIC);
            for (cursor.moveToFirst();!cursor.isAfterLast(); cursor.moveToNext()) {
                Song song = new Song();
                song.setSinger(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)));
                song.setDuration(cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)));
                song.setPath(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)));
                song.setALLName(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)));
                song.setSong(cursor.getSring(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)));
                song.setSize(cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)));
                song.setId(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)));
                if(song.getSong().contains("-")){
                    String Name[] = song.getSong().split("-");
                    String name = Name[1].toString().split(".mp3")[0].indexOf("[mqms2]") > 0
                            ? Name[1].toString().split(".mp3")[0].substring(0, Name[1].toString().split(".mp3")[0].indexOf("[mqms2]")) : Name[1].toString().split(".mp3")[0];
                    song.setSong(name);
                    song.setSinger(Name[0]);
                }
                if (song.getDuration()/(1000 * 60) >= 1) {    
                    song.setPosition(position);
                    list1.add(song);
                    Log.i("songsong","+"+song.getALLName()+song.getPath());
                    position++;
                }
                Log.i("getMUSIC","TTTTTTTTTTT3"+list1.size());
            }
             cursor.close();

       if (list == null) {
           list = list1;
       }
        return list1;
    }

随机播放,单曲循环,顺序播放核心代码:

 case R.id.iv_mode:
                if (mode == MusicUtil.TYPE_ORDER) {
                    Toast.makeText(this, "已切换为随机模式", Toast.LENGTH_SHORT).show();
                    mode = MusicUtil.TYPE_RANDOM;
                    ivMode.setImageResource(R.drawable.play_btn_shuffle_selector);
                    MusicUtil.getInstance().setPatten(MusicUtil.TYPE_RANDOM);
                } else if (mode == MusicUtil.TYPE_RANDOM) {
                    Log.i("pat2", "" + mode);
                    Toast.makeText(this, "已切换为单曲循环", Toast.LENGTH_SHORT).show();
                    this.mode = TYPE_SINGLE;
                    ivMode.setImageResource(R.drawable.play_btn_one_selector);
                    MusicUtil.getInstance().setPatten(TYPE_SINGLE);
                    Log.i("pat4", "" + mode);

                } else if (mode == TYPE_SINGLE) {
                    Log.i("pat5", "" + mode);
                    Toast.makeText(this, "已切换为顺序播放", Toast.LENGTH_SHORT).show();
                    this.mode = MusicUtil.TYPE_ORDER;
                    ivMode.setImageResource(R.drawable.play_btn_loop_selector);
                    MusicUtil.getInstance().setPatten(MusicUtil.TYPE_ORDER);
                    Log.i("pat6", "" + mode);
                }
                break;

下一首,上一首,暂停,播放核心代码:

case R.id.iv_prev:
                if (!isplay) {
                    isplay = true;
                    ivPlay.setImageResource(R.drawable.play_btn_pause_selector);
                }
                MusicUtil.getInstance().pre();
                changInfo();
                Intent startIntent2 = new Intent(this, MusicService.class);
                startIntent2.putExtra("action", MusicService.PREVIOUSMUSIC);
                startService(startIntent2);
                musicService.changNotifi(1);
                break;
            case R.id.iv_play:
                if (isplay) {

                    ivPlay.setImageResource(R.drawable.play_btn_play_selector);
                    isplay = false;


                } else {
                    isplay = true;

                    ivPlay.setImageResource(R.drawable.play_btn_pause_selector);
                }
                Intent startIntent1 = new Intent(this, MusicService.class);
                startIntent1.putExtra("action", MusicService.PLAYORPAUSE);
                startService(startIntent1);


                break;
            case R.id.iv_next:
                MusicUtil.getInstance().next();

                changInfo();
                if (!isplay) {
                    isplay = true;
                    ivPlay.setImageResource(R.drawable.play_btn_pause_selector);
                }
                Intent startIntent3 = new Intent(this, MusicService.class);
                startIntent3.putExtra("action", MusicService.NEXTMUSIC);
                startService(startIntent3);
                break;
        }

删除歌曲核心代码:

    public static boolean deleteSong (Song song) {
        File file = new File(song.getPath());
        if (file.isFile() && file.exists()) {
            file.delete();
            MusicUtil.getInstance().changeList(song);
            musicAdapter.setList(MusicUtil.getInstance().getList());
            return true;
        }
          return false;
    }

五.5名最优apk评论

1.第一名:https://www.cnblogs.com/JusperLee/p/10192769.html(李凯、季轩石组)
(1)功能:计划的事实的添加;获取计划编写的时间;整体架构使用mvp架构;使用了第三方库来实现WiFi查看等功能。
(2)优点:功能较为完善,体系较为清楚,界面较为简洁,按钮较为明显。
(3)缺点:结构较为粗糙,颜色较为单一深暗。
(4)假想:如果由我组进行该项目的更改,我组成员将变更架构并将界面更加清新化,力求有别于官方APP。
2.第二名:https://www.cnblogs.com/Suejun/p/10192755.html(苏毅俊、南加拉才让、周泽加、李长栋组)
(1)功能:上课点名;学习资料;共享论坛;考试;习题等功能。
(2)优点:功能较为完善,体系较为清楚,界面较为简洁,颜色较为丰富。
(3)缺点:按钮较为奇特,布局较为简单。
(4)假想:如果由我组进行该项目的更改,我组成员将变更颜色搭配及界面按钮分布。
3.第二名:https://www.cnblogs.com/mxl123/p/10199113.html(马秀莲、马玉花组)
(1)功能:登录;注册;发布动态;查看好友列表;消息等功能。
(2)优点:功能可以说是很好了,按钮较为简洁,体系较为清晰。
(3)缺点:界面可以说是很简单了,布局不太合常理。
(4)假想:如果由我组进行该项目的更改,我组成员将变更按钮布局,从界面简洁性等着手改造,力求其商业化。
4.第四名:https://www.cnblogs.com/hlpbk/p/10190166.html(韩丽萍、祁海燕组)
(1)功能:添加日记;保存日记;修改日记;删除日记等功能。
(2)优点:界面较为清新,功能较为完善
(3)缺点:按钮太简洁了,字体有些奇怪
(4)假想:如果由我组进行该项目的更改,我组成员将变更字体及布局体系。
5.第五名:https://www.cnblogs.com/gao98/p/10201768.html(马玉娟、高志杰、高怡组)
(1)功能:显示,添加,修改,删除课程信息;跳转显示当前时间的课程;显示课程表的详细信息。
(2)优点:界面较为清新,体系较为清晰,架构较为简短
(3)缺点:布局有些奇特,功能较少
(4)假想:如果由我组进行该项目的更改,我组成员将变更架构,添加更多的复杂体系

六.所遇到的问题

郭守杰 1600802041

问题一:安卓6.0权限问题,在模拟器上可以运行apk,但是安装到手机上就闪退,查了一下是由于从安卓6.0开始要手动请求权限

解决方法:在AndroidManifest.xml中添加权限获取代码  然后在mainActivity里添加函数,最后在OnCreate中调用。

问题二:想实现网络歌曲播放,但是没有歌曲库,没有歌曲版权,无法获取网络歌曲。所以说改问题没有解决。

张文君 1600802069

问题一:在实现单曲循环的功能时,点击单曲循环按钮,无法进行相应的操作,导致它只会播放下一曲,并不会单曲循环,但是在顺序播放中是正常的。

解决方法:通过仔细调试,发现单曲循环功能的代码并不是随机播放,而是下一首,也就是说,单曲循环功能并没有进行实际的编程,通过查询,了解到单曲循环实在当前Activity中重新调用初始化播放的代码,也就是继续播放当前的歌曲,跟随机播放相类似,随机播放时通过随机生成的一个数来播放不同歌曲。

问题二:声音功能的实现,在最初时遇到了很多问题,也是通过网上查询和一次次的调试,才将声音功能实现

解决方法:用seekBar来调节大小,查了资料后发现,AudioManager可以调节各种类型的声音的音量,不过要添加<uses-permission Android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> 权限,否则无法控制音量,功能无法实现。

季澈1600802044:
问题一:如何自定义一个view组件?(以自定义一个ImageView组件为例)

定义一个Java类,

继承要自定义的组件类型,
重写其中的一些方法,
对原组件扩展

public class ImageAsyncView extends ImageView
{

protected void onDraw(Canvas canvas){ }
}

问题二:如何更改listview的间隔条宽度,颜色?

android:divider="#f00" <!-- ?divider设定间隔条的颜色-->

android:dividerHeight="8px" <!-- ?dividerHeight设定间隔条的宽度-->

七.项目分工

姓名 分工 工作比例 分数(10)
季澈 UI,部分功能的实现 32% 8
郭守杰 UI,编程,代码上传 36% 8
张文君 UI,编程,写博客 32% 8
posted @ 2019-01-01 13:23  青竹_123  阅读(276)  评论(0编辑  收藏  举报