PDA

View Full Version : ارور Index -1 requested, with a size of 24



hamedjj
یک شنبه 28 اردیبهشت 1393, 03:29 صبح
سلام
من تو کلاس mainactivity دارم از downloadManager برای دانلود آهنگ ها در listview استفاده میکنم که ارور زیر را در logcat دریافت کردم:


FATAL EXCEPTION: main
android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 24
at android.database.AbstractCursor.checkPosition(Abst ractCursor.java:424)
at android.database.AbstractWindowedCursor.checkPosit ion(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString( AbstractWindowedCursor.java:50)

تو stackoverflow این سوال را مطرح کردم که جواب این بود:


Your Cursor is not positioned on a valid row. Use moveToFirst() or one of the other move...() methods to position the Cursor on the row that you wish to read from.

که میگه cursor شما در موقیت یا پوزیشن درستی نیست . از movetofirst() یا ... استفاده کن تا موقعیت cursor را در سطر ها درست کنید .(کامل ترجمه نکردم ... منظورش تقریبا همینه)

خوب الان برای این کار باید در کلاس downloadManager خودم چیکار کنم که این ارور را دوباره نگیرم:

mainActivity :


public class MainActivity extends ActionBarActivity {

public ListView listview;
private DownloadManager mgr=null;
private long lastDownload;
private String name;
private MediaPlayer mp;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mgr=(DownloadManager) getSystemService(DOWNLOAD_SERVICE);
registerReceiver(onComplete,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPL ETE));
registerReceiver(onNotificationClick,new IntentFilter(DownloadManager.ACTION_NOTIFICATION_C LICKED));

mp = new MediaPlayer();

MyDatabase MyDatabase = new MyDatabase(this);
SQLiteDatabase mydb = MyDatabase.getReadableDatabase();
Cursor c = mydb.rawQuery("select id from list" , null);

String[] array = new String[c.getCount()];
int i = 0;
if (c.moveToFirst()) {
do {
try {
array[i] = c.getString(c.getColumnIndex("id"));
i++;
} catch (Exception e) {
e.printStackTrace();
}
} while (c.moveToNext());
}

ListView list = (ListView) findViewById(R.id.listView1);
list.setAdapter(new MyAdapter(this, array));
list.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> arg0, View v, int position,
long id) {
Download();
}
});

}


protected void Download() {

MyDatabase MyDatabase = new MyDatabase(this);
SQLiteDatabase mydb = MyDatabase.getReadableDatabase();
Cursor c = mydb.rawQuery("select id,url from list" , null);

name = "hamed"+c.getString(c.getColumnIndex("id"))+".mp3";
Uri uri=Uri.parse(c.getString(c.getColumnIndex("url")));
lastDownload=mgr.enqueue(new DownloadManager.Request(uri)
.setAllowedNetworkTypes(DownloadManager.Request.NE TWORK_WIFI |
DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("DOWNLOAD")
.setDescription("Please Wait...")
.setDestinationInExternalPublicDir("/Download/",name));
Toast.makeText(this, "آغاز دانلود در نوتیفیکیشن دستگاه شما", Toast.LENGTH_SHORT).show();

}

/////////////////////////// نمایش پیغامهای وضعیت دانلود
private CharSequence statusMessage(Cursor c) {
// TODO Auto-generated method stub
String msg="???";
switch(c.getInt(c.getColumnIndex(DownloadManager.C OLUMN_STATUS))) {
case DownloadManager.STATUS_FAILED:
msg="خطا در دانلود!";
break;
case DownloadManager.STATUS_PAUSED:
msg="توقف دانلود!";
break;
case DownloadManager.STATUS_PENDING:
msg="آماده شدن برای دانلود";
break;
case DownloadManager.STATUS_RUNNING:
msg="در حال بارگیری";
break;
case DownloadManager.STATUS_SUCCESSFUL:
msg="دانلود کامل شد";
break;
default:
msg="دانلودی به چشم نمیخورد";
break;
}
return(msg);
}
///////////////////////////////وقتی دانلود کامل شد این تابع اجرا میشود
BroadcastReceiver onComplete=new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
Toast.makeText(getApplicationContext(), "دانلود کامل شد", Toast.LENGTH_SHORT).show();

}
};
////////////////////////////// وقتی نوار دانلود در نوتیفیکیشن را لمس کنیم
BroadcastReceiver onNotificationClick=new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
display();
}

private CharSequence display() {
// TODO Auto-generated method stub
Cursor c=mgr.query(new DownloadManager.Query().setFilterById(lastDownload ));
if (c==null) {
Toast.makeText(getApplicationContext(), "فایلی یافت نشد", Toast.LENGTH_SHORT).show();
}
else {
c.moveToFirst();
Toast.makeText(getApplicationContext(), statusMessage(c), Toast.LENGTH_SHORT).show();
}

return null;
}
};

