PermissionHelper+ContentProvider实现扫描本地音乐

废话不多说,首先看下运行效果:



介绍:

MediaStore中定义了一系列的数据表格,通过ContentResolver提供的查询接口,我们能够得到各种须要的媒体信息。通过下面两个URI能够扫描设备外部和内部的媒体文件。Android系统提供了MediaProvider,MediaStore。MediaScanner接口,通过Content Provider的方式提供给用户。

但是,在使用ContentProvider扫描音乐时一定要先获取到权限,特别是在安卓6.0以后的设备,要动态授权,否则程序必定崩溃。(这点我想吐槽csdn上有些文章,和下载的demo,直接把ContentProvider扫描音乐写上去,权限都不给)

当然最后显示在RecyclerView上面

准备工作:

AndroidManifest:


导入依赖:


扫描二维码关注公众号,回复: 2690347 查看本文章

第二个依赖是,Android 6.0 权限申请辅助 ----PermissionsHelper

PermissionsHelper解析                   这是didikee大佬写的      

准备工作做完后,首先把布局写出来。

本地音乐界面

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.administrator.mymusic.LogicFragment">

  <!--  <ListView
        android:id="@+id/logic_lv"
        android:layout_width="match_parent"
        android:divider="@null"
        android:layout_height="match_parent"></ListView>-->

        <android.support.v7.widget.RecyclerView
            android:id="@+id/logic_lv"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        </android.support.v7.widget.RecyclerView>
</LinearLayout>



music_item布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp">

    <View
        android:id="@+id/musicitem_playing_v"
        android:layout_width="3dp"
        android:layout_height="50dp"
        android:visibility="invisible"
        android:background="@color/colorAccent"
        />

    <ImageView
        android:id="@+id/musicitem_album_imgv"
        android:layout_marginLeft="3dp"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
        android:src="@mipmap/ic_launcher"/>

    <TextView
        android:id="@+id/musicitem_title_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/musicitem_album_imgv"
        android:textSize="20dp"
        android:text="成都"/>
    <TextView
        android:id="@+id/musicitem_artist_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/musicitem_album_imgv"
        android:layout_below="@+id/musicitem_title_tv"
        android:layout_marginLeft="20dp"
        android:layout_gravity="bottom"
        android:text="赵雷"/>

    <ImageView
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_marginRight="10dp"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:layout_margin="10dp"
        android:src="@mipmap/ic_music_list_icon_more" />
    <View
        android:layout_width="match_parent"
        android:layout_height="1sp"
        android:layout_toRightOf="@+id/musicitem_album_imgv"
        android:background="#cccccc"
        android:layout_alignParentBottom="true"/>

</RelativeLayout>

Java代码

工具类

public class Common {

    public static List<Music> musicList = new ArrayList<>();
}


public class Music {
    /**
     * 在这里所有的属性都是用public修饰的,所以在以后调用时直接调用就可以了
     * 如果用private修饰是需要构建set和get方法
     */
    //歌名
    public String title;
    //歌唱者
    public String artist;
    //专辑名
    public  String album;
    public  int length;
    //专辑图片
    public Bitmap albumBip;
    public String path;
    public boolean isPlaying;
}
adapter


import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.administrator.mymusic.R;
import com.example.administrator.mymusic.entity.Music;
import com.example.administrator.mymusic.utils.Common;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2018/6/12.
 */

public class MusicShowAdapter extends RecyclerView.Adapter<MusicShowAdapter.MyViewHolder>{
       private Context context;
       private  List<Music> musicList;

    public MusicShowAdapter(Context context, List<Music> musicList) {
        this.context = context;
        this.musicList=musicList;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view=View.inflate(parent.getContext(), R.layout.music_item,null);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        //赋值 准确的是绑定赋值的中介
         holder.titleTv.setText(Common.musicList.get(position).title);
         holder.artistTv.setText(Common.musicList.get(position).artist + "-" + Common.musicList.get(position).album);
         holder.albumImgv.setImageBitmap(Common.musicList.get(position).albumBip);
        if (Common.musicList.get(position).isPlaying) {
           holder.isPlayingView.setVisibility(View.VISIBLE);
        } else {
           holder.isPlayingView.setVisibility(View.INVISIBLE);
        }
              holder.itemView.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View view) {
                      if (listener!=null){
                          listener.onClick(musicList.get(position).title,musicList.get(position).path);
                      }
                  }
              });
    }

    @Override
    public int getItemCount() {
        return Common.musicList==null?0:Common.musicList.size();
    }

    public class MyViewHolder  extends  RecyclerView.ViewHolder{
        TextView titleTv;
        TextView artistTv;
        ImageView albumImgv;
        View isPlayingView;
        public MyViewHolder(View itemView) {
            super(itemView);
            titleTv=itemView.findViewById(R.id.musicitem_title_tv);
            artistTv=itemView.findViewById(R.id.musicitem_artist_tv);
            albumImgv=itemView.findViewById(R.id.musicitem_album_imgv);
            isPlayingView=itemView.findViewById(R.id.musicitem_playing_v);
        }
    }
    private MyClickListener listener;

    //传入点击事件具体实现的方法
    public void setListener(MyClickListener listener) {
        this.listener = listener;
    }

    //声明一个点击事件的接口
    public interface MyClickListener{
        void onClick(String title,String path);
        //void onLongClick(String username,int postion);
    }

}

