フォルダ内のサウンド ファイルの ListView で、ファイルの長さを秒単位で表示したいと考えています。私が取る手順:
- 最初に、soundFiles のインスタンスの ArrayList を作成します。
- 次に for ループで、soundFile.setLength(calculateLength(file[i])) によってデータをインスタンスに追加します。
- この後、CustomArrayAdapter を開始し、それを listView に適用します。
- 私の CustomArrayAdapter では、それを適用します: tvFileLength.setText(soundFile.getLength()); (ホルダー付きですが..)
しかし、私はこれをやっているので、私のアプリはタートルよりも遅いです! (400 個のファイルがあります) この速度を修正する方法はありますか?
private int calculateLength(File yourFile)
throws IllegalArgumentException, IllegalStateException, IOException {
MediaPlayer mp = new MediaPlayer();
FileInputStream fs;
FileDescriptor fd;
fs = new FileInputStream(yourFile);
fd = fs.getFD();
mp.setDataSource(fd);
mp.prepare();
int length = mp.getDuration();
length = length / 1000;
mp.release();
return length;
}
**EDIT**
私が持っている新しいコード:
アクティビティ
myList = new ArrayList<RecordedFile>();
File directory = Environment.getExternalStorageDirectory();
file = new File(directory + "/test/");
File list[] = file.listFiles();
for (int i = 0; i < list.length; i++) {
if (checkExtension(list[i].getName()) == true) {
RecordedFile q = new RecordedFile();
q.setTitle(list[i].getName());
q.setFileSize(readableFileSize(list[i].length()));
//above is the size in kB, is something else but I
//also might move this to the AsyncTask!
myList.add(q);
}
}
new GetAudioFilesLength(myList).execute();
非同期タスク
List<RecordedFile> mFiles = new ArrayList<RecordedFile>();
public GetAudioFilesLength(List<RecordedFile> theFiles) {
mFiles = theFiles;
}
@Override
protected String doInBackground(Void... params) {
File directory = Environment.getExternalStorageDirectory();
// File file = new File(directory + "/test/");
String mid = "/test/";
for (RecordedFile fileIn : mFiles) {
File file = new File(directory + mid + fileIn.getTitle());
try {
int length = readableFileLengthSeconds(file);
fileIn.setFileLengthSeconds(length);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Do something with the length
// You might want to update the UI with the length of this file
// with onProgressUpdate so that you display the length of the files
// in real time as you process them.
}
return mid;
}
@Override
protected void onProgressUpdate(Void... values) {
}
@Override
protected void onPostExecute(String result) {
// Update the UI in any way you want. You might want
// to store the file lengths somewhere and then update the UI
// with them here
}
/*
* @Override protected void onPreExecute() { }
*/
public int readableFileLengthSeconds(File yourFile)
throws IllegalArgumentException, IllegalStateException, IOException {
MediaPlayer mp = new MediaPlayer();
FileInputStream fs;
FileDescriptor fd;
fs = new FileInputStream(yourFile);
fd = fs.getFD();
mp.setDataSource(fd);
mp.prepare(); // might be optional
int length = mp.getDuration();
length = length / 1000;
mp.release();
return length;
}
素晴らしい、部分的には機能しますが!残りの 2 つの質問があります。
- これは問題なく効率的に見えますか?
- リストビューの最初の 100 要素で動作し、その後 0 が表示され、onProgressUpdate と関係があると思いますが、どうすればこれを機能させることができるかわかりません。