protected void start(String name2) {
// TODO Auto-generated method stub
try {
mp.reset();
String mp3Uri = Environment.getExternalStorageDirectory()+ "/Download/"+name2;
mp.setDataSource(mp3Uri);
mp.prepare();
mp.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}




در کد بالا با کلیک بر روی لیست ویو متد download() اجرا میشه که باید شروع به دانلود بکنه که crash میشه

poorman
یک شنبه 28 اردیبهشت 1393, 05:26 صبح
سلام

حامد جان دقیقا خطا مال همون تابع دانلود هست

شما هیچ شرطی برای کوئری که از دیتابیس select میکنی نذاشتی و اون کوئری دانلود میاد 24 تا سطر تیبل رو توی cursor میریزه و شما هم بدون مشخص کردن اینکه کدوم سطر رو نیاز داری، میگی اطلاعات رو توی متغیر name بریز

برای اینکه درست بشه به هرحال شما نیاز به moveToFirst داری اما توی این حالت اگر روی هر آیتم از لیست کلیک کنی، فقط آیتم اول رو دانلود میکنه

پس بهترین کار اینه که position آیتم کلیک شده رو به تابع دانلود بفرستی و بعد با متد moveToPosition اطلاعات مورد نظرت رو از cursor بخونی

hamedjj
سه شنبه 30 اردیبهشت 1393, 02:01 صبح
سلام

حامد جان دقیقا خطا مال همون تابع دانلود هست

شما هیچ شرطی برای کوئری که از دیتابیس select میکنی نذاشتی و اون کوئری دانلود میاد 24 تا سطر تیبل رو توی cursor میریزه و شما هم بدون مشخص کردن اینکه کدوم سطر رو نیاز داری، میگی اطلاعات رو توی متغیر name بریز

برای اینکه درست بشه به هرحال شما نیاز به moveToFirst داری اما توی این حالت اگر روی هر آیتم از لیست کلیک کنی، فقط آیتم اول رو دانلود میکنه

پس بهترین کار اینه که position آیتم کلیک شده رو به تابع دانلود بفرستی و بعد با متد moveToPosition اطلاعات مورد نظرت رو از cursor بخونی

چطور میتونم position آیتم را به به تابع download بفرستم؟

poorman
سه شنبه 30 اردیبهشت 1393, 02:30 صبح
توی تعریف تابع دانلود اینطوری مینویسی

protected void Download(int position) {

}

موقع فراخوانی هم که توی همون رویداد onItemClick مینویسی Download(position);

توی خود تابع دانلود هم که میگی c.moveToPosition(position);

hamedjj
سه شنبه 30 اردیبهشت 1393, 02:39 صبح
توی تعریف تابع دانلود اینطوری مینویسی

protected void Download(int position) {

}

موقع فراخوانی هم که توی همون رویداد onItemClick مینویسی Download(position);

توی خود تابع دانلود هم که میگی c.moveToPosition(position);

دمت گرم ... حل شد :تشویق:

hamedjj
سه شنبه 30 اردیبهشت 1393, 03:22 صبح
تو تابع start که یرای پخش آهنگه باید همین کارو بکنم؟
چون میخوام بنویسم اگر این آهنگ وجود داشت پخش کن اگر نه دانلود کن


if (f1.exists()){
start(name, position);
}else {
Download(position);
}





protected void start(String name2) {
// TODO Auto-generated method stub
try {
mp.reset();
String mp3Uri = Environment.getExternalStorageDirectory()+ "/Download/"+name2;
mp.setDataSource(mp3Uri);
mp.prepare();
mp.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

hamedjj
سه شنبه 30 اردیبهشت 1393, 03:43 صبح
وقتی تابع start را اضافه میکنم همون ارور position را میده


name = "hamed"+c.getString(c.getColumnIndex("id"))+".mp3";
File f1 = new File(Environment.getExternalStorageDirectory() +"/Download/"+name);
if (f1.exists()){
start(name, position);
}else {
Download(position);
}

poorman
سه شنبه 30 اردیبهشت 1393, 15:48 عصر
نه دیگه به تابع start کاری نداشته باش

بذار مثل قبل باشه

چون تابع استارت اسم رو میگیره و پخش میکنه، دیگه کاری به position نداره

hamedjj
سه شنبه 30 اردیبهشت 1393, 19:46 عصر
گرفتم ... باید c.moveToPosition(position); را درون onitemclick میذاشتم
حل شد

poorman (http://barnamenevis.org/member.php?295320-poorman) جان دمت گرم که کمک کردی ... خیلی حال دادی
CursorAdapter از این دردسرها نداشت به همین خاطر ازش استفاده میکردم
بازم ممنون :قلب:

poorman
سه شنبه 30 اردیبهشت 1393, 21:31 عصر
قربونت، وظیفه بود حامد جان

c.moveToPosition رو هرجایی که داری اطلاعات رو از دیتابیس میخونی و میخوای بریزی تو آرایه، میتونی استفاده کنی

توی اون کد اول، اینو باید توی تابع دانلود مینوشتی

حالا باز اگه اینا رو اوردی توی تابع onItemClick، همونجا بنویس

hamedjj
چهارشنبه 31 اردیبهشت 1393, 01:34 صبح
اول این کد را تو کلاس main نوشتم حالا میخوام تو کلاس adapter بنویسم
حالا ایندفعه این ارور را میده: (24 به 1 تبدیل شد)
Index -1 requested, with a size of 1اینجا دیگه مشکل چیه؟؟ :متفکر:

تو کلاس adapter دیتابیس به این شکل تعریف شده : (Values[position])

public Cursor database(final int position) {
MyDatabase MyDatabase = new MyDatabase(context);
SQLiteDatabase mydb = MyDatabase.getReadableDatabase();
Cursor cur = mydb.rawQuery("SELECT id,name,category,like,url FROM list WHERE id='"+values[position]+"'", null);
return cur;
}


کل کلاس adapter :


@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_S ERVICE);
View rootview = inflater.inflate(R.layout.item, parent, false);

mgr = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE) ;
context.registerReceiver(onComplete,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPL ETE));
context.registerReceiver(onNotificationClick,new IntentFilter(DownloadManager.ACTION_NOTIFICATION_C LICKED));
mp = new MediaPlayer();

TextView tv1 = (TextView)rootview.findViewById(R.id.txt_name);
TextView tv2 = (TextView)rootview.findViewById(R.id.txt_numer);
ImageView img = (ImageView) rootview.findViewById(R.id.imageView1);
CheckBox repeatChkBx = (CheckBox) rootview.findViewById(R.id.favorite_check);
TextView id = (TextView)rootview.findViewById(R.id.id);

Cursor cur = database(position);
if (cur != null) {
cur.moveToFirst();}

id.setText(String.valueOf(cur.getString(cur.getCol umnIndex("like"))));
id.setVisibility(View.GONE);

String me = cur.getString(cur.getColumnIndex("like"));
if (me.equals("yes")) {
repeatChkBx.setChecked(true);
}

tv1.setText(cur.getString(cur.getColumnIndex("name")));
tv2.setText(cur.getString(cur.getColumnIndex("category")));
img.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Cursor cur = database(position);
cur.moveToPosition(position);

name = "hamed"+cur.getString(cur.getColumnIndex("id"))+".mp3";
File f1 = new File(Environment.getExternalStorageDirectory() +"/Download/"+name);
if (f1.exists()){
start(name);
}else {
Download(position);
}
}
});

