Delete a row from SQLite DataBase doesn't work - android

I'm showing data from a database in a list view and I want to delete one entry when the user do a longclick in one row and then selects "yes" in a Dialog. I have all the code and it compiles but it isn't deleting anything. Any suggestion? Thanks
That's the code of the listview:
public class Consult extends FragmentActivity {
private ListView list;
private SQLiteDatabase db;
private int id = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.consult);
list = (ListView)findViewById(R.id.list);
this.getIntent();
ApeironsSQLiteHelper apeironsdb = new ApeironsSQLiteHelper(this, "DBApeirons.DB", null, 1);
db = apeironsdb.getWritableDatabase();
String[] campos = new String[]{"_id", "name", "kind_place", "score"};
Cursor c = db.query("Apeirons", campos, null, null, null, null, null);
c.moveToFirst();
String[] from = new String[]{"name", "kind_place", "score"};
int [] to = new int[] {R.id.Titulo, R.id.SubTitulo};
//#SuppressWarnings("deprecation")
MyListAdapter myadapter = new MyListAdapter (this,
R.layout.entrys, c, from, to);
list.setAdapter(myadapter);
list.setLongClickable(true);
list.setOnItemLongClickListener(new OnItemLongClickListener(){
public boolean onItemLongClick(AdapterView<?> arg0, View v,
int index, long arg3) {
saveID(index);
//db.delete("Apeirons", "_id=" + String.valueOf(index), null);
Log.d("ONCLICK", String.valueOf(index));
Log.d("ONCLICK", String.valueOf(id));
callDialog();
return false;
}
});
}
public void callDialog(){
Log.d("DIALOG", String.valueOf(id));
FragmentManager fragmentmanager = getSupportFragmentManager();
SimpleDialog dialog = new SimpleDialog();
dialog.saveIndex(id);
//SimpleDialog.newInstance(id);
dialog.show(fragmentmanager, "tag");
Log.d("erase", "salgo del callDialog");
}
public void saveID(int ID){
id = ID;
}
And that's the code of the Dialog:
public class SimpleDialog extends DialogFragment {
private SQLiteDatabase dbs;
int ID;
#Override
public Dialog onCreateDialog (Bundle savedInstanceState){
//ID = getArguments().getInt("id");
ApeironsSQLiteHelper apeironsdbs = new ApeironsSQLiteHelper(getActivity(),
"DBApeirons.DB", null, 1);
dbs = apeironsdbs.getWritableDatabase();
AlertDialog.Builder builder =
new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.EraseDialogMessage);
builder.setTitle(R.string.app_name);
builder.setPositiveButton(R.string.EraseDialogPButton, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String args = String.valueOf(ID);
Log.d("Yes BUTTON", args);
/*String sql = "DELETE FROM Apeirons WHERE _id=" + args;
dbs.execSQL(sql);*/
//int prueba = dbs.delete("Apeirons", " _id = ?" + args, null);
int prueba = dbs.delete("Apeirons", "_id = ?", new String[] { "" + args });
Log.d("RETORNO DELETE", String.valueOf(prueba));
}
});
builder.setNegativeButton(R.string.EraseDialogNButton, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
return builder.create();
}
public void saveIndex(int index){
ID = index;
}
}
I fixed!!! The problem was that I was using the id of the listview and it isn't the same in the database. Now I recover first the _id of the database and works perfect. Thank you for all the answers. The code to recover the _id of database below (maybe is useful to someone):
list.setLongClickable(true);
list.setOnItemLongClickListener(new OnItemLongClickListener(){
public boolean onItemLongClick(AdapterView<?> arg0, View v,
int index, long arg3) {
c.moveToPosition(index);
int id = c.getInt(c.getColumnIndex("_id"));
saveID(id);
Log.d("ONCLICK", String.valueOf(index));
Log.d("ONCLICK", String.valueOf(id));
callDialog();
return false;
}
});

You can try
private SQLiteDatabase dbs;
String args = String.valueOf(ID);
Delete query:
Method 1:
dbs = apeironsdbs.getWritableDatabase();
String deleteQuery = "DELETE FROM Apeirons where _id='"+ args +"'";
dbs .execSQL(deleteQuery);
Or you can use
Method 2:
ApeironsSQLiteHelper apeironsdb = new ApeironsSQLiteHelper(this, "DBApeirons.DB", null, 1);
apeironsdb .delete(Apeirons, _id+"="+ID, null); // ID is int value

Try change this line:
int prueba = dbs.delete("Apeirons", " _id = ?" + args, null);
into
int prueba = dbs.delete("Apeirons", " _id = \"" + args + "\"", null);

Related

How to update ListView in Activity after updating database in other Activity?

