废话不多说,首先看下运行效果:
介绍:
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切换界面