repeatChkBx.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
CheckBox chk = (CheckBox) v.findViewById(R.id.favorite_check);
MyDatabase MyDatabase = new MyDatabase(context);
SQLiteDatabase mydb = MyDatabase.getWritableDatabase();

if (chk.isChecked()) {
ContentValues cv = new ContentValues();
cv.put("like", "yes");
mydb.update("list", cv, "id ="+ values[position], null);
}else {
ContentValues cv = new ContentValues();
cv.put("like", "no");
mydb.update("list", cv, "id ="+ values[position], null);
}
}
});

return rootview;
}

public Cursor database(final int position) {
MyDatabase MyDatabase = new MyDatabase(context);
SQLiteDatabase mydb = MyDatabase.getReadableDatabase();
Cursor cur = mydb.rawQuery("SELECT id,name,category,like,url FROM list WHERE id='"+values[position]+"'", null);
return cur;
}

protected void Download(int position) {
Cursor cur = database(position);
cur.moveToPosition(position);

name = "hamed"+cur.getString(cur.getColumnIndex("id"))+".mp3";
Uri uri=Uri.parse(cur.getString(cur.getColumnIndex("url")));
lastDownload=mgr.enqueue(new DownloadManager.Request(uri)
.setAllowedNetworkTypes(DownloadManager.Request.NE TWORK_WIFI |
DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle("DOWNLOAD")
.setDescription("Please Wait...")
.setDestinationInExternalPublicDir("/Download/",name));
Toast.makeText(getContext(), "آغاز دانلود در نوتیفیکیشن دستگاه شما", Toast.LENGTH_SHORT).show();

}

/////////////////////////// نمایش پیغامهای وضعیت دانلود
private CharSequence statusMessage(Cursor c) {
// TODO Auto-generated method stub
String msg="???";
switch(c.getInt(c.getColumnIndex(DownloadManager.C OLUMN_STATUS))) {
case DownloadManager.STATUS_FAILED:
msg="خطا در دانلود!";
break;
case DownloadManager.STATUS_PAUSED:
msg="توقف دانلود!";
break;
case DownloadManager.STATUS_PENDING:
msg="آماده شدن برای دانلود";
break;
case DownloadManager.STATUS_RUNNING:
msg="در حال بارگیری";
break;
case DownloadManager.STATUS_SUCCESSFUL:
msg="دانلود کامل شد";
break;
default:
msg="دانلودی به چشم نمیخورد";
break;
}
return(msg);
}
///////////////////////////////وقتی دانلود کامل شد این تابع اجرا میشود
BroadcastReceiver onComplete=new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
Toast.makeText(getContext(), "دانلود کامل شد", Toast.LENGTH_SHORT).show();

}
};
////////////////////////////// وقتی نوار دانلود در نوتیفیکیشن را لمس کنیم
BroadcastReceiver onNotificationClick=new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
display();
}