public class SettingsActivity extends AppCompatActivity {
private Context context;
private DogDatabaseHelper dbHelper;
private ListView mListView;
private ArrayList<String> names = new ArrayList<String>();
private AdapterForNames namesAdapter;
#Override
public void onCreate(Bundle savedInstance){
super.onCreate(savedInstance);
setContentView(R.layout.settings);
mListView = (ListView)findViewById(R.id.listforall);
context = this;
namesAdapter = new AdapterForNames(this,names);
mListView.setAdapter(namesAdapter);
DogDatabaseHelper dbHelper = new DogDatabaseHelper(getApplicationContext());
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.rawQuery("select name from dog",null);
if(cursor != null && cursor.moveToFirst()){
do{
names.add(cursor.getString(cursor.getColumnIndex("name")));
namesAdapter.notifyDataSetChanged();
}while (cursor.moveToNext());
}
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Intent intent = new Intent(SettingsActivity.this,SetupActivity.class);
intent.putExtra("name",names.get(position));
startActivity(intent);
}
});
}
public class AdapterForNames extends ArrayAdapter<String> {
private ArrayList<String> names;
AdapterForNames(Context context, ArrayList<String> names){
super(context,R.layout.settingsname,names);
this.names = names;
}
public void refresh(ArrayList<String> names){
this.names= names;
notifyDataSetChanged();
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater setLayout = LayoutInflater.from(getContext());
View customView = setLayout.inflate(R.layout.settingsname,parent,false);
String setItem = names.get(position);
TextView nameText = (TextView)customView.findViewById(R.id.settingsname);
nameText.setText(setItem);
return customView;
}
}
public class SetupActivity extends AppCompatActivity {
private Context context;
static String extra = "values";
ListView mListView;
private String name;
final String[] setItems = {"name","birthday","size","sex"};
#Override
public void onCreate(Bundle savedInstance){
super.onCreate(savedInstance);
setContentView(R.layout.setuplist);
mListView = (ListView)findViewById(R.id.listview);
context = this;
Intent intent =getIntent();
name = intent.getStringExtra("name");
setResult(RESULT_OK,intent);
showView();
}
private void showView(){
DogDatabaseHelper dbHelper= new DogDatabaseHelper(getApplicationContext());
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.rawQuery("select * from dog where name = ?",new String[]{name});
//Cursor cursor = db.query("Dog",null,null,null,null,null,null,null);
if(cursor.moveToFirst()){
String name = cursor.getString(cursor.getColumnIndex("name"));
String birthday = cursor.getString(cursor.getColumnIndex("birthday"));
String size = cursor.getString(cursor.getColumnIndex("size"));
String sex = cursor.getString(cursor.getColumnIndex("sex"));
final String[] setValues = {name,birthday,size,sex};
ListAdapter listAdapter = new CustomAdapter(this,setItems,setValues);
mListView.setAdapter(listAdapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String setupItemValue = setValues[position];
String setupItem = setItems[position];
Intent intent;
if(setupItem.equals("name")){
intent = new Intent(SetupActivity.this,ChangeName.class);
intent.putExtra(extra,setupItemValue);
startActivityForResult(intent,1);
} else if(setupItem.equals("birthday")){
intent = new Intent(SetupActivity.this,ChangeBirthday.class);
intent.putExtra(extra,setupItemValue);
startActivityForResult(intent,2);
}else if(setupItem.equals("size")){
intent = new Intent(SetupActivity.this,ChangeType.class);
intent.putExtra(extra,setupItemValue);
startActivityForResult(intent,3);
}else{
intent = new Intent(SetupActivity.this,ChangeSex.class);
intent.putExtra(extra,setupItemValue);
startActivityForResult(intent,4);
}
}
});
}
cursor.close();
}
private void updateView(){
DogDatabaseHelper dbHelper= new DogDatabaseHelper(getApplicationContext());
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.query("Dog",null,null,null,null,null,null,null);
if(cursor.moveToFirst()){
String name = cursor.getString(cursor.getColumnIndex("name"));
String birthday = cursor.getString(cursor.getColumnIndex("birthday"));
String size = cursor.getString(cursor.getColumnIndex("size"));
String sex = cursor.getString(cursor.getColumnIndex("sex"));
final String[] setValues = {name,birthday,size,sex};
ListAdapter listAdapter = new CustomAdapter(this,setItems,setValues);
mListView.setAdapter(listAdapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String setupItemValue = setValues[position];
String setupItem = setItems[position];
Intent intent;
if(setupItem.equals("name")){
intent = new Intent(SetupActivity.this,ChangeName.class);
intent.putExtra(extra,setupItemValue);
startActivityForResult(intent,1);
} else if(setupItem.equals("birthday")){
intent = new Intent(SetupActivity.this,ChangeBirthday.class);
intent.putExtra(extra,setupItemValue);
startActivityForResult(intent,2);
}else if(setupItem.equals("size")){
intent = new Intent(SetupActivity.this,ChangeType.class);
intent.putExtra(extra,setupItemValue);
startActivityForResult(intent,3);
}else{
intent = new Intent(SetupActivity.this,ChangeSex.class);
intent.putExtra(extra,setupItemValue);
startActivityForResult(intent,4);
}
}
});
}
cursor.close();
}
#Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
DogDatabaseHelper dbHelper= new DogDatabaseHelper(getApplicationContext());
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.query("Dog",null,null,null,null,null,null,null);
switch (requestCode){
case 1:
if (resultCode == RESULT_OK){
ContentValues cv = new ContentValues();
cv.put("name",data.getStringExtra("return_name"));
db.update("dog",cv,"id=?",new String[]{"1"});
}
break;
case 2:
if(resultCode == RESULT_OK){
ContentValues cv = new ContentValues();
cv.put("birthday",data.getStringExtra("return_birthday"));
db.update("dog",cv,"id=?",new String[]{"1"});
}
break;
case 3:
if(resultCode == RESULT_OK){
ContentValues cv = new ContentValues();
cv.put("size",data.getStringExtra("return_type"));
db.update("dog",cv,"id=?",new String[]{"1"});
}
break;
case 4:
if(resultCode == RESULT_OK){
ContentValues cv = new ContentValues();
cv.put("sex",data.getStringExtra("return_sex"));
db.update("dog",cv,"id=?",new String[]{"1"});
}
break;
}
db.close();
updateView();
}
}
public class DogDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_DOG = "create table dog ("
+ "id integer primary key autoincrement,"
+ "name text,"
+ "birthday text,"
+ "size text,"
+ "sex text,"
+ "count integer)";
private Context context;
public DogDatabaseHelper(Context context){
super(context,"Dog.db",null,1);
this.context = context;
}
#Override
public void onCreate(SQLiteDatabase db){
db.execSQL(CREATE_DOG);
}
#Override
public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion){
db.execSQL("drop table if exists Dog");
onCreate(db);
}
public ArrayList<String> getAllNames(){
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<String> names = new ArrayList<String>();
Cursor cursor = db.query("Dog",null,null,null,null,null,null);
if(cursor.moveToFirst()){
do{
String name = cursor.getString(cursor.getColumnIndex("name"));
names.add(name);
}while (cursor.moveToNext());
}
cursor.close();
return names;
}
}
I can get data from database and I'm able to update data after clicking the name in the ListView, but when I return to this Activity, I don't know how to update the ListView, cause notifyDataSetChanged() didn't work.
Have no idea what went wrong, Anyone can help?
Use startActivityForResult() instead of startActivity() to start your SetupActivity:
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Intent intent = new Intent(SettingsActivity.this, SetupActivity.class);
intent.putExtra("name", names.get(position));
startActivityForResult(intent, REQUEST_SETUP);
// REQUEST_SETUP is just a private int constant in SettingsActivity
}
Override onActivityResult() in SettingsActivity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK) {
switch (requestCode) {
case REQUEST_SETUP:
dataChanged();
break;
// other request codes (if any)
}
}
}
The dataChanged() method:
private void dataChanged() {
// fetch the new data from the DB into your ArrayList
names.clear();
names.addAll(dbHelper.getAllNames());
// update the ListView with the new data
namesAdapter.notifyDataSetChanged();
}
The getAllNames() method in DogDatabaseHelper:
public ArrayList<String> getAllNames() {
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<String> names = new ArrayList<>();
Cursor cursor = db.query(TABLE_DOG, new String[]{COLUMN_NAME},
null, null, null, null, null, null);
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(cursor.getColumnIndex(COLUMN_NAME)));
names.add(name);
} while (cursor.moveToNext());
}
cursor.close();
return names;
}
And finally, when you finished your stuff in SetupActivity and inserted/updated the data in the DB, set the result to RESULT_OK and return to SettingsActivity by calling finish():
setResult(RESULT_OK);
finish();
NOTE: for better performance, you could pass the ID(s) of the inserted/updated record(s) from SetupActivity to SettingsActivity in the Intent, so instead of querying all rows by calling getAllNames(), you could just fetch the modified record(s).
I think the easiest and quicker way for you would be to put all this code:
DogDatabaseHelper dbHelper = new DogDatabaseHelper(getApplicationContext());
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.rawQuery("select name from dog",null);
// Edit: to reload all data you must first clear the list
names.clear();
if (cursor != null && cursor.moveToFirst()) {
do {
names.add(cursor.getString(cursor.getColumnIndex("name")));
} while (cursor.moveToNext());
// Note: move this out of the bucle to avoid calling it in every iteration
namesAdapter.notifyDataSetChanged();
}
in your MainActivity's onResume() method, so every time you come back you refresh the data.
EDIT: since reloading the data each time the activity calls onResume, I would suggest you also use a flag for the MainActivity to know if there have been changes. Something like:
#Override
protected void onResume() {
super.onResume();
if (thereWereChanges) {
realoadDataSet();
}
}

