AutoCompleteTextView adapter not displaying dropdown? - java

Here is my onCreate method:
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = getIntent();
if (intent.getData() == null)
intent.setData(Formulas.CONTENT_URI);
AutoCompleteTextView searchBar = (AutoCompleteTextView)findViewById(R.id.searchBar);
Cursor c = getContentResolver().query(getIntent().getData(),new String[] { Formulas.TITLE }, null, null, null);
SimpleCursorAdapter searchAdapter =
new SimpleCursorAdapter(this, android.R.layout.simple_dropdown_item_1line, c,
new String[] { Formulas.TITLE } , new int[] { android.R.id.text1} );
searchBar.setAdapter(searchAdapter);
}
I did input some sample data in my databaseopenhelper:
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE formula ( \n" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, \n" +
"title TEXT NOT NULL, \n" +
"formula TEXT NOT NULL \n" +
");");
db.execSQL("INSERT INTO formula VALUES ( \n" +
"null, \"Pythagorean theorium\", \"a^2+b^2=c^2\" \n" +
"); ");
db.execSQL("INSERT INTO formula VALUES ( \n" +
"null, \"Perimeter of a square\", \"l^2 * w^2\" \n" +
"); ");
db.execSQL("INSERT INTO formula VALUES ( \n" +
"null, \"Area of a square\", \"l^4\" \n" +
"); ");
}
The problem is where I set the adapter to the AutoCompleteTextView, I expect the values that I inserted using the SQLiteDatabase.execSQL(String) method. But nothing is there? The dropdown box doesn't even show up? I used debugging and found that the Cursor was not null and neither was the adapter or AutoCompleteTextView? What could be the problem? I already defined my own contentprovider.

The query returned nothing because the content uri was faulty and completely my fault. Here is the relavent thread.

Related

Changing what data is used by CustomCursorAdapter

I've been trying for some days to load some data from a SQLite database into a ListView inside a Fragment but I'm having this issue that I can't see the solution neither found help online.
My database consists of two tables, 'user' and 'team', being the former in a one to many relation with the later.
//User Table
public static final String CREATE_TABLE_USER =
"CREATE TABLE " + USER_TABLE + "("
+ USER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ USER_NAME + " TEXT NOT NULL,"
+ USER_SURNAME + " TEXT NOT NULL,"
+ USER_EMAIL + " TEXT NOT NULL,"
+ USER_PHONE + " NUMBER,"
+ USER_PASSWORD + " TEXT NOT NULL)";
//Team Table
public static final String CREATE_TABLE_TEAM =
"CREATE TABLE " + TeamColumns.TEAM_TABLE + "("
+ TeamColumns.TEAM_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ TeamColumns.TEAM_NAME + " TEXT NOT NULL,"
+ TeamColumns.TEAM_COUNTRY + " TEXT NOT NULL,"
+ TeamColumns.TEAM_BOSS + " TEXT NOT NULL,"
+ TeamColumns.TEAM_DRIVER1 + " TEXT NOT NULL,"
+ TeamColumns.TEAM_DRIVER2 + " TEXT NOT NULL,"
+ TeamColumns.TEAM_CAR + " TEXT NOT NULL,"
+ TeamColumns.TEAM_POINTS + " NUMBER,"
+ TeamColumns.TEAM_ICON + " TEXT,"
+ TeamColumns.TEAM_USER_ID + " INTEGER,"
+ "CONSTRAINT userID_FK FOREIGN KEY (userID) REFERENCES " + USER_TABLE + "(id))";
So with a database structured this way, I want the ListView to only show the teams associated to the one user logged in. But i can't find how to do it, I don't really select what SQL query is used when loading info, trying to alter the cursor in the overriden bindView method does nothing and the furthest i managed to get showed the wanted rows, but the app crushed the moment i scrolled down to the bottom (I presume i just created a bunch of empty list items where usually are more items). Online search has also been of no help (sorry in advance if this question is already here) so I'm at a stalemate with this part of my app.
My question is:
Is there a way to change the SQL sentence my CustomCursorAdapter uses to load my data?
This is where I load all the data into the ListItem in the CursorAdapter class:
#Override
public void bindView(View view, final Context context, Cursor cursor) {
//Team info placeholders
final ImageView logoView = view.findViewById(R.id.listIcon);
TextView nameText = view.findViewById(R.id.listName);
TextView countryText = view.findViewById(R.id.listCountry);
TextView directorText = view.findViewById(R.id.listDirector);
//Retrieving info
String logoURI = cursor.getString(cursor.getColumnIndexOrThrow(TeamContract.TeamColumns.TEAM_ICON));
String name = cursor.getString(cursor.getColumnIndexOrThrow(TeamContract.TeamColumns.TEAM_NAME));
String country = cursor.getString(cursor.getColumnIndexOrThrow(TeamContract.TeamColumns.TEAM_COUNTRY));
String director = cursor.getString(cursor.getColumnIndexOrThrow(TeamContract.TeamColumns.TEAM_BOSS));
//Seting the image
Glide.with(context).asBitmap()
.load(Uri.parse("file:///android_asset/" + logoURI))
.error(R.drawable.ic_baseline_error_outline_24).centerCrop().into(new BitmapImageViewTarget(logoView) {
#Override
protected void setResource(Bitmap resource) {
RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(context.getResources(), resource);
drawable.setCircular(true);
logoView.setImageDrawable(drawable);
}
});
//Setting the texts
nameText.setText(name);
countryText.setText(country);
directorText.setText(director);
}
And here where I initialize the Adapter from my Fragment class:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_team, container, false);
// Referencias UI
teamList = root.findViewById(R.id.teams_list);
mteamAdapter = new TeamAdapter(getActivity(), null);
// Setup
teamList.setAdapter(mteamAdapter);
// Eventos
teamList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Cursor currentItem = (Cursor) mteamAdapter.getItem(i);
String currentTeamId = currentItem.getString(currentItem.getColumnIndexOrThrow(TeamContract.TeamColumns.TEAM_ID));
launchTeamView(currentTeamId);
}
});
mTeamDbHelper = new DatabaseHelper(getActivity());
loadLawyers();
return root;
}

