• 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
  • 相关阅读:
    如何面试你的面试官
    给老婆的一篇文章
    机器学习:选对时机直线超车
    面试技巧:带走面试官的节奏
    微信红包的随机算法是怎样实现的?
    全栈技术导图
    AI时代:推荐引擎正在塑造人类
    冲顶大会APP技术选型及架构设计
    多域名解析及延伸知识点
    在编程中为所欲为[圣诞版]
  • 原文地址:https://www.cnblogs.com/qingzhujushi/p/10200806.html
Copyright © 2020-2023  润新知