Reputation: 59
I have editText1, editText2 and EditText3. Users need to write personal informations this areas. When they put save button, editText1, editText2 and EditText3 must save. They should find what they write when ever they want. But when i try to save 3 of them (editText1, editText2 and EditText3), this is not happens. I can save just editText1. Or i can save 3 spaces areas just in editText1. For example, i wrote in editText1 "hello", in editText2 "listen", in editText3 " guys", i am saving this and when i open in saved area i can see 3 times "listen". Others dont save. Can you help me? What should i change?
MainActivity:
public class MainActivity extends AppCompatActivity {
static ArrayList<Bitmap> newImage;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.add_new, menu);
return super.onCreateOptionsMenu(menu);
}
@Override //Menüyü seçersek ne olacak onu belirler.
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.add_new) {
Intent intent = new Intent(getApplicationContext(), Main2Activity.class);
intent.putExtra("info", "new"); //Bu satırda amaç eğer yeni bir resimmi yoksa eski resimmi görentülenmek isteniyor onu anlamak
startActivity(intent);
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listView);
//Databaseden çektiğimiz dataları kaydedeceğimiz bir arraylist oluşturalım ve listview ile bağlayalım
final ArrayList<String> newName = new ArrayList<String>();
final ArrayList<String> newName2 = new ArrayList<String>();
final ArrayList<String> newName3 = new ArrayList<String>();
newImage = new ArrayList<Bitmap>();
ArrayAdapter arrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,newName);
listView.setAdapter(arrayAdapter);
//uygulama ilk açıldığında database'de kayıtlı bir şey varmı bakmasını istiyoruz aşağıdaki aşamalarda
try {
Main2Activity.database = this.openOrCreateDatabase("Yeni", MODE_PRIVATE, null);
Main2Activity.database.execSQL("CREATE TABLE IF NOT EXISTS yeni (name VARCHAR, name2 VARCHAR, name3 VARCHAR, image BLOB)");
Cursor cursor = Main2Activity.database.rawQuery("SELECT * FROM yeni", null); //Data çekmek için cursoru kullanıyoruz
int nameIx = cursor.getColumnIndex("name");
int name2Ix = cursor.getColumnIndex("name2");
int name3Ix = cursor.getColumnIndex("name3");
int imageIx = cursor.getColumnIndex("image");
cursor.moveToFirst();
while (cursor != null) {
newName.add(cursor.getString(nameIx)); //Kullanıcının girdği ismi newName'in içine ekle
newName2.add(cursor.getString(name2Ix));
newName3.add(cursor.getString(name3Ix));
byte[] byteArray = cursor.getBlob((imageIx));
Bitmap image = BitmapFactory.decodeByteArray(byteArray,0,byteArray.length);
newImage.add(image); //newImage'in içine ekle diyoruz
cursor.moveToNext();
arrayAdapter.notifyDataSetChanged();//Eğer bir datayı değiştirdiysek hemen güncelleyen bir konut
}
} catch (Exception e) {
}
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent (getApplicationContext(), Main2Activity.class);
intent.putExtra("info", "old");
intent.putExtra("name", newName.get(position));
intent.putExtra("name2", newName2.get(position));
intent.putExtra("name3", newName3.get(position));
intent.putExtra("position", position);
startActivity(intent);
}
});
}
}
Main2Activity
public class Main2Activity extends AppCompatActivity {
ImageView imageView; //imageView'i heryerde tanımladık
EditText editText;
EditText editText2;
EditText editText3;
static SQLiteDatabase database; //Buraya yazdığımız database'e MainActivity'den de ulaşabileceğiz çünkü statik yazdık
Bitmap selectedImage; //seçilen resmi kaydetmek için burada bunu tanımladık
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
imageView = (ImageView) findViewById(R.id.imageView); //layouttaki imageView'i tanımladık
editText = (EditText) findViewById(R.id.editText);
editText2 = (EditText) findViewById(R.id.editText2);
editText3 = (EditText) findViewById(R.id.editText3);
Button button = (Button) findViewById(R.id.button); //Buton tanımladık
Intent intent = getIntent();
String info = intent.getStringExtra("info"); //MainActivity'deki 28. satırla bağlantılı
if (info.equalsIgnoreCase("new")) {
Bitmap background = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.dede); //Kullanıcı resim seçerkenki aşama
imageView.setImageBitmap(background);
button.setVisibility(View.VISIBLE); //Eğer yeni eklenecekse görünür yap
editText.setText(""); //Bu satır eğer daha önceden bir şey yazdıysak onun orada kalmamasını bize boş yazma yeri açmasını sağlıyor
editText2.setText("");
editText3.setText("");
} else {
String name = intent.getStringExtra("name");
editText.setText(name);
String name2 = intent.getStringExtra("name2");
editText2.setText(name2);
String name3 = intent.getStringExtra("name3");
editText3.setText(name3);
int position = intent.getIntExtra("position", 0);
imageView.setImageBitmap(MainActivity.newImage.get(position));
button.setVisibility(View.INVISIBLE); //Eskiyse gösterme
}
}
//Resim koyma yerine tıklandığında olacaklar
public void select (View view) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, 2);
} else {
Intent intent = new Intent (Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); //Kullanıcının medyasına eriş diyoruz
startActivityForResult(intent,1);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 2) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent (Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); //Kullanıcının medyasına eriş diyoruz
startActivityForResult(intent,1);
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
//Yukarıdaki medyaya erişime izin verildiyse resim seçme yeri
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && resultCode == RESULT_OK && data!= null) {
Uri image = data.getData();
//try ve catch ın içine aldık bu olayı çünkü bi sorun çıkarsa burda uygulama hata vermesin.
try {
selectedImage = MediaStore.Images.Media.getBitmap(this.getContentResolver(), image);
imageView.setImageBitmap(selectedImage); //imageView'e burda ulaşmak için koyduk
} catch (IOException e) {
e.printStackTrace();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
// Kaydetme butonuna tıklandığında olacaklar
public void save (View view) {
String newName = editText.getText().toString(); //Kullanıcının kardettiği isme bu şekilde ulaştık
String newName2 = editText2.getText().toString();
String newName3 = editText3.getText().toString();
//image'ler bytearray şeklinde kaydedilir!!!!!!!!!!
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); //selectedImage'i compress etmeliyiz kaydetme aşamalarından biri
selectedImage.compress(Bitmap.CompressFormat.PNG,50,outputStream); //bu şekilde ziplemiş olduk resmi
byte[] byteArray = outputStream.toByteArray(); //Bu outpuSteam'i al array'e çevir dedik! ve resmimiz kaydedilebilir oldu
try { //Tüm bu alttaki aşamalarda kullanıcının girdiği isim ve resmi database'imize işlemiş olduk!
database = this.openOrCreateDatabase("Yeni", MODE_PRIVATE, null);
database.execSQL("CREATE TABLE IF NOT EXISTS yeni (name VARCHAR, image BLOB)");
String sqlString = "INSERT INTO yeni (name, image) VALUES (?, ?, ?, ?)";
SQLiteStatement statement =database.compileStatement(sqlString);
statement.bindString(1,newName);
statement.bindString(3,newName2);
statement.bindString(4,newName3);
statement.bindBlob(2,byteArray);
statement.execute();
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent(getApplicationContext(), MainActivity.class); //kaydet'e bastığında anasayfaya yönlendirilsin
startActivity(intent);
}
}
Upvotes: 0
Views: 95
Reputation: 56953
Issues 1 is that you try defining the same table but with 4 columns (in the onCreate
method of MainActivity
) and then with 2 columns (in the save
method of Main2Activity
), the 2nd will not create the table as it will already have been created, so it appears that the 4 column version will exist (if it doesn't and the table gets create then you would end up with issues whenever you return to MainActivity
as two columns (name2
and name3
) will not exist and result in a column not found when int name2Ix = cursor.getColumnIndex("name2");
is attempted.
A 2nd issue is that you are trying to insert 2 values but with 4 values given as arguments i.e. INSERT INTO yeni (name,image) ....
2 values VALUES(?, ?, ? ,?)
4 arguments.
A 3rd issue is that you are not detecting the success or failure of the insert, rather just assuming that it will work (when it doesn't). Using try/catch around SQLiteDatabase methods is also not a good idea as very often they will handle many situations and only crash when something dire is wrong (and you'd want a crash).
A 4th issue is that you can click the Save button (assuming you have used android:onClick="save"
in the layout) that selectedImage
may well be null.
A 5th issue is that when done with Main2Activity
you try to start MainActivity
, which will start another activity, rather you you return to it by finishing Main2Activity
. Currently, this works to your advantage in that the ListView the lists the newly inserted row. However, you end up with lots of activities and hitting the back button will progressively return through the stack of activities and will be very confusing.
Fixing the 5th issue, i.e. finishing Main2Activty
introduces a 6th issue and that is that the List isn't refreshed, it remains as it was before a new row is inserted.
Fixing the 6th issue requires a number of code changes but ultimately you refresh the List by overriding the onResume
method by rebuilding the source of the List (clearing the ArrayList and then adding all the elements to it).
Ignoring the 1st issue, which won't cause an issue as it very much appears that the table having 4 columns is created first (certainly was in testing). And also initially ignoring the 2nd and 3rd issue. But using :-
if (info.equalsIgnoreCase("new")) { // UNCHANGED
Bitmap background = BitmapFactory.decodeResource(
getApplicationContext().getResources(),
android.R.drawable.ic_dialog_alert //<<<< Use a stock Android image for testing
); //Kullanıcı resim seçerkenki aşama
selectedImage = background; //<<<< ADDED to overcome null pointer exception
imageView.setImageBitmap(background); //<<<< UNCHANGED
//........ rest of the code
in Main2Activity
's onCreate
method and inputtin Test, Test and Test in the 3 EditText's and then Clicking on the button results in a return to MainActivity but with nothing displayed. However, the log shows the anticipated E/SQLiteLog: (1) 4 values for 2 columns
:-
06-03 22:13:09.895 2647-2647/yeni.yeni E/SQLiteLog: (1) 4 values for 2 columns
06-03 22:13:09.895 2647-2647/yeni.yeni W/System.err: android.database.sqlite.SQLiteException: 4 values for 2 columns (code 1): , while compiling: INSERT INTO yeni (name, image) VALUES (?, ?, ?, ?)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:887)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:498)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:994)
at yeni.yeni.Main2Activity.save(Main2Activity.java:145)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:384)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
A suggested fix for the main issue, the insert not inserting a record, could be the following, which utilises the SQLiteDatabase insert convenience method :-
public void save (View view) {
String newName = editText.getText().toString(); //Kullanıcının kardettiği isme bu şekilde ulaştık
String newName2 = editText2.getText().toString();
String newName3 = editText3.getText().toString();
//image'ler bytearray şeklinde kaydedilir!!!!!!!!!!
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); //selectedImage'i compress etmeliyiz kaydetme aşamalarından biri
selectedImage.compress(Bitmap.CompressFormat.PNG,50,outputStream); //bu şekilde ziplemiş olduk resmi
byte[] byteArray = outputStream.toByteArray(); //Bu outpuSteam'i al array'e çevir dedik! ve resmimiz kaydedilebilir oldu
ContentValues cv = new ContentValues();
cv.put("name",newName);
cv.put("name2",newName2);
cv.put("name3",newName3);
cv.put("image",byteArray);
long new_row_id = database.insert("yeni",null,cv);
//<<<< ADDED TO ISSUE TOAST WITH THE RESULT
if (new_row_id > 0) {
Toast.makeText(this,"Row Insereted.",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this,"Row NOT Inserted",Toast.LENGTH_SHORT).show();
}
/*
try { //Tüm bu alttaki aşamalarda kullanıcının girdiği isim ve resmi database'imize işlemiş olduk!
Log.d("SAVE","Attempting OPEN Or CREATE DATABASE");
database = this.openOrCreateDatabase("Yeni", MODE_PRIVATE, null);
Log.d("SAVE","Attempting CREATE OF TABLE yeni");
database.execSQL("CREATE TABLE IF NOT EXISTS yeni (name VARCHAR, image BLOB)");
String sqlString = "INSERT INTO yeni (name, image) VALUES (?, ?, ?, ?)";
SQLiteStatement statement =database.compileStatement(sqlString);
statement.bindString(1,newName);
statement.bindString(3,newName2);
statement.bindString(4,newName3);
statement.bindBlob(2,byteArray);
Log.d("SAVE","Attempting EXECUTION of the SQL INSERT using :- " + statement.toString());
statement.execute();
} catch (Exception e) {
e.printStackTrace();
}
*/
Intent intent = new Intent(getApplicationContext(), MainActivity.class); //kaydet'e bastığında anasayfaya yönlendirilsin
startActivity(intent);
//this.finish(); //<<<< Should not start a parent activity you should return to it by finishing the child activity
}
This requires quite a few code changes but basically involves allowing the List to be refreshed, by the onResume
method in the MainActivity
public class MainActivity extends AppCompatActivity {
static ArrayList<Bitmap> newImage;
ArrayList<String> nameList;
ArrayList<String> name2List;
ArrayList<String> name3List;
ArrayAdapter<String> arrayadpater;
ListView listView;
Button addbutton; //<<<< Instead of menu for my convenience
//<<<<<<<<<< Code Commented out for convenience of using button >>>>>>>>>
/*
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.add_new, menu);
return super.onCreateOptionsMenu(menu);
}
@Override //Menüyü seçersek ne olacak onu belirler.
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.add_new) {
Intent intent = new Intent(getApplicationContext(), Main2Activity.class);
intent.putExtra("info", "new"); //Bu satırda amaç eğer yeni bir resimmi yoksa eski resimmi görentülenmek isteniyor onu anlamak
startActivity(intent);
}
return super.onOptionsItemSelected(item);
}
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listview); //<<<< CHANGED as declared as class variable
//<<<<<<<<<< Code below for the conveince of using a button instead of Menu >>>>>>>>>>
addbutton = (Button) findViewById(R.id.addnew);
addbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), Main2Activity.class);
intent.putExtra("info", "new"); //Bu satırda amaç eğer yeni bir resimmi yoksa eski resimmi görentülenmek isteniyor onu anlamak
startActivity(intent);
}
});
//<<<<<<<<<< End of code for Button handling >>>>>>>>>>
setupListView();
//<<<<<<<<<< NOTE commented out Code >>>>>>>>>>
/*
//Databaseden çektiğimiz dataları kaydedeceğimiz bir arraylist oluşturalım ve listview ile bağlayalım
final ArrayList<String> newName = new ArrayList<String>();
final ArrayList<String> newName2 = new ArrayList<String>();
final ArrayList<String> newName3 = new ArrayList<String>();
newImage = new ArrayList<Bitmap>();
ArrayAdapter arrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,newName);
listView.setAdapter(arrayAdapter);
//uygulama ilk açıldığında database'de kayıtlı bir şey varmı bakmasını istiyoruz aşağıdaki aşamalarda
try {
Main2Activity.database = this.openOrCreateDatabase("Yeni", MODE_PRIVATE, null);
Main2Activity.database.execSQL("CREATE TABLE IF NOT EXISTS yeni (name VARCHAR, name2 VARCHAR, name3 VARCHAR, image BLOB)");
Cursor cursor = Main2Activity.database.rawQuery("SELECT * FROM yeni", null); //Data çekmek için cursoru kullanıyoruz
int nameIx = cursor.getColumnIndex("name");
int name2Ix = cursor.getColumnIndex("name2");
int name3Ix = cursor.getColumnIndex("name3");
int imageIx = cursor.getColumnIndex("image");
cursor.moveToFirst();
while (cursor != null) {
newName.add(cursor.getString(nameIx)); //Kullanıcının girdği ismi newName'in içine ekle
newName2.add(cursor.getString(name2Ix));
newName3.add(cursor.getString(name3Ix));
byte[] byteArray = cursor.getBlob((imageIx));
Bitmap image = BitmapFactory.decodeByteArray(byteArray,0,byteArray.length);
newImage.add(image); //newImage'in içine ekle diyoruz
cursor.moveToNext();
arrayAdapter.notifyDataSetChanged();//Eğer bir datayı değiştirdiysek hemen güncelleyen bir konut
}
} catch (Exception e) {
}
*/
}
//<<<< ADDED to handle return from child >>>>
@Override
public void onResume() {
super.onResume();
setupListView();
}
//<<<< ADDED to utilise a single refreshable ListView
private void setupListView() {
getListsFromDatabase();
if (arrayadpater == null) {
arrayadpater = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,nameList);
listView.setAdapter(arrayadpater);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent (getApplicationContext(), Main2Activity.class);
intent.putExtra("info", "old");
intent.putExtra("name", nameList.get(position));
intent.putExtra("name2", name2List.get(position));
intent.putExtra("name3", name3List.get(position));
intent.putExtra("position", position);
startActivity(intent);
}
});
} else {
arrayadpater.notifyDataSetChanged();
}
}
//<<<< Added to build/rebuild the Arraylist's used by the ListView
private void getListsFromDatabase() {
// Get the database (and set the databse for Main2Acticity)
SQLiteDatabase db = openOrCreateDatabase(
"Yeni",
MODE_PRIVATE,
null
);
db.execSQL("CREATE TABLE IF NOT EXISTS yeni (name VARCHAR, name2 VARCHAR, name3 VARCHAR, image BLOB)");
Main2Activity.database = db;
// Initialise or clear the array lists
if (nameList == null) {
nameList = new ArrayList<>();
} else {
nameList.clear();
}
if (name2List == null) {
name2List = new ArrayList<>();
} else {
name2List.clear();
}
if (name3List == null) {
name3List = new ArrayList<>();
} else {
name3List.clear();
}
if (newImage == null) {
newImage = new ArrayList<>();
} else {
newImage.clear();
}
// get the
Cursor cursor = db.query("yeni",
null,
null,
null,
null,
null,
null
);
while (cursor.moveToNext()) {
nameList.add(cursor.getString(cursor.getColumnIndex("name")));
name2List.add(cursor.getString(cursor.getColumnIndex("name2")));
name3List.add(cursor.getString(cursor.getColumnIndex("name3")));
byte[] b = cursor.getBlob(cursor.getColumnIndex("image"));
Bitmap bmp = BitmapFactory.decodeByteArray(b,0,b.length);
newImage.add(bmp);
}
cursor.close();
}
}
In Main2Activity
remove the 2 lines :-
Intent intent = new Intent(getApplicationContext(), MainActivity.class); //kaydet'e bastığında anasayfaya yönlendirilsin
startActivity(intent);
and then add the line :-
this.finish(); //<<<< ADD this to finish Main2Activity and return to MainActivity
When first started :-
Click Add (equivalent to select Add from Menu) :-
Just before clicking Save (Hit Me) button :-
After clicking Save (Hit Me) button (i.e. return to MainActivity)
Clicking on item in the list (to update)
Upvotes: 1
Reputation: 323
Check your logcat! Maybe This statement has issue!
String sqlString = "INSERT INTO yeni (name, image) VALUES (?, ?, ?, ?)"
You selected two columns but you put 4 values to insert.
Upvotes: 0