我正在开发一个应用程序,它可以读取SD卡上的音频文件,并在按下开始按钮时播放它们。奇怪的是,应用程序在我的Droid RAZR上正常运行,但在其他设备上崩溃。我已经在我父亲的Droid RAZR上尝试过它,以及我的朋友三星Galaxy S2和我的旧Droid Incredible。我将SD卡从我的手机放入我的Incredible中并且它工作了一次,但是当我把它放在爸爸的手中时,我没有得到相同的结果。
这是光标方法的代码:
private void init_phone_music_grid() {
System.gc();
String[] proj = { MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST }; // was originally set to MediaStore.Video.Media.ARTIST
musiccursor = managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
proj, MediaStore.Audio.Media.DURATION + ">= 65000", null, null );
count = musiccursor.getCount(); //causes force close, when plugged in sometimes; not an issue with StateCheck class
musiclist = (ListView) findViewById(R.id.lvTrackList);
musiclist.setAdapter(new MusicAdapter(getApplicationContext()));
musiclist.setOnItemClickListener(musicgridlistener);
mMediaPlayer = new MediaPlayer();
}
这是OnCreate方法的代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initializeVars();
init_phone_music_grid();
//countDown();
trackList.setCacheColorHint(Color.GRAY);
start.setEnabled(false);
pause.setEnabled(false);
reset.setEnabled(false);
trackList.setVisibility(View.INVISIBLE);
instructions.setVisibility(View.VISIBLE);
//*** USED FOR TESTING!!! ***//
Calendar date = Calendar.getInstance();
if(date.get(Calendar.DAY_OF_YEAR) >= 6) {
AlertDialog.Builder builder1 = new AlertDialog.Builder(this);
builder1.setCancelable(false);
builder1.setMessage("This test version of Musercise has ended! Buy the real one if you want to use it!");
builder1.setPositiveButton("Close",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
finish();
}
});
AlertDialog alert11 = builder1.create();
alert11.show();
}
// END TESTING
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
chrono.setBase(SystemClock.elapsedRealtime() + timeWhenStopped);
chrono.start();
for(int i = 0; i <= trackList.getCount() - 1; i++) {
randomArray[i] = i;
}
shuffleArray(randomArray);
if(!isPaused) {
MyTimerTask myTask = new MyTimerTask();
timer = new Timer();
timer.schedule(myTask, (totalTimeLong)*60000);
}else if(resumeNeeded){
MyTimerTask myTask = new MyTimerTask();
timer = new Timer();
timer.schedule(myTask, timeRemainingAfterPause);
resumeNeeded = false;
pause.setEnabled(true);
}
if(!mMediaPlayer.isPlaying()) {
music_column_index = musiccursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
musiccursor.moveToPosition(randomArray[0]);
String filename = musiccursor.getString(music_column_index);
try {
mMediaPlayer.setDataSource(filename);
} 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();
}
try {
mMediaPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mMediaPlayer.start();
}
if(mMediaPlayer.isPlaying()) {
includeWarmUp.setEnabled(false);
includeCoolDown.setEnabled(false);
test.setEnabled(false);
start.setEnabled(false);
trackList.setVisibility(View.VISIBLE);
instructions.setText("Track List:");
}
isPaused = false;
drawer.setBackgroundResource(R.drawable.run);
}
});
pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
isPaused = true;
resumeNeeded = true;
timeWhenStopped = chrono.getBase() - SystemClock.elapsedRealtime();
chrono.stop();
mMediaPlayer.pause();
long elapsedMillis = SystemClock.elapsedRealtime() - chrono.getBase();
timer.cancel();
timeRemainingAfterPause = totalTimeLong*60000 - elapsedMillis;
start.setEnabled(true);
pause.setEnabled(false);
drawer.setBackgroundResource(R.drawable.pause);
}
});
reset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
chrono.stop();
timeWhenStopped = 0;
chrono.setBase(SystemClock.elapsedRealtime());
mMediaPlayer.reset();
start.setTextColor(Color.BLACK);
pause.setTextColor(Color.BLACK);
includeWarmUp.setEnabled(true);
includeCoolDown.setEnabled(true);
test.setEnabled(true);
start.setEnabled(true);
pause.setEnabled(true);
trackList.setEnabled(true);
drawer.setBackgroundResource(R.drawable.ic_launcher);
}
});
test.setOnSeekBarChangeListener(this);
}
崩溃时的Logcat:
01-03 19:41:01.678: E/AndroidRuntime(499): android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
01-03 19:41:01.678: E/AndroidRuntime(499): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
01-03 19:41:01.678: E/AndroidRuntime(499): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
01-03 19:41:01.678: E/AndroidRuntime(499): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
01-03 19:41:01.678: E/AndroidRuntime(499): at android.database.CursorWrapper.getString(CursorWrapper.java:135)
01-03 19:41:01.678: E/AndroidRuntime(499): at com.flannigan.musercise.MuserciseActivity$3.onClick(MuserciseActivity.java:133)
01-03 19:41:01.678: E/AndroidRuntime(499): at android.view.View.performClick(View.java:2408)
01-03 19:41:01.678: E/AndroidRuntime(499): at android.view.View$PerformClick.run(View.java:8816)
01-03 19:41:01.678: E/AndroidRuntime(499): at android.os.Handler.handleCallback(Handler.java:587)
01-03 19:41:01.678: E/AndroidRuntime(499): at android.os.Handler.dispatchMessage(Handler.java:92)
01-03 19:41:01.678: E/AndroidRuntime(499): at android.os.Looper.loop(Looper.java:123)
01-03 19:41:01.678: E/AndroidRuntime(499): at android.app.ActivityThread.main(ActivityThread.java:4627)
01-03 19:41:01.678: E/AndroidRuntime(499): at java.lang.reflect.Method.invokeNative(Native Method)
01-03 19:41:01.678: E/AndroidRuntime(499): at java.lang.reflect.Method.invoke(Method.java:521)
01-03 19:41:01.678: E/AndroidRuntime(499): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-03 19:41:01.678: E/AndroidRuntime(499): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-03 19:41:01.678: E/AndroidRuntime(499): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:1)
您收到此error
:
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
表示您的cursor size
为0,而您正试图从index 0
获取数据,该数据会变为force close
。
这一行,
String filename = musiccursor.getString(music_column_index);
尝试用这种方式覆盖,
if(music_column_index > 0)
String filename = musiccursor.getString(music_column_index);
else
// Toast some error message
感谢。
答案 1 :(得分:1)
不要只是光标上的moveToPosition()
,确保光标可以转到那个位置。
对游标使用附加检查,即游标不为空,moveToFirst()
为真,行数位于您提供给moveToPosition()
的任何索引之间。
if( cur != null && cur.getCount() > 0){
int rnd = //--some random number--
//--clamp rnd to cursor size--
rand = Math.max(0,Math.min(cur.getCount() - 1,rnd));
if(cur.moveToPosition(rnd)){
//--do stuff--
}
}
除此之外,不要按列索引获取值,而是重用已定义的列名:
musiccursor.getString(musiccursor.getColumnIndex(MediaStore.Audio.Media.DATA));
如果它在投影中,则将在数据的结果光标中。