栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

移动互联网开发技术教学网站项目研究第二篇

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

移动互联网开发技术教学网站项目研究第二篇

2021@SDUSC

目录
  • 移动互联网开发技术教学网站项目研究第二篇
    • 歌曲相关方法分析
      • 歌曲实体类
      • 歌曲列表
      • 音乐适配器——把数据映射到前端页面上的中介
      • 音乐列表显示和播放监听器`void init()`
      • 权限管理
      • `onCreate()`初始化

移动互联网开发技术教学网站项目研究第二篇 歌曲相关方法分析 歌曲实体类
private String name;//歌曲名
    private String singer;//歌手
    private long size;//歌曲所占空间大小
    private int duration;//歌曲时间长度
    private String path;//歌曲地址
    private long  albumId;//图片id
    private long id;//歌曲id

歌曲属性有:歌曲名、歌手、歌曲播放时间、存放在手机本地空间的地址,歌曲包的大小,歌曲封面、歌曲id。定义了getter和setter方法。

歌曲列表

获取本地音乐列表
private List pick()该方法获取设备本地音乐列表,返回一个List

Cursor cursor= getApplicationContext().getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                null,null,null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);

用Cursor对象对Android本地的SQLite数据库进行操作,存放获取的歌曲列表信息。先获取应用程序环境的上下文,然后通过Android的内容提供器访问位于不同程序中的音乐文件数据,并且保证被访问数据的安全性。最后查询Android系统中媒体文件的音乐文件信息,从而获得本地音乐列表。
因为需要返回的音乐列表是全局数据,播放的Activity和其他view也需要访问它,不能随当前Activity关闭而消失,所以先用getApplicationContext()获取应用程序环境的上下文,它返回的上下文会随应用存在而存在。如果用getApplication()虽然与上述方法返回值相同,但是生命周期不同。
getContentResolver()获取内容提供器中共享的数据,query()
提供查询操作,Audio,Files, Images, Video等媒体文件的URI信息和数据表结构信息封装在android.provider.MediaStore类中,属性EXTERNAL_CONTENT_URI明确标识访问的数据位于哪个程序某一张表里面的数据,属性DEFAULT_SORT_ORDER为列表默认的排序方式。其他projection : selection: selectionArfs:指定查询列的条件,不需要考虑,为null。查询完成后返回的仍为Cursor对象,后面需要将数据从查询到的对象中读取出来。

if(cursor!=null){
            while (cursor.moveToNext()){
                song=new Song();
                //获取名字等信息
                String name=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
                String singer=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
                String path=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
                int duration=cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
                long size=cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
                long albumid=cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
                long id=cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
                //有的时候名字和歌手会放在一起
                if(name.contains("-")){
                    String[] str=name.split("-");
                    singer=str[0];
                    name=str[1];
                }
                //把它放入song中
                song.setName(name);
                song.setSinger(singer);
                song.setPath(path);
                song.setDuration(duration);
                song.setSize(size);
                song.setAlbumId(albumid);
                song.setId(id);
                //把建好的歌曲信息放入list中
                //除去Unknown的作者
                if(!singer.contains("unknown")) {
                    list.add(song);
                }
            }
        }

如果查询结果不为空,用方法moveTonext()遍历Cursor cursor对象的每一行,方法getColumnIndexOrThrow()获取歌曲的各种信息。最后存放放到该方法开始建立的List list=new ArrayList();中,这样就获取了设备本地的歌曲列表。

音乐适配器——把数据映射到前端页面上的中介
ublic class SongAdapter extends ArrayAdapter {
    private final int resourceid;
    public SongAdapter(Context context, int textViewResourceid, List songs){
        super(context,textViewResourceid,songs);
        resourceid=textViewResourceid;
    }
    @SuppressLint("ResourceType")
    public View getView(int positon , View convertView, ViewGroup parent){
        Song song=(Song)getItem(positon);
        View view = LayoutInflater.from(getContext()).inflate(resourceid,null);
        ImageView songImage=(ImageView)view.findViewById(R.id.song_cover);
        TextView textView=(TextView)view.findViewById(R.id.song_name);
        TextView singer_View=(TextView)view.findViewById(R.id.song_singer);
        songImage.setImageResource(R.raw.music);
        textView.setText(song.getName());
        singer_View.setText(song.getSinger());
        return view;
    }
}

