قبلی هم یک خطا بود چون لاگ رو نداده بودین این خطا مشخص نبود برا همین
ببین دیتابیست رو نمیتونه باز کنه برا همین
کدهای MyDatabase.java ت رو بده
دوست عزیز فایل دیتابیس باید توی پوشه assets و توی پوشه databases باشه
به کوچکی و بزرگی حروف اسم پوشه ها هم توجه کنید
سلام
از این دیتابیس چه طوری میشه مثلا واسه یه بانک مطلبی استفاده کرد؟
برای درست کردن دیتابیس جوک یا داستان هیچ تفاوتی وجود نداره
مثلا برای دیتابیس پیامک شما به چند ستون توی جدول نیاز دارید
ستون آیدی، ستون دسته بندی و ستون متن پیامک
یا برای ذخیره داستان
ستون آیدی، ستون فصل، ستون قسمت و ستون داستان
محدودیتی برای ذخیره متن ندارید، میتونید متن های بلند رو هم ذخیره کنید اما برای داستان بهتره متن ها رو تکه تکه کنید تا نمایشتون صفحه ای باشه
به هرحال معماری دیتابیس شما بستگی داره به نیاز شما و اینکه چطوری میخواین ازش استفاده کنید
نمایش اطلاعات هم هیچ فرقی نداره، کوئری مینویسید و اطلاعات برگشتی رو نمایش میدید
پس یعنی باید دیتابیسو از یه برنامه مثل sql expert بسازم؟ یا همین تو هم میشه متون رو کپی کرد؟
آقا ما یه دیتابیس sqlite داریم
چه جوری به لیست ویو خودمون حالی کنیم که مثلا آقا شما فقط بیا ردیف های مثلا ۱ و ۳و ۷ و ۸ جدول رو بگیرو و نشون بده و و با باقی ردیف ها کار نداشته باش؟
سلام
از اون جایی که sqlite asset helper تو صفحه اصلیش فقط آموزش برای eclipse داده؛ برای استفاده از "دیتابیس آماده SQLit" (لایبرری) در android studio 1.0 باید چی کار کرد؟
چون پوشه های android studio 1.0 فرق میکنه، مثلا پوشه libs نداره که بخوایم database رو اونجا بزاریم.
باید از ابزار دیگه ای استفاده کنیم؟ آموزش دیگه ای داره؟
سلام
این که خیلی آسونتره ، اگر دقت کنید نوشته چجوری به پروژتون اضافه کنید > لینک ، فایل build.gradle رو باز کنید و خطی که نوشته رو بهش اضافه کنید، حالا اون بالا یه نوار زرد رنگ میاد که انتهای نوار نوشته Sync Now با انتخابش کتابخونه از اینترنت دانلود و به پروژه اضافه میشه و میتونید استفاده کنید، البته برای پروژه های بعدی به نظر نیاز به اینترنت هم نیست.
خیلی خب حالا اومدیم تا اینجای کار این مراحل رو انجام دادیم،حالا چند تا سوال:
1. database خودمون رو کجا بزاریم؟
2. یه سری قوانین بود مثل، zip کردن database خودمون و ... ؛ در مورد اونا باید چی کار کرد؟
3. مثلا گفته بودن یه پوشه assets بسازین یا یه پوشه database بعد db تون را در اون قرار بدید، در مورد اینا چی؟
دوستان این main منه :
package ir.apriliyaa.book;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import ir.esfandune.database.DBAdapter;
import ir.esfandune.database.apy;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ListView;
import android.app.ListActivity;
import android.content.Intent;
public class Main extends ListActivity {
DBAdapter db;
List<apy> apyha;
ListView lst;
boolean isAll;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn_about = (Button) findViewById(R.id.main_about);
ImageButton btn_sett = (ImageButton) findViewById(R.id.main_setting);
isAll =true;
lst = getListView();
db = new DBAdapter(getBaseContext());
db.open();
Log.i(DBAdapter.TAG, "3");
apyha = db.getAllContacts();
Log.i(DBAdapter.TAG, "4");
if (apyha.size() == 0) {
String destPath = "/data/data/" + getPackageName() + "/databases";
try {
CopyDB(getBaseContext().getAssets().open("mydb"),
new FileOutputStream(destPath + "/apyha"));
Log.i(DBAdapter.TAG, "db copy shod");
apyha = db.getAllContacts();
refreshDisplay();
Log.i(DBAdapter.TAG, apyha.size() + "= tedad apyha");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
refreshDisplay();
}
{
btn_about.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent next = new Intent(getBaseContext(), About.class);
startActivity(next);
}
});
btn_sett.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent next = new Intent(getBaseContext(), Setting.class);
startActivity(next);
}
});
}
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
apy apy = apyha.get(position);
Intent next = new Intent(this, ShowData.class);
next.putExtra("thisapy", apy);
startActivity(next);
}
public void CopyDB(InputStream inputStream, OutputStream outputStream)
throws IOException {
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}
public void refreshDisplay() {
Log.i(DBAdapter.TAG, apyha.size() + "= tedad apyha");
ArrayAdapter<apy> adapter = new apyAdapter(this, apyha);
setListAdapter(adapter);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (isAll) {
apyha = db.getAllContacts();
}else {
apyha=db.findFAVContacts();
}
refreshDisplay();
}
}
مشکل اینجاست که میاد و از دیتابیس می خونه و هر چی هست تو لیست ویو نشون میده !
اما من می خوام مثلا جوری تنظیم بشه که از تیبل ما فقط ستون های 2 و 3 و 4 و 6 رو بخونه
چی کار باید بکنم؟
منو کلافه کرده !
دوست عزیز، من فکر میکنم شما آشنایی لازم با دیتابیس رو ندارید
شما توی main هیچ کدی برای خوندن از دیتابیس ندارید و فقط دارید یک تابع رو صدا میزنید
apyha = db.getAllContacts();
این تابع از اسمش معلومه که داره تمام کانتکت ها رو برمیگردونه، توقع معجزه که ندارید، دارید؟
باید کدهای داخل این تابع رو تغییر بدید دوست عزیز
سلام دوستان
مرسی از راهنمایی های عالی همه
من یه سوال دارم، ببینید ما یه اپلیکیشن میسازیم توشم از دیتابیس استفاده میکنیم خیلی عالی. مشکل من این هست که وقتی برنامه روی یه گوشی جدید نصب میشه دیتابیس خام روی اون گوشی نصب میشه، یه راهکاری وجود داره که نرم افزار با اطلاعات درون دیتابیسش روی گوشی موردنظر نصب بشه؟
آیا باید تمام اطلاعات دیتابیس رو بوسیه کد sql و insert ، توی کدمون وارد کنیم؟ یا میشه یه دیتابیس بسازیم بگیم آقای نرم افزار محترم، پس از نصب برنامه این هم دیتابیست هست که این اطلاعات هم توشه حالا ازش استفاده کن توی نرم افزار
ممنون از پاسخگوییتون
با سلام
من اومدم دیتابیس را به لیست ویو وصل کردم آلانم هیچ مشکلی ندارم
توی لیست ویو من چند تا آیکن گذاشتم که یکی برایش اینه که وقتی کاربر روش کلیک کرد مقدار ستون fav که بصورت پیش فرض 0 گذاشتم 1 بشه؟
حالا فقط موندم چجوری شماره آی دی این قسمت از لیست ویو را انتخاب کنم ؟؟؟
منظور کلی اینه که با توجه به اینکه لیست ویو هستش چجوری مقدار آیتم مربوطه را بگیرم و بعدش دستور sql بکار ببرم که وقتی کاربر روی آیکن مربوط به هر آیتم کلیک کرد شما فقط برو مقدار fav مربوط به اون آیتمو تغییر بده نه همه لیست ویو را ؟؟؟؟؟؟
تشکر اوکی شد
حالا اگه بخوام بگم مثلا ای آیتمی که مقدار شما 1 هستش مقدرا آیکن شما ستاره زرد هستش و آیتمی که مقدار fav 0 هستش مقدرا آیکن شما باشه ستاره مشکی
که دائمی باشه مگر اینکه مقدار دوباره برعکس بشه!!!
در حالت عادی ستاره عوض میشه ولی دستور sql کار نمیکنه اگه میشه ببینید مشکل کد من کجاست
btnfav.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
int id = adapter.getPosition(item);
G.database = SQLiteDatabase.openOrCreateDatabase(G.DIR_APP + "/dbkalam.sqlite", null);
G.database.execSQL("UPDATE tbl_kalam SET fav =1 WHERE rowid = " + id);
if (id == 0) {
btnfav.setImageResource(R.drawable.fav_off);
} else {
btnfav.setImageResource(R.drawable.fav_on);
}
}
});
adapter.notifyDataSetChanged();
}
}
در اینصورت باید یک آرایه از حالت های لایک هم بفرستید
به این صورت که مشخص باشه لایک هر آیتم صفر هست یا یک
بعد تمام اینا رو باید با شرط کنترل کنید دوست عزیز
بگید اگر لایکش صفر هست این عکس اگر یک هست این عکس
و وقتی روی دکمه کلیک میشه اگر لایکش صفر هست آپدیت کن یک بشه، اگر یک هست آپدیت کن صفر بشه
یک نمونه برنامه برای لایک توی تاپیک نمونه برنامه ها هست، میتونید از اون استفاده کنید
آقا یکی به من بگه من چه گلی به سرم بگیرم...
ببینید داستان از این قراره:
db = new DBAdapter(this);
db.open();
imp.setText(mokhatab.getImp());
String sid=mokhatab.getsenfid();
senfid.setText(db.execSQL("SELECT " + DBAdapter.SENF_NAME + " FROM " + DBAdapter.DATABASE_SENFTABLE + " WHERE " + DBAdapter.SENF_ROWID + " = " + sid ););
یه دیتابیس دارم به نام db همونطور که میبینید، قطعه کدimp.setText(mokhatab.getImp());خیلی قشنگ میاد این imp رو میگیره و میذاره توی ویوی من.
حالا قصد دارم به این بفهمونم که داداش من، وقتی میخوای senfid رو settext کنی، بیا برو ببین این senfid که ریختیش توی sid برابر چه ردیفی از نام جدول DATABASE_SENFTABLE هست، اون نام رو بجای عدد برای من settext کن.
نمیفهمه، منم نمیتونم بهش بفهمونم...
یکی راهنمایی کنه توروخدا
ممنون
آخرین ویرایش به وسیله m_jafari_1370 : جمعه 12 دی 1393 در 13:01 عصر
سلام
مشکل شما توی خوندن از جدول هست
کوئری شما درسته، اما نحوه خوندن درست نیست
شما باید با دستور db.rawQuery اطلاعات برگشتی رو بریزید توی Cursor و بعد از توی Cursor بخونید اطلاعات رو
به اولین پست همین تاپیک، قسمت خوندن اطلاعات مراجعه کنید
من توی دیتابیس یک فیلد آیدی دارم که بصورت اتوماتیک آیدی میده حالا اگه من بیام این دیتابیسو به لیست ویو اتصال بدم برای بدست آوردن مقدار id هر آیتم از چه دستوری استفاده کنم!!!!!!!!
کجای این کد باید همچین کاری انجام بدم؟؟!!!!!!!!!!
public class AdapterApplication extends ArrayAdapter<StructApplication> {
public AdapterApplication(ArrayList<StructApplication> array) {
super(G.context, R.layout.adapter_mohtava, array);
}
private static class ViewHolder {
public ViewGroup layoutRoot;
public TextView txtmohtava;
public ImageView imgShare;
public ImageButton btnfav;
int id;
public ViewHolder(View view) {
txtmohtava = (TextView) view.findViewById(R.id.txtmohtava);
layoutRoot = (ViewGroup) view.findViewById(R.id.layoutRoot);
imgShare = (ImageView) view.findViewById(R.id.imgShare);
btnfav = (ImageButton) view.findViewById(R.id.btnfav);
}
public void fill(final ArrayAdapter<StructApplication> adapter, final StructApplication item, final int position) {
txtmohtava.setText(item.mohtava);
btnfav.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// item.don = imageButton.isClickable();
int id = adapter.getPosition(item);
G.database = SQLiteDatabase.openOrCreateDatabase(G.DIR_APP + "/dbkalam.sqlite", null);
G.database.execSQL("UPDATE tbl_kalam SET fav =1 WHERE rowid = " + id);
Toast.makeText(G.context, "به علاقه مندی اضافه شد", Toast.LENGTH_SHORT).show();
adapter.notifyDataSetChanged();
/*
if (item.don) {
btnfav.setImageResource(R.drawable.fav_off);
} else {
btnfav.setImageResource(R.drawable.fav_on);
}*/
}
});
/*
if (item.don) {
btnfav.setImageResource(R.drawable.fav_off);
} else {
btnfav.setImageResource(R.drawable.fav_on);
}*/
//adapter.notifyDataSetChanged();
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
StructApplication item = getItem(position);
if (convertView == null) {
convertView = G.layoutInflater.inflate(R.layout.adapter_mohtava, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.fill(this, item, position);
return convertView;
}
}
دوست عزیز اینطوری من متوجه نمیشم شما چی نوشتید و نمیتونم راهنمایی تون کنم
شما به نظر میرسه از پایه با آداپتر و لیست ویو آشنایی کامل ندارید وگرنه منظور بنده رو متوجه میشدید
شما دارید یک لیست از StructApplication میفرستید، که mohtava رو نمایش میدید
اگر آیدی داره، از اون آیدی استفاده کنید، اگر نداره بهش اضافه کنید
شرمنده بیشتر از این فکر نکنم بتونم راهنمایی کنم
دوستان عزیز من یه تیکه کد دارم به این صورت:
public class MokhatabAdapter extends ArrayAdapter<Mokhatab> {
public MokhatabAdapter(Context c, List<Mokhatab> mokhatabha) {
super(c, android.R.id.content, mokhatabha);
this.c = c;
this.mokhatabha = mokhatabha;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater vi = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE );
View view = vi.inflate(R.layout.item, null);
Mokhatab mokhatab = mokhatabha.get(position);
TextView txt_imp = (TextView) view.findViewById(R.id.txt_imp);
txt_imp.setText(mokhatab.getImp());
TextView txt_tel = (TextView) view.findViewById(R.id.txt_tel);
txt_tel.setText(mokhatab.gettel());
TextView txt_email = (TextView) view.findViewById(R.id.txt_email);
txt_email.setText(mokhatab.getMail());
TextView txt_web = (TextView) view.findViewById(R.id.txt_web);
txt_web.setText(mokhatab.getWeb());
return view;
}
List<Mokhatab> mokhatabha;
Context c;
}
خیلی خوش و خرم کار میکنه! حالا مشکل اینجاست که وسط این کد، دقیقا قبل از
TextView txt_imp = (TextView) view.findViewById(R.id.txt_imp);
txt_imp.setText(mokhatab.getImp());
باید به دیتابیسم وصل شم و یه کوئری روش بزنم و نتیجمو بگیرم و چاپ کنم.
حال قابل عرض است که مثلا توی اکتیویتی های دیگم، به راحتی با این تیکه کد میتونم به دیتابیسم وصل شم:
DBAdapter db;
db = new DBAdapter(this);
db.open();
و کارامو روش کنم. ولی توی این کلاس که اکتیویتی نیست نمیتونم وصل شم و بهم ارور میده... (فکر کنم مشکل از همین this هست که منم هیچوقت نتونستم باهاش ارتباط برقرار کنم!!!)
البته این کد رو دراصل من از سایتی گرفتم و از نویسندش که پرسیدم خیلی مختصر این جواب رو بهم داده که بازم سواد من نمیکشه چی گفته!!! بنده خدا در جواب اینکه چجوری به دیتابیس وصل شم گفته که:
(((فرقی نداره مثل جاهای دیگه هست فقط برای context نمیشه مثل اکتیویتی باهاش رفتار کرد . باید مقدار context ی که داخل آداپتر میگیرید رو هنگام تعریف DbAdapter استفاده کنید
Dbadapter(contextname) که احتمال زیاد نامش c باشه )))
اگر بتونید مشکل منو حل کنید ممنون میشم، خصوصا آقا poorman که همیشه مزاحمش میشم...
اگرم به اطلاعات بیشتری نیاز هست تا عرض کنم خدمتتون...
سلام
توی همین کلاس آداپترتون با همین کدی که دارید یک متغیر عمومی به شکل زیر تعریف کنید:
Context c;
بعد هرجا که خواستین دیتابیس رو فراخوانی کنید به جای this بنویسید c
DBAdapter db;
db = new DBAdapter(c);
db.open();
حالا توضیح بیشتر اینکه، شما برای خوندن از دیتابیس نیاز دارید مشخص کنید از چه اکتیویتی این درخواست داره داده میشه.
اینکه توی چه اکتیویتی هستیم همون Context ماست که معمولا با this یا activityName.this مقداردهی میکنیم.
حالا توی آداپتر همونطور که گفتید چون کلاسی از جنس اکتیویتی نیست، نمیشه با this کار کرد
بنابراین نیاز هست که اکتیویتی رو به این کلاس بفرستیم
توی تابع اصلی آداپتر شما دو تا ورودی دارید، یکی Context c و یکی لیست مخاطبین
این c همون اکتیویتی ماست
حالا برای اینکه بتونیم ازش استفاده کنیم باید مقدارش به صورت عمومی ذخیره بشه
امیدوارم تونسته باشم خوب توضیح بدم
اینقدر پاسخت برام ارزش داشت که به لایک بسنده نکردم، ترجیح دادم پست برات بزنم داشpoorman
ممنون و سپاس
راستی یه راهی آموزشی چیزی واسه خوشکل کردن لیست ویو داری بهمون بدی؟
خواهش میکنم
برای قشنگ تر کردن لیست ویو راهی وجود نداره جز اینکه هر آیتم رو شخصی سازی کنید دیگه
همه چیز برمیگرده به دیزاین و طراحی برنامه![]()
سلام بزرگان
یکی این قطعه کد رو واسه من شرح بده!!! (فکرکنم مخاطبم Mr. poorman عزیز است!!!) و ترجیحا مشکلشو بگه!
String[] allsenfs;
Spinner spinner = (Spinner) findViewById(R.id.spinner1);
Cursor e = db.fetchAllsenfname();
int i=0;
if(e.moveToFirst()){
do{
allsenfs[i] = e.getString(i);
i++;
}
while(e.moveToNext());
}
e.close();
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,i, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.s imple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
این کد رو از گوگل گرفتم!!! البته مثال گوگل گفته بود که یه string-array به نام planets_array داخل strings.xml بسازید و اطلاعات موجود در اسپینر رو از توی اون بخونید. که بواسطه اون هم آرگومان دوم تابع createFromResource رو R.array.planets_array تعریف کرده بود.
خب حالا من اومدم که با تابع fetchAllsenfname که یه کوئری میزنه روی دیتابیس و تمام اطلاعات رو با Cursor میاره تبدیل کنم به یک string-array و این اطلاعات رو توی اسپینر نمایش بدم. ولی بهم اررور میده، لطفا اگر وقت دارید و میتونید راهنماییم کنید...
(خدا بخیر کنه بقیه ماجرا رو که بخوام روش سرچ هم بذارم!!!)
سلام
ارور شما مربوط به این خط داخل حلقه هست
allsenfs[i] = e.getString(i);
شما دارید خونه i ام از cursor رو میخونید در حالی که i هر سری داره یکی اضافه میشه
بنابراین وقتی اندازه i از تعداد ستون های cursor بیشتر بشه خطا میگیرید
باید ستون مشخص خودتون رو بخونید، مثلا ستون 0 ( کاملا بستگی داره به اینکه توی cursor چه چیزی هست )
آقا poorman ، شما توی این قطعه کد مشکلی میبینی؟
public Cursor fetchsenfid(String sname) {
Log.i("mylog", "raftim too fetchsenfid va sname is = "+sname);
return db.rawQuery("SELECT " + SENF_ROWID + " FROM " + DATABASE_SENFTABLE + " WHERE " + SENF_NAME + " = " + sname ,null);
//return db.query(DATABASE_SENFTABLE, new String[] {SENF_ROWID} , SENF_NAME + " = " + sname , null, null, null,null);
}
هر کدوم از دوتا return ها رو میزنم SQLiteDatabaseCpp بهم ارور میده که:
sqlite returned: error code = 1, msg = no such column: s1, db=/data/data/ir.esfandune.Databases/databases/MyDB
البته اینم توضیح بدم که sname توی این انتخاب مقدار s1 میگیره که توی دیتابیس هم هستش!!!، همچنین DATABASE_SENFTABLE اینگونه است:
// DATABASE_SENFTABLE Columns
static final String SENF_ROWID = "senf_id";
static final String SENF_NAME = "senfname";
static final String CREATE_SENFTABLE = "create table " + DATABASE_SENFTABLE +"("+ SENF_ROWID + " integer primary key autoincrement, " + SENF_NAME + " text not null);";
یکی نیست بگه بچه خجالت بکش از بس از این Mr. poorman میپرسی!!!
تنها مشکلی که اینجا به چشمم میخوره اینه که چیزی که شما دارید براش جستجو میکنید رو به صورت رشته وارد نکردید و بدون کوتیشن قرار دادید
کوئری زیر در صورتی که جدول شما ساخته شده باشه نباید خطایی بده
return db.rawQuery("SELECT " + SENF_ROWID + " FROM " + DATABASE_SENFTABLE + " WHERE " + SENF_NAME + " = '" + sname + "'" ,null);