private CharSequence display() {
// TODO Auto-generated method stub
Cursor c=mgr.query(new DownloadManager.Query().setFilterById(lastDownload ));
if (c==null) {
Toast.makeText(getContext(), "فایلی یافت نشد", Toast.LENGTH_SHORT).show();
}
else {
c.moveToFirst();
Toast.makeText(getContext(), statusMessage(c), Toast.LENGTH_SHORT).show();
}

return null;
}
};

protected void start(String name2) {
// TODO Auto-generated method stub
try {
mp.reset();
String mp3Uri = Environment.getExternalStorageDirectory()+ "/Download/"+name2;
mp.setDataSource(mp3Uri);
mp.prepare();
mp.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}


این پروژه همون پروژه افزودن به علاقه مندی هاست که دارم برای دانلود روش کار میکنم.

poorman
چهارشنبه 31 اردیبهشت 1393, 01:43 صبح
حامد جان وسط خوندن کدهات خوابم برد :لبخند:

آقا ببین شما وقتی داری برای select کردن شرط میذاری و میگی where آیدی برابر یک چیزی، خب مسلما فقط یک سطر رو برمیگردونه

پس دیگه نمیتونی بگی cursor بره به سطر 10، چون فقط یک سطر انتخاب شده

اونجایی که گفتم cursor رو moveToPosition کن به این خاطر بود که همه سطرها رو داشتی select میکردی

hamedjj
چهارشنبه 31 اردیبهشت 1393, 02:04 صبح
Values[position] را از دیتابیس برداشتم دانلود درست شد
Cursor cur = mydb.rawQuery("SELECT id,name,category,like,url FROM list ", null);

حالا این مشکل پیش اومد :عصبانی++:
فقط یه اسم را نمایش میده
چطوری این مبحث دیتابیس رو یاد گرفتی ... توکله من که اصلا نمیره

http://www.axgig.com/images/52533567274912543237.png

poorman
چهارشنبه 31 اردیبهشت 1393, 02:19 صبح
:قهقهه::قهقهه::قهقهه:

خب الان دیگه فقط داری moveToFirst میکنی

به همین خاطر سطر اول رو فقط نشون میده

الان که شرط رو برداشتی باید moveToPosition کنی دیگه

-------------------------------------------------------

نمیدونم یادته من اینجا واسه دیتابیس و کار باهاش تاپیک میزدم سوال میپرسیدم ؟ یک هفته شب و روزم شده بود دیتابیس :لبخند:

البته خب من SQL کار کردم و با کوئری هاش آشنا هستم

hamedjj
چهارشنبه 31 اردیبهشت 1393, 02:28 صبح
:قهقهه::قهقهه::قهقهه:

خب الان دیگه فقط داری moveToFirst میکنی

به همین خاطر سطر اول رو فقط نشون میده

الان که شرط رو برداشتی باید moveToPosition کنی دیگه

-------------------------------------------------------

نمیدونم یادته من اینجا واسه دیتابیس و کار باهاش تاپیک میزدم سوال میپرسیدم ؟ یک هفته شب و روزم شده بود دیتابیس :لبخند:

البته خب من SQL کار کردم و با کوئری هاش آشنا هستم

ای دمت گرم:تشویق:
درست شد

دیگه مردم از بس روش زوم کردم
تو که یه هفته گذاشتی من فکر کنم باید 1 ماه وقت بزارم فقط دیتابیس کار کنم
فدایی داری