How to delete a row in SQLiteDatabase - Android Content Provider

I’m struggling to write a method that deletes a row from the SQLiteDatabase. I have a list of songs in a gridview where when a user clicks one of the items from the list the app will take them to my SongDetailFragment activity which contains more information about the song and a star button where if a song in in the database the star button is “switched on”, conversely if the item is NOT in the database the star button is “switched-off”
When a user click the star button I'm able to add a song successfully in the database and my star button is “switched-on”. Now I want to press the same button again and call deleteFromDB() to delete the song that was added to the database. So I have the following code in my onClick:
public void onClick(View v)
{
if (mIsFavourite) {
deleteFromDB();
}
else {
insertData();
mIsFavourite = true;
}
The problem is deleteFromDB() method is not working correctly as I can see that the song is not deleting from the database. I’m not sure what is the correct syntax to fix it.
Here is my method:
private void deleteFromDB() {
ContentValues songValues = new ContentValues();
getActivity().getContentResolver().delete(SongContract.SongEntry.CONTENT_URI,
SongContract.SongEntry.COLUMN_TITLE + " = ?",
new String[]{songValues.getAsString(song.getTitle())});
//switch off button
imgViewFavButton.setImageResource(android.R.drawable.btn_star_big_off);
}
Here is my delete method snippet from my ContentProvider class:
#Override
public int delete(Uri uri, String selection, String[] selectionArgs){
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
int numDeleted;
switch(match){
case SONG:
numDeleted = db.delete(
SongContract.SongEntry.TABLE_NAME, selection, selectionArgs);
// reset _ID
db.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" +
SongContract.SongEntry.TABLE_NAME + "'");
break;
case SONG_WITH_ID:
numDeleted = db.delete(SongContract.SongEntry.TABLE_NAME,
SongContract.SongEntry._ID + " = ?",
new String[]{String.valueOf(ContentUris.parseId(uri))});
// reset _ID
db.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" +
SongContract.SongEntry.TABLE_NAME + "'");
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
return numDeleted;
}
Here is my SongDetailFragment:
public class SongDetailFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>{
private Song song;
private static final int CURSOR_LOADER_ID = 0;
ImageButton imgViewFavButton;
Boolean mIsFavourite = false;
// private final Context mContext;
public SongDetailFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.song_fragment_detail, container, false);
Intent intent = getActivity().getIntent();
if (intent != null && intent.hasExtra("song")) {
song = intent.getParcelableExtra("song");
//display title
((TextView) rootView.findViewById(R.id.detail_title_textview))
.setText(song.getTitle());
((TextView)rootView.findViewById(R.id.detail_description_textview))
.setText(song.getDescription());
((TextView)rootView.findViewById(R.id.song_releasedate_textview))
.setText(song.getReleaseDate());
double dRating = song.getVoteAverage();
String sRating = String.valueOf(dRating);
((TextView)rootView.findViewById(R.id.song_rating_textview))
.setText(sRating + "/10 ");
//show song poster
ImageView imageView = (ImageView) rootView.findViewById(R.id.song_detail_poster_imageview);
Picasso.with(getActivity()).load(song.getPoster()).into(imageView);
}
imgViewFavButton = (ImageButton) rootView.findViewById(R.id.imgFavBtn);
checkFavourites();
imgViewFavButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if (mIsFavourite) {
deleteFromDB();
}
else {
insertData();
mIsFavourite = true;
}
}
});
return rootView;
}
// insert data into database
public void insertData(){
ContentValues songValues = new ContentValues();
songValues.put(SongContract.SongEntry.COLUMN_ID, song.getsong_id());
songValues.put(SongContract.SongEntry.COLUMN_IMAGE, song.getPoster());
songValues.put(SongContract.SongEntry.COLUMN_TITLE, song.getTitle());
songValues.put(SongContract.SongEntry.COLUMN_OVERVIEW, song.getDescription());
songValues.put(SongContract.SongEntry.COLUMN_RELEASEDATE, song.getReleaseDate());
songValues.put(SongContract.SongEntry.COLUMN_RATING, song.getVoteAverage().toString());
//Insert our ContentValues
getActivity().getContentResolver().insert(SongContract.SongEntry.CONTENT_URI,
songValues);
imgViewFavButton.setImageResource(android.R.drawable.btn_star_big_on);
}
private void deleteFromDB() {
ContentValues songValues = new ContentValues();
getActivity().getContentResolver().delete(SongContract.SongEntry.CONTENT_URI,
SongContract.SongEntry.COLUMN_TITLE + " = ?",
new String[]{songValues.getAsString(song.getTitle())});
imgViewFavButton.setImageResource(android.R.drawable.btn_star_big_off);
}
private void checkFavourites() {
Cursor c =
getActivity().getContentResolver().query(SongContract.SongEntry.CONTENT_URI,
null,
SongContract.SongEntry.COLUMN_ID + " = ?",
new String[]{song.getsong_id()},
null);
if (c != null) {
c.moveToFirst();
int index = c.getColumnIndex(SongContract.SongEntry.COLUMN_ID);
if (c.getCount() > 0 && c.getString(index).equals(song.getsong_id())) {
mIsFavourite = true;
imgViewFavButton.setImageResource(android.R.drawable.btn_star_big_on);
}
else{
imgViewFavButton.setImageResource(android.R.drawable.btn_star_big_off);
}
c.close();
}
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args){
return new CursorLoader(getActivity(),
SongContract.songEntry.CONTENT_URI,
null,
null,
null,
null);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
}
// Set the cursor in our CursorAdapter once the Cursor is loaded
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
}
// reset CursorAdapter on Loader Reset
#Override
public void onLoaderReset(Loader<Cursor> loader){
}
}
Notice this line right here:
ContentValues songValues = new ContentValues();
getActivity().getContentResolver().delete(SongContract.songEntry.CONTENT_URI,
SongContract.songEntry.COLUMN_TITLE + " = ?",
new String[]{songValues.getAsString(song.getTitle())});
You set songValues to an empty ContentValues object, and later call getAsString() which will return null since it doesn't contain any key for song.getTitle().
Just change your array to have the song title, you don't need ContentValues here:
new String[]{song.getTitle()});