为了将已取出的音乐列表显示到前端的页面中创建一个音乐适配器类SongAdapter,继承ArrayAdapter类。重写getView()方法绘制页面,int positon判断当前显示的条目在屏幕上的位置,然后通过getItem(positon)在定义的列表中取值显示在屏幕上。当需要浏览已经加载过但是不在当前界面中的条目时,可以将这些条目缓存到View convertView,提高效率。ViewGroup parent存放当前界面的所有条目。根据资源布局idresourceid找到音乐条目前端页面文件。findViewById(R.id.song_name)在R中的索引按id找到音乐条目对应的song_name组件。setImageResource(R.raw.music)找到歌曲的封面id。setText(song.getName())设置歌曲名称。最后返回绘制好的条目界面。

音乐列表显示和播放监听器void init()
SongAdapter songAdapter=new SongAdapter(
                Music_List.this,R.layout.music_item,list
        );

初始化一个歌曲适配器,music_item是歌曲条目布局。

List data=new ArrayList();
Iterator iterator=list.iterator();
while (iterator.hasNext()){
       Song song=(Song) iterator.next();
       data.add(song.getName()+"-"+song.getSinger());
}

遍历歌曲列表,获取歌曲名称和歌手。

ListView listView=(ListView)findViewById(R.id.List_song);
listView.setAdapter(songAdapter);

添加歌曲列表List_song布局,并为其添加适配器。

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                Song song = list.get(position);
                //跳转到播放界面
                if (intent == null) {
                    intent = new Intent(Music_List.this, MusicActivity.class);
                    intent.putExtra("path", song.getPath());
                    intent.putExtra("song_name", song.getName());
                    intent.putExtra("singer", song.getSinger());
                    finish();
                    startActivity(intent);
                } else {
                    Toast.makeText(Music_List.this,"还有歌曲在播放",Toast.LENGTH_SHORT);
                }
            }
        });

找到用户想要播放的歌曲,然后跳转到音乐播放界面MusicActivity。如果当前有音乐在播放,弹出提示框两秒Toast.LENGTH_SHORT。

权限管理
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if(requestCode==1){
            if(permissions[0].equals(Manifest.permission.READ_EXTERNAL_STORAGE)&&grantResults[0]== PackageManager.PERMISSION_GRANTED){
                //用户同意授权,执行读取文件的代码
                list = pick();
                init();
            }else{
                //若用户不同意授权,直接暴力退出应用。
                finish();
            }
        }
    }

读取手机的存储空间需要向用户获取权限,Android 6.0 之后需要动态获取权限,所以请求用户访问设备上文件的权限Manifest.permission.READ_EXTERNAL_STORAGE。取得权限后就获取音乐列表并显示。如果用户拒绝则直接退出应用程序。

onCreate()初始化
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.music_list);
        //检查当前权限(若没有该权限,值为-1;若有该权限,值为0)
        int hasReadExternalStoragePermission = ContextCompat.checkSelfPermission(getApplication(),Manifest.permission.READ_EXTERNAL_STORAGE);
        if(hasReadExternalStoragePermission== PackageManager.PERMISSION_GRANTED){
            list = pick();
            init();
        }else{
            //若没有授权,会弹出一个对话框(这个对话框是系统的,开发者不能自己定制),用户选择是否授权应用使用系统权限
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
        }
    }

在 onCreate 函数中初始化调用上述方法,hasReadExternalStoragePermission== PackageManager.PERMISSION_GRANTED检查用户是否给予权限,如果没有则弹出下图图所示对话框。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/327666.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号