package com.wm.usbscansdk.utils;
import android.os.Handler;
import android.os.Message;
import android.database.Cursor;
import android.provider.MediaStore;
import android.content.Context;
import android.util.Log;
import com.wm.usbscansdk.utils.Song;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ScanFileUtils {
public static final String TAG = "ScanFileUtils";
private ConcurrentLinkedQueue<File> mFileConcurrentLinkedQueue;
private Set<String> mSet;
private List<Song> mAudioData;
private Handler mHandler;
public ScanFileUtils(Handler handler){
mHandler = handler;
mSet = setFileType();
mAudioData = new ArrayList<>();
mFileConcurrentLinkedQueue = new ConcurrentLinkedQueue<>();
}
public void scanRootFile(String path) {
Log.i(TAG, "scanRootFile: path = " + path);
mAudioData.clear();
if (path == null) {
return;
}
File file = new File(path);
//非目录或者目录不存在直接返回
if (!file.exists() || file.isFile()) {
return;
}
//获取到根目录下的文件和文件夹
File[] files = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File file, String s) {
//过滤掉隐藏文件
return !file.getName().startsWith(".");
}
});
//临时存储任务,便于后面全部投递到线程池
List<Runnable> runnableList = new ArrayList<>();
//创建信号量(最多同时有10个线程可以访问)
// Semaphore semaphore = new Semaphore(100);
for (File f : files) {
if (f.isDirectory()) {
//把目录添加进队列
mFileConcurrentLinkedQueue.offer(f);
//创建的线程的数目是根目录下文件夹的数目
Runnable runnable = new Runnable() {
@Override
public void run() {
scanSonFile();
}
};
runnableList.add(runnable);
} else { //判断文件类型是否为音频
String suffix = f.getName().substring(f.getName().indexOf(".") + 1).toLowerCase();
if (mSet.contains(suffix)) {
Song song = new Song();
song.setPath(f.getPath());
song.setSong(f.getName());
mAudioData.add(song);
sendMsg(0);
}
}
}
//获取可用处理器的Java虚拟机的数量
int executorNum = Runtime.getRuntime().availableProcessors();
//固定数目线程池(最大线程数目为cpu核心数,多余线程放在等待队列中)
ExecutorService executorService = Executors.newFixedThreadPool(executorNum);
for (Runnable runnable : runnableList) {
executorService.submit(runnable);
}
//不允许再添加线程
executorService.shutdown();
//等待线程池中的所有线程运行完成
while (true) {
if (executorService.isTerminated()) {
break;
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
sendMsg(1);
}
/**
* 扫描子目录
*/
private void scanSonFile() {
//对目录进行层次遍历
while (!mFileConcurrentLinkedQueue.isEmpty()) {
//队头出队列
final File tmpFile = mFileConcurrentLinkedQueue.poll();
final File[] fileArray = tmpFile.listFiles(new FilenameFilter() {
@Override
public boolean accept(File file, String s) {
//过滤掉隐藏文件
return !file.getName().startsWith(".");
}
});
for (File f : fileArray) {
if (f.isDirectory()) {
//把目录添加进队列
mFileConcurrentLinkedQueue.offer(f);
} else { //判断文件类型是否为音频
String suffix = f.getName().substring(f.getName().indexOf(".") + 1).toLowerCase();
if (mSet.contains(suffix)) {
Song song = new Song();
song.setPath(f.getPath());
song.setSong(f.getName());
// song.setDuration((int) MusicUtils.getAudioFileVoiceTime(f.getPath()));
mAudioData.add(song);
sendMsg(0);
}
}
}
}
}
/**
* 发送通知消息
* @param what 0:音频文件增加 1:扫描完成
*/
private void sendMsg(int what){
Message message = Message.obtain();
message.what = what;
mHandler.sendMessage(message);
}
/**
* 设置需要识别的格式
* ac3和ra,有需求,但是MediaPlayer暂不支持
*/
private Set<String> setFileType(){
Set<String> set = new HashSet<>();
set.add("mp3");
set.add("wma");
set.add("acc");
set.add("ogg");
set.add("mp1");
set.add("mp2");
set.add("m4a");
set.add("m4b");
set.add("wav");
// set.add("ac3");
set.add("ape");
set.add("flac");
// set.add("ra");
set.add("amr");
return set;
}
/**
* 获取音频列表
*/
public List<Song> getScanData(){
Log.i(TAG, "getScanData: size = " + mAudioData.size());
return mAudioData;
}
public List<Song> getMusicData(Context context) {
List<Song> list = new ArrayList<Song>();
// 媒体库查询语句(写一个工具类MusicUtils)
Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null,
null, MediaStore.Audio.AudioColumns.IS_MUSIC);
Log.i(TAG, "MusicUtils: cursor = " + cursor.toString());
if (cursor != null) {
while (cursor.moveToNext()) {
Song song = new Song();
song.song = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
song.singer = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
song.path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
song.duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
song.size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
if (song.size > 1000 * 800) {
// 注释部分是切割标题,分离出歌曲名和歌手 (本地媒体库读取的歌曲信息不规范)
if (song.song.contains("-")) {
String[] str = song.song.split("-");
song.singer = str[0];
song.song = str[1];
}
list.add(song);
}
}
// 释放资源
cursor.close();
}
return list;
}
}