Listview shows one item multiple times

I am trying to create a List for Android with a SQLite DB. While creating a new Item works without a problem, after it returns to the list activity, the Items are showed various times. Still in my DB only one new Item is inserted (as should), and when I restart the App and load the list, each Item is showed once. So here is my main activity, as I said DBHandler should be ok.
public class MainActivity extends Activity {
List<FavImages> FavImages = new ArrayList<FavImages>();
ListView favImageListView;
final Context context = this;
private SharedPreferences mPrefs;
private SharedPreferences.Editor mEditor;
//label logs
private static String logtag = "CameraApp";
//use main camera
private static int TAKE_PICTURE = 1;
private Uri imageUri;
public Uri imagePath = Uri.parse("android.resource://com.adrian/drawable/no_picture.png");
DataBaseHandler dbHandler;
int longClickedItemIndex;
ArrayAdapter<FavImages> favImagesAdapter;
private static final int EDIT = 0, DELETE = 1;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
favImageListView = (ListView) findViewById(R.id.listView);
dbHandler = new DataBaseHandler(getApplicationContext());
mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
mEditor = mPrefs.edit();
//enter an Item
registerForContextMenu(favImageListView);
//maybe without long
favImageListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
//position of Item
longClickedItemIndex = position;
return false;
}
});
populateList();
//Button Action
Button cameraButton = (Button)findViewById(R.id.button_camera);
cameraButton.setOnClickListener(cameraListener);
}
private OnClickListener cameraListener = new OnClickListener(){
public void onClick(View v){
takePhoto(v);
}
};
//launch native camera app
private void takePhoto(View v){
final Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
//save Image and create file
// in Progress
LayoutInflater factory = LayoutInflater.from(this);
final View textEntryView = factory.inflate(R.layout.text_entry, null);
final EditText input1 = (EditText) textEntryView.findViewById(R.id.pictureName);
final AlertDialog.Builder alert = new AlertDialog.Builder(this);
//create Dialog
alert
.setTitle("Bitte bennenen Sie Ihr Bild!")
.setView(textEntryView)
.setPositiveButton(R.string.alert_dialog_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Log.i("AlertDialog","TextEntry 1 Entered "+input1.getText().toString());
/* User clicked OK so do some stuff */
String inputText = input1.getText().toString();
mEditor.putString("pictureName", inputText);
mEditor.commit();
File photo = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), replaceChars(mPrefs.getString("pictureName", "picture")) + ".jpg");
//access information of file
imageUri = Uri.fromFile(photo);
//save image path information
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
//for favImages
imagePath = imageUri;
mEditor.putString("picturePath", imagePath.toString());
mEditor.commit();
//
startActivityForResult(intent, TAKE_PICTURE);
//
Log.e("Dateipfad", imagePath.toString());
FavImages favImages = new FavImages(dbHandler.getFavCount(), mPrefs.getString("pictureName", "Bild"), imagePath);
dbHandler.createFav(favImages);
FavImages.add(favImages);
//favImagesAdapter.notifyDataSetChanged();
populateList();
List<FavImages> addableFavs = dbHandler.getAllFav();
int favCount = dbHandler.getFavCount();
for(int i = 0; i < favCount; i++){
FavImages.add(addableFavs.get(i));
}
if (!addableFavs.isEmpty())
populateList();
}
});
//show Dialog
alert.show();
}
public String replaceChars (String inputText){
inputText = inputText.replace("ä","ae");
inputText = inputText.replace("ö","oe");
inputText = inputText.replace("ü","ue");
inputText = inputText.replace("ß","ss");
return inputText;
}
//deal with output
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent){
super.onActivityResult(requestCode, resultCode, intent);
//user hits ok button (picture accepted)
if(resultCode == Activity.RESULT_OK){
Uri selectedImage = imageUri;
//communication between apps
getContentResolver().notifyChange(selectedImage, null);
/*get Image
ImageView imageView = (ImageView)findViewById(R.id.image_camera);
//hold Image data
ContentResolver cr = getContentResolver();
Bitmap bitmap;
//get bitmap data
try {
bitmap = MediaStore.Images.Media.getBitmap(cr, selectedImage);
//set Image
imageView.setImageBitmap(bitmap);
//notify user of success
Toast.makeText(MainActivity.this, selectedImage.toString(), Toast.LENGTH_LONG).show();
}catch (Exception e){ //catch exceptions along the way
Log.e(logtag, e.toString());
} */
}
}
//
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo){
super.onCreateContextMenu(menu, view, menuInfo);
menu.setHeaderTitle("Favorit bearbeiten");
menu.add(Menu.NONE, DELETE, menu.NONE, "Favorit löschen");
}
public boolean onContextItemSelected (MenuItem item){
switch (item.getItemId()){
case EDIT:
//TODO: edit Favorites
break;
case DELETE:
//
dbHandler.deleteFav(FavImages.get(longClickedItemIndex));
FavImages.remove(longClickedItemIndex);
favImagesAdapter.notifyDataSetChanged();
break;
}
return super.onContextItemSelected(item);
}
private void populateList(){
//ArrayAdapter<FavImages> adapter = new favImagesListAdapter();
//favImageListView.setAdapter(adapter);
favImagesAdapter = new favImagesListAdapter();
favImageListView.setAdapter(favImagesAdapter);
}
//Constructor for List Items
private class favImagesListAdapter extends ArrayAdapter<FavImages>{
public favImagesListAdapter(){
super (MainActivity.this, R.layout.listview_item, FavImages);
}
#Override
public View getView (int position, View view, ViewGroup parent){
if (view == null)
view = getLayoutInflater().inflate(R.layout.listview_item, parent, false);
FavImages currentFav = FavImages.get(position);
TextView favName = (TextView) view.findViewById(R.id.favName);
favName.setText(currentFav.getImageName());
ImageView ivFavsImage = (ImageView) view.findViewById(R.id.favImage);
ivFavsImage.setImageURI(currentFav.getImagePath());
return view;
}
}
So to sum it up, what am I doing wrong, that my Items are loaded various times.
EDIT:
as requested here is my DBHandler class:
<!-- language: lang-java -->
public class DataBaseHandler extends SQLiteOpenHelper{
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "favoritesManager",
TABLE_FAVS = "favorites",
KEY_ID = "id",
KEY_IMGName = "name",
KEY_IMGPATH = "imagePath";
//standard DB method
public DataBaseHandler(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
//standard DB method
#Override
public void onCreate(SQLiteDatabase db){
db.execSQL("CREATE TABLE " + TABLE_FAVS + "(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_IMGName + " TEXT, " + KEY_IMGPATH + " TEXT)");
}
//standard DB method
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("DROP TABL IF EXISTS" + TABLE_FAVS);
onCreate(db);
}
public void createFav(FavImages favImages){
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_IMGName, favImages.getImageName());
values.put(KEY_IMGPATH, favImages.getImagePath().toString());
db.insert(TABLE_FAVS, null, values);
db.close();
}
public void deleteFav(FavImages favImages){
SQLiteDatabase db = getWritableDatabase();
db.delete(TABLE_FAVS, KEY_ID + "=?", new String[]{String.valueOf(favImages.getId())});
db.close();
}
public int getFavCount(){
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_FAVS, null);
int count = cursor.getCount();
cursor.close();
db.close();
return count;
}
public List<FavImages> getAllFav(){
List<FavImages> favImages = new ArrayList<FavImages>();
SQLiteDatabase db = getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_FAVS, null);
if (cursor.moveToFirst()){
do {
favImages.add(new FavImages(Integer.parseInt(cursor.getString(0)), cursor.getString(1), Uri.parse(cursor.getString(2))));
}while (cursor.moveToNext());
}
cursor.close();
db.close();
return favImages;
}
Hi you need to use the view holder pattern see link provided below:
http://ricston.com/blog/optimising-listview-viewholder-pattern/
Ok after a fresh look on the code I found my mistake myself, I am adding multiple times the same Item to the List. Stupid mistake I know but now it works fine.
Still, thanks for your Help.