delete item from local database function doesn't work

//the following function 'listens to the click' - here we are using an 'item click listener' which gives you a number of which one was clicked
lv_customerList.setOnItemClickListener((parent, view, position, id) -> {
//getting the customer that was just clicked to send it to the method to delete
//the parent of the listener is the listview
CustomerModel clickedCustomer = (CustomerModel) parent.getItemAtPosition(position); //this tells me which person was just clicked
//now we call the "deleteOne" function from the databaseHelper class
dataBaseHelper.deleteOne(clickedCustomer);
//now we update the list view
ShowCustomersOnListView(dataBaseHelper);
Toast.makeText(MainActivity.this, "Deleted" + clickedCustomer,Toast.LENGTH_SHORT).show();
});
This is the code in the MainActivity
//creating a new function that will delete contents from a database
public boolean deleteOne(CustomerModel customerModel) {
//find customerModel in the database. if is is found, delete it and return true, otherwise return false
SQLiteDatabase db = this.getWritableDatabase();
String queryString = "DELETE FROM" + CUSTOMER_TABLE + "WHERE" + CUSTOMER_ID + " = " + customerModel.getId();
Cursor cursor = db.rawQuery(queryString, null);
if (cursor.moveToFirst()) {
return true;
}
else {
return false;
}
}
And this is the code from the DatabaseHelper activity
I followed the https://youtu.be/312RhjfetP8 tutorial and copied the code exactly (although the android IDE suggested to change the...
new AdapterView.OnItemClickListener()
to a lambda (in the method in mainactivity)
But now whenever I click one of the rows (see video to understand what i mean) in the app - the app just crashes and I'm not sure why :(
Could someone please help me out?
Thank you so much!
I'm pretty sure that you miss a lot of space characters in the query String.
String queryString = "DELETE FROM" + CUSTOMER_TABLE + "WHERE" + CUSTOMER_ID + " = " + customerModel.getId();
should be changed to
String queryString = "DELETE FROM " + CUSTOMER_TABLE + " WHERE " + CUSTOMER_ID + " = " + customerModel.getId();
DeleteBuilder<CustomerModel, Integer> deletebuilder =
mcustomermodel.deleteBuilder();

Checking that conditions are met before adding the order to the database