关于RecyclerView,如果不知道可以看一下我写的关于RecyclerView的文章,非常好理解。

扫描本地音乐java代码

import android.Manifest;
import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.administrator.mymusic.adapter.MusicShowAdapter;
import com.example.administrator.mymusic.entity.Music;
import com.example.administrator.mymusic.utils.Common;
import com.master.permissionhelper.PermissionHelper;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 */
public class LogicFragment extends Fragment {
    private String TAG = "HelloActivity";                                       //下面两个属性和获取mediadatabase的权限有关系,可查阅代码块下的链接
    private PermissionHelper permissionHelper;
   // private ListView listView;                                                          //创建ListView的对象
    private  List<Music> musicList;                                                          //将Music放入List集合中,并实例化List<Music>
  //  private List<ListView> listViewList;
   // private MusicAdapter adapter;
    private RecyclerView recyclerView;
    private MusicShowAdapter adapter;
    public LogicFragment() {
        // Required empty public constructor
    }

    //LoginFrangment中的onCreate()方法
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_logic, container, false);        //创建View对象,返回view

// 关于权限的代码
        permissionHelper = new PermissionHelper(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
        permissionHelper.request(new PermissionHelper.PermissionCallback() {
            @Override
            public void onPermissionGranted() {
                initListView();                                          //获取权限后扫描数据库获取信息
                Log.d(TAG, "onPermissionGranted() called");
            }

            @Override
            public void onIndividualPermissionGranted(String[] grantedPermission) {
                Log.d(TAG, "onIndividualPermissionGranted() called with: grantedPermission = [" + TextUtils.join(",", grantedPermission) + "]");
            }

            @Override
            public void onPermissionDenied() {
                Log.d(TAG, "onPermissionDenied() called");
            }

            @Override
            public void onPermissionDeniedBySystem() {
                Log.d(TAG, "onPermissionDeniedBySystem() called");
            }
        });
// 权限代码结束

          recyclerView=view.findViewById(R.id.logic_lv);
         adapter=new MusicShowAdapter(getActivity(),musicList);
         recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
        return view;
    }




    // 权限代码
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (permissionHelper != null) {
            permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
// 权限代码结束

    //nitListView()实现对手机中MediaDataBase的扫描
    private void initListView() {
         Common.musicList.clear();//Common
        //获取ContentResolver的对象,并进行实例化
        ContentResolver resolver = getActivity().getContentResolver();
        //获取游标
        Cursor cursor = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null); //创建游标MediaStore.Audio.Media.EXTERNAL_CONTENT_URI获取音频的文件,后面的是关于select筛选条件,这里填土null就可以了
        //游标归零
        cursor.moveToFirst();
        do {

            String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));            //获取歌名
            String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));         //获取歌唱者
            String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));           //获取专辑名
            int albumID = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));            //获取专辑图片id
            int length = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
            String path = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
            //创建Music对象,并赋值
            Music music = new Music();
            music.length = length;
            music.title = title;
            music.artist = artist;
            music.album = album;
            music.path = path;
            music.albumBip = getAlbumArt(albumID);
            //将music放入musicList集合中
            Common.musicList.add(music);//Common.musicList

        }
        while (cursor.moveToNext());                                                    //当游标不能搜索到底时,cursor.moveToNext()==false
        cursor.close();                                                                         //关闭游标
    }

    //获取专辑图片的方法
    private Bitmap getAlbumArt(int album_id) {                              //前面我们只是获取了专辑图片id,在这里实现通过id获取掉专辑图片
        String mUriAlbums = "content://media/external/audio/albums";
        String[] projection = new String[]{"album_art"};
        Cursor cur = getActivity().getContentResolver().query(Uri.parse(mUriAlbums + "/" + Integer.toString(album_id)), projection, null, null, null);
        String album_art = null;
        if (cur.getCount() > 0 && cur.getColumnCount() > 0) {
            cur.moveToNext();
            album_art = cur.getString(0);
        }
        cur.close();
        Bitmap bm = null;
        if (album_art != null) {
            bm = BitmapFactory.decodeFile(album_art);
        } else {
            bm = BitmapFactory.decodeResource(getResources(), R.mipmap.touxiang3);
        }
        return bm;
    }

    @Override
    public void onResume() {
        super.onResume();
        adapter.notifyDataSetChanged();
    }

}


由于是放在Fragment里面写的,可以看下上一篇文章,关于ViewPager+Fragment切换界面

二次元传送门

猜你喜欢

转载自blog.csdn.net/qq_38812658/article/details/80714654