How to check if database is empty in SQLite Android with DatabaseConnector class

I have a DatabaseConnector class where I want to check if the database is empty and then show an alert and a click on it will close the activity.
This is my DatabaseConnector class
public class DatabaseConnector {
// Declare Variables
private static final String DB_NAME = "MyNotes";
private static final String TABLE_NAME = "tablenotes";
private static final String TITLE = "title";
private static final String ID = "_id";
private static final String NOTE = "note";
private static final int DATABASE_VERSION = 2;
private SQLiteDatabase database;
private DatabaseHelper dbOpenHelper;
public static final String MAINCAT = "maincat";
public static final String SUBCAT = "subcat";
public DatabaseConnector(Context context) {
dbOpenHelper = new DatabaseHelper(context, DB_NAME, null,
DATABASE_VERSION);
}
// Open Database function
public void open() throws SQLException {
// Allow database to be in writable mode
database = dbOpenHelper.getWritableDatabase();
}
// Close Database function
public void close() {
if (database != null)
database.close();
}
// Create Database function
public void InsertNote(String title, String note , String maincat, String subcat) {
ContentValues newCon = new ContentValues();
newCon.put(TITLE, title);
newCon.put(NOTE, note);
newCon.put(MAINCAT, maincat);
newCon.put(SUBCAT, subcat);
open();
database.insert(TABLE_NAME, null, newCon);
close();
}
// Update Database function
public void UpdateNote(long id, String title, String note) {
ContentValues editCon = new ContentValues();
editCon.put(TITLE, title);
editCon.put(NOTE, note);
open();
database.update(TABLE_NAME, editCon, ID + "=" + id, null);
close();
}
// Delete Database function
public void DeleteNote(long id) {
open();
database.delete(TABLE_NAME, ID + "=" + id, null);
close();
}
// List all data function
//String selection = dbOpenHelper.MAINCAT + " = 'quiz'"
// +" AND " + dbOpenHelper.SUBCAT + " = 'test'";
// public Cursor ListAllNotes() {
// return database.query(TABLE_NAME, new String[] { ID, TITLE }, null,
// null, null, null, TITLE);
// }
public Cursor ListAllNotes(String selection) {
return database.query(TABLE_NAME, new String[] { ID, TITLE }, selection,
null, null, null, TITLE);
}
// Capture single data by ID
public Cursor GetOneNote(long id) {
return database.query(TABLE_NAME, null, ID + "=" + id, null, null,
null, null);
}
And here is the ListActivity wherein I want to close the Activity with an alert
public class dbMainactivty extends ListActivity {
// Declare Variables
public static final String ROW_ID = "row_id";
private static final String TITLE = "title";
private ListView noteListView;
private CursorAdapter noteAdapter;
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Tracker t = ((AnalyticsSampleApp)this.getApplication()).getTracker(TrackerName.APP_TRACKER);
t.setScreenName("dbMainactivty");
t.send(new HitBuilders.AppViewBuilder().build());
// Locate ListView
noteListView = getListView();
// setContentView(R.layout.list_note);
//noteListView = (ListView) findViewById(R.id.listview);
// Prepare ListView Item Click Listener
noteListView.setOnItemClickListener(viewNoteListener);
// Map all the titles into the ViewTitleNotes TextView
String[] from = new String[] { TITLE };
int[] to = new int[] { R.id.ViewTitleNotes };
// Create a SimpleCursorAdapter
noteAdapter = new SimpleCursorAdapter(dbMainactivty.this,
R.layout.list_note, null, from, to);
// Set the Adapter into SimpleCursorAdapter
setListAdapter(noteAdapter);
}
// Capture ListView item click
OnItemClickListener viewNoteListener = new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// Open ViewNote activity
Intent viewnote = new Intent(dbMainactivty.this, ViewNote.class);
// Pass the ROW_ID to ViewNote activity
viewnote.putExtra(ROW_ID, arg3);
startActivity(viewnote);
}
};
#Override
protected void onResume() {
super.onResume();
// Execute GetNotes Asynctask on return to MainActivity
new GetNotes().execute((Object[]) null);
GoogleAnalytics.getInstance(dbMainactivty.this).reportActivityStart(this);
}
#Override
protected void onStop() {
Cursor cursor = noteAdapter.getCursor();
// Deactivates the Cursor
if (cursor != null)
cursor.deactivate();
noteAdapter.changeCursor(null);
super.onStop();
GoogleAnalytics.getInstance(dbMainactivty.this).reportActivityStop(this);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent i = null;
switch (item.getItemId()) {
case R.id.action_rate:
String webpage = "http://developer.android.com/index.html";
Intent intent2 = new Intent(Intent.ACTION_VIEW, Uri.parse(webpage));
startActivity(intent2);
overridePendingTransition(R.anim.slide_in, R.anim.slide_out);
case R.id.action_share:
i = new Intent();
i.setAction(Intent.ACTION_SEND);
//i.putExtra(Intent.EXTRA_TEXT, feed.getItem(pos).getTitle().toString()+ " to know the answer download http://developer.android.com/index.html");
i.setType("text/plain");
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
};
// GetNotes AsyncTask
private class GetNotes extends AsyncTask<Object, Object, Cursor> {
DatabaseConnector dbConnector = new DatabaseConnector(dbMainactivty.this);
#Override
protected Cursor doInBackground(Object... params) {
// Open the database
dbConnector.open();
return dbConnector.ListAllNotes("maincat LIKE 'quiz' AND subcat LIKE 'test'");
}
#Override
protected void onPostExecute(Cursor result) {
noteAdapter.changeCursor(result);
// Close Database
dbConnector.close();
}
}
#Override
protected void onStart() {
super.onStart();
ConnectivityManager conMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (conMgr.getActiveNetworkInfo() == null) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(
"Please check your Internet Connection.")
.setTitle("tilte")
.setCancelable(false)
.setPositiveButton("Exit",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int id) {
//loader.cancel(true);
finish();
}
});
AlertDialog alert = builder.create();
alert.show();
} else {
Cursor cursor = noteAdapter.getCursor();
if(cursor != null && cursor.getCount() > 0){
cursor.moveToFirst();
//do your action
//Fetch your data
GoogleAnalytics.getInstance(dbMainactivty.this).reportActivityStart(this);
Toast.makeText(getBaseContext(), "Yipeee!", Toast.LENGTH_SHORT).show();
}
else {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(
"oops nothing pinned yet! ....")
.setTitle("title")
.setCancelable(false)
.setPositiveButton("Exit",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int id) {
//loader.cancel(true);
finish();
}
});
AlertDialog alert = builder.create();
alert.show();
Toast.makeText(getBaseContext(), "No records yet!", Toast.LENGTH_SHORT).show();
}
}
}
}
I am trying to check
cursor != null && cursor.getCount()>0 and if it turns false then show the alert that
nothing has been pinned yet
Should show up however even though if the cursor returns data the alert still shows up.
First step, take a look at the lifecycle of your activity: http://www.android-app-market.com/wp-content/uploads/2012/03/Android-Activity-Lifecycle.png
As you can see onResume() is called after onStart() which means that checking the cursor on the onStart() can not work.
Secondly you are starting an AsyncTask (GetNotes) on the onResume() method which means you are running a parallel thread at this point and can't check for the result after calling new GetNotes().execute((Object[]) null);
Your problem is you need to check the emptiness of your cursor (cursor != null && cursor.getCount()>0) AFTER the data is loader which mean after the AsyncTask has completed. In other words, move the check for emptiness on your cursor inside the onPostExecute(Cursor result) method.