I am trying to make sure that the user has selected a waiter id (The first if statement) and that the id is valid and relates to a record in the database(The else if statement).
I am collecting the id from a Number (GUI Text in Android) and selecting the Number value like so
EditText waiter_id;
waiter_id = (EditText) findViewById(R.id.waiter_id);
TextUtils.isEmpty(waiter_id.getText() checks to make sure a value has been entered and displays a message if not this works.
After I am calling a method created in the DataBaseHelper isEmployee(String id) class which uses the id entered by the user to search the database for that record. If the id is not found in the database then a message should appear to alert the user.
Order onClick OrderActivity
order.setOnClickListener(new View.OnClickListener() {
Order order;
#Override
public void onClick(View view) {
if (TextUtils.isEmpty(waiter_id.getText())) {
Toast.makeText(OrderActivity.this, "Please select waiter id", Toast.LENGTH_SHORT).show();
// This is where the method which returns the boolean is called using
// the value in the Number field in xml file
} else if (!dbHelp.isEmployee(String.valueOf(waiter_id))){
Toast.makeText(OrderActivity.this, "Id not valid", Toast.LENGTH_SHORT).show();
}
});
Method for querying the database DataBaseHelper Class
public Boolean isEmployee(String id){
SQLiteDatabase db = this.getReadableDatabase();
String findEmployeeUsingId = "SELECT * FROM " + EMP_TABLE +
" WHERE " + ID_EMP + " = " + id;
Cursor cursor = db.rawQuery(findEmployeeUsingId, null);
if (cursor.getCount() == 0) {
return false;
}
else
return true;
}
The error message I am receivingis:
com.example.dropit E/SQLiteLog: (1) near ".": syntax error in "SELECT * FROM EMP_TABLE WHERE ID = androidx.appcompat.widget.AppCompatEditText{93d8cbb VFED..CL. .F...... 249,193-829,317 #7f08011f app:id/waiter_id aid=1073741824}"
android.database.sqlite.SQLiteException: near ".": syntax error (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM EMP_TABLE WHERE ID = androidx.appcompat.widget.AppCompatEditText{93d8cbb VFED..CL. .F...... 249,193-829,317 #7f08011f app:id/waiter_id aid=1073741824}
at com.example.dropit.DataBaseHelper.isEmployee(DataBaseHelper.java:283)
at com.example.dropit.OrderActivity$1.onClick(OrderActivity.java:58)
waiter_id is an EditText and not a string.
When you call isEmployee() you should pass its text:
else if (!dbHelp.isEmployee(waiter_id.getText().toString()))
Also use a ? placeholder inside rawQuery() instead of concatenating the parameter:
String findEmployeeUsingId = "SELECT * FROM " + EMP_TABLE + " WHERE " + ID_EMP + " = ?";
Cursor cursor = db.rawQuery(findEmployeeUsingId, new String[] {id});

Android SQLite database: "Column does not exist" when it does

The database is created using a SQLiteOpenHelper:
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
String SQL_CREATE_INVENTORY_TABLE = "CREATE TABLE " + InventoryEntry.TABLE_NAME + "("
+ InventoryEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ InventoryEntry.COLUMN_PRODUCT_IMAGE + " BLOB, "
+ InventoryEntry.COLUMN_PRODUCT_NAME + " TEXT NOT NULL, "
+ InventoryEntry.COLUMN_PRODUCT_PRICE + " REAL NOT NULL, "
+ InventoryEntry.COLUMN_PRODUCT_QUANTITY + " INTEGER, "
+ InventoryEntry.COLUMN_PRODUCT_DESCRIPTION + " TEXT);";
sqLiteDatabase.execSQL(SQL_CREATE_INVENTORY_TABLE);
}
All the constants are defined in a contract, this is the COLUMN_PRODUCT_IMAGE one:
public static final String COLUMN_PRODUCT_IMAGE = "image";
In a CursorAdapter, I try to access the image column from the bindView method, after adding some random data to the database:
#Override
public void bindView(View view, final Context context, Cursor cursor) {
ImageView imageView = view.findViewById(R.id.product_image);
byte [] bytes = cursor.getBlob(cursor.getColumnIndexOrThrow(InventoryEntry.COLUMN_PRODUCT_IMAGE));
Bitmap bitmap = BitmapUtils.getBitmap(bytes);
imageView.setImageBitmap(bitmap);
}
This produces an java.lang.IllegalArgumentException: column 'image' does not exist
I double checked the database using windows cmd, here's how it looks:
sqlite> select * from inventory;
_id image name price quantity description
---------- ---------- ---------- ---------- ---------- -----------
1 ff 5.0 5 fds
Column 'image' exists, so why the error?

Android - SQlite insert not inserting

So i am trying to insert some data in the internal sqlite database but after i run the insert no data has been added. There are, as far as i can see no errors in the logs and every debug log i put into it is shown. If i try to run the query that is returned in the log in sqlitestudio it works without a problem so i haven't got a clue as to what is going wrong.
#Override
public void onCreate(SQLiteDatabase db) {
String SQL = pictureTable();
db.execSQL(SQL);
}
private String pictureTable() {
return "CREATE TABLE geophoto_db_pictures ( picid integer,"
+ "name varying character(50),"
+ "city varying character(20) NOT NULL,"
+ "zipcode varying character(20) NOT NULL,"
+ "country varying character(20) NOT NULL,"
+ "picdate datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,"
+ "tags varying character(200),"
+ "image varying character(200) NOT NULL,"
+ "uploaded integer NOT NULL DEFAULT 0, PRIMARY KEY (picid))";
}
#Override
public void savePicture(Picture pic) {
Log.d(LOG_TAG, "saving picture started. Data: " + pic.getName());
// clean the inputs
String name = pic.getName();
String city = pic.getCity();
if (city != null) {
city = "'" + city + "'";
}
String country = pic.getCountry();
if (country != null) {
country = "'" + country + "'";
}
String zip = pic.getZipcode();
if (zip != null) {
zip = "'" + zip + "'";
}
String tags = tagsToString(pic.getTags());
String image = pic.getImage();
// Insert Query, all possible null values on "not null" rows will be
// replaced by a default value.
String SQL = "INSERT INTO geophoto_db_pictures(name, city, zipcode, country, tags, image)"
+ "VALUES('"
+ name
+ "',"
+ "IFNULL("
+ city
+ ", 'Unknown')"
+ ","
+ "IFNULL("
+ zip
+ ", 'Unknown')"
+ ","
+ "IFNULL("
+ country + ",'Unknown')" + ",'" + tags + "','" + image + "')";
Log.d(LOG_TAG, SQL);
executeWriteQuery(SQL);
ArrayList<Picture> list = getAllPictures();
Log.d(LOG_TAG, "Size :"+list.size());
}
private Cursor executeWriteQuery(String query){
Log.d(LOG_TAG, "execute write query");
SQLiteDatabase db = getWritableDatabase();
Cursor response = db.rawQuery(query, null);
Log.d(LOG_TAG, "write query executed");
return response;
}
All tips/help greatly appreciated!
Thomas
Try to put a semicolon at the end of table creation query. In your case as show below
private String pictureTable() {
return "CREATE TABLE geophoto_db_pictures ( picid integer,"
+ "name varying character(50),"
+ "city varying character(20) NOT NULL,"
+ "zipcode varying character(20) NOT NULL,"
+ "country varying character(20) NOT NULL,"
+ "picdate datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,"
+ "tags varying character(200),"
+ "image varying character(200) NOT NULL,"
+ "uploaded integer NOT NULL DEFAULT 0, PRIMARY KEY (picid));";
}
While providing a query through an external String, you will need to provide SQL query with an end of statement ;. Using the primitive SQLite does not require ; as it just takes arguments and create function query itself. I have experienced both cases and I ended up understanding the way I have put it here.
The problem you are facing is that you are trying to use rawQuery() to insert a record, when you should be using execSQL() instead (see this answer).
So, the correct code for executeWriteQuery would be as follows:
private void executeWrite(String command){
Log.d(LOG_TAG, "execute write");
SQLiteDatabase db = getWritableDatabase();
db.execSQL(command);
Log.d(LOG_TAG, "write executed");
}
Also, consider using insert() instead as that will allow you to get a return value to determine whether or not the data was inserted successfully.

Categories

Resources