retrieve the ID (in the database) of the element the user have clicked on a listview

this is what i have done, to retrieve the id but it says that getIndexColumn is not defined in the cursor... what i'm doing wrong?
protected void onListItemClick(ListView l, View v, int position, long id) {
Cursor data = (Cursor)l.getItemAtPosition(position);
String cat = Cursor.getString(Cursor.getIndexColumn(MySQLiteHelper.COLUMN_ID));
Intent myIntent = new Intent(MainActivity.this, sondaggioActivity.class);
myIntent.putExtra("categoriaId", cat);
MainActivity.this.startActivity(myIntent);
}
this is the category class:
public class categorie {
private long id;
private String nome;
private long preferita;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public long getPreferita() {
return preferita;
}
public void setPreferita(long preferita) {
this.preferita = preferita;
}
// Will be used by the ArrayAdapter in the ListView
#Override
public String toString() {
return nome;
}
}
and this is the datasource:
public class pollDataSource {
// Database fields
private SQLiteDatabase database;
private MySQLiteHelper dbHelper;
private String[] allCategorieColumns = { MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_PREF, MySQLiteHelper.COLUMN_NOME };
private String[] allSondaggiColumns = { MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_CATID, MySQLiteHelper.COLUMN_DOMANDA };
private String[] allRisposteColumns = { MySQLiteHelper.COLUMN_ID,
MySQLiteHelper.COLUMN_SONDID, MySQLiteHelper.COLUMN_RISPOSTA,
MySQLiteHelper.COLUMN_SELEZIONATA };
public pollDataSource(Context context) {
dbHelper = new MySQLiteHelper(context);
}
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
public void close() {
dbHelper.close();
}
public categorie createCategoria(String categoria) {
ContentValues values = new ContentValues();
values.put(MySQLiteHelper.COLUMN_NOME, categoria);
values.put(MySQLiteHelper.COLUMN_PREF, 0);
long insertId = database.insert(MySQLiteHelper.TABLE_CATEGORIE, null,
values);
Cursor cursor = database.query(MySQLiteHelper.TABLE_CATEGORIE,
allCategorieColumns, MySQLiteHelper.COLUMN_ID + " = " + insertId, null,
null, null, null);
cursor.moveToFirst();
categorie newCategoria = cursorToCategorie(cursor);
cursor.close();
return newCategoria;
}
public void deleteCategoria(categorie categoria) {
long id = categoria.getId();
System.out.println("Categoria cancellata, id: " + id);
database.delete(MySQLiteHelper.TABLE_CATEGORIE, MySQLiteHelper.COLUMN_ID
+ " = " + id, null);
}
public sondaggi createSondaggio(String domanda, int catid) {
ContentValues values = new ContentValues();
values.put(MySQLiteHelper.COLUMN_DOMANDA, domanda);
values.put(MySQLiteHelper.COLUMN_CATID, catid);
long insertId = database.insert(MySQLiteHelper.TABLE_SONDAGGI, null,
values);
Cursor cursor = database.query(MySQLiteHelper.TABLE_SONDAGGI,
allSondaggiColumns, MySQLiteHelper.COLUMN_ID + " = " + insertId, null,
null, null, null);
cursor.moveToFirst();
sondaggi newSondaggio = cursorToSondaggi(cursor);
cursor.close();
return newSondaggio;
}
public void deleteSondaggio(sondaggi sondaggio) {
long id = sondaggio.getId();
System.out.println("Sondaggio cancellato, id: " + id);
database.delete(MySQLiteHelper.TABLE_SONDAGGI, MySQLiteHelper.COLUMN_ID
+ " = " + id, null);
}
public Cursor getAllCategorie() {
List<categorie> categorie = new ArrayList<categorie>();
Cursor cursor = database.query(MySQLiteHelper.TABLE_CATEGORIE,
allCategorieColumns, null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
categorie categoria = cursorToCategorie(cursor);
categorie.add(categoria);
cursor.moveToNext();
}
// Make sure to close the cursor
// cursor.close();
return cursor;
}
private categorie cursorToCategorie(Cursor cursor) {
categorie categorie = new categorie();
categorie.setId(cursor.getLong(0));
categorie.setPreferita(cursor.getLong(1));
categorie.setNome(cursor.getString(2));
return categorie;
}
private sondaggi cursorToSondaggi(Cursor cursor) {
sondaggi sondaggi = new sondaggi();
sondaggi.setId(cursor.getLong(0));
sondaggi.setDomanda(cursor.getString(1));
sondaggi.setCatid(cursor.getLong(2));
return sondaggi;
}
}
the main activity:
public class MainActivity extends ListActivity {
private pollDataSource datasource;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
datasource = new pollDataSource(this);
datasource.open();
Cursor values = datasource.getAllCategorie();
String[] categorieColumns =
{
MySQLiteHelper.COLUMN_NOME // Contract class constant containing the word column name
};
int[] mWordListItems = { R.id.categoria_label };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
getApplicationContext(), // The application's Context object
R.layout.single_list_item, // A layout in XML for one row in the ListView
values, // The result from the query
categorieColumns, // A string array of column names in the cursor
mWordListItems, // An integer array of view IDs in the row layout
0); // Flags (usually none are needed)
setListAdapter(adapter);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.add:
datasource.createCategoria("peppe");
break;
}
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent myIntent = new Intent(MainActivity.this, sondaggioActivity.class);
myIntent.putExtra("categoriaId", id);
MainActivity.this.startActivity(myIntent);
//Toast.makeText(this, selection, Toast.LENGTH_LONG).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
I assume you have an activity with a list of categories, and onClick of a particular item you want to launch new activity with details of that Item.
I suggest you when you launch the listScreen, query all/some items and maintaine an arrayList of items and save that in some singleton class, then onClick of a particular item pass that index to detail screen via intent.putExtra("index", position) and on detail Screen get that index via getIntent().getIntExtra("index", -1) .now get details of that particular index from arraylist saved in singleton class.
This approach will reduce cost of querying every time from database and data will be available easily.
Change
Cursor data = (Cursor)l.getItemAtPosition(position);
String cat = Cursor.getString(Cursor.getIndexColumn(MySQLiteHelper.COLUMN_ID));
to
Cursor data = (Cursor)l.getItemAtPosition(position);
Long clid = data.getLong(data.getIndexColumn(MySQLiteHelper.COLUMN_ID));
String cat=Long.toString(clid);
those two lines:
Cursor data = (Cursor)l.getItemAtPosition(position);
String cat = Cursor.getString(Cursor.getIndexColumn(MySQLiteHelper.COLUMN_ID));
makes absolutely no sense at all! If you're using a CursorAdapter why are you creating an array of objects? If you're using a ArrayAdapter why are you getting data from cursor?
Also, Cursor don't have any static methods to be called like that. That shouldn't even compile.
If you're using a CursorAdater (or some class that extend it) you the id is passed to you long id here protected void onListItemClick(ListView l, View v, int position, long id)

Categories

Resources