I am making app for finding number plates of india.
my database contains two columnns "code" and "city" code contains data like MH1,MH2 etc.
and city contains data like Pune,Mumbai.
App contains one edittext box and listview.
Listview consists whole data from database like GJ3 Rajkot, GJ10 Jamnagar etc.
if i write GJ in edittext box whole only data of GJ must be apperaed in listview.
Here is the query :
SELECT *
FROM table_name
WHERE code LIKE '%GJ%'
LIMIT 0 , 30
Try this :
Cursor c = mDb.rawQuery(
"select * from table_name where column_name = ?",
new String[] { "search" });
EDIT :
Follow the tutorial of the given above link and add below method into TestAdapter
public Cursor get_tag_Data()
{
try
{
String sql ="select * from table_name where column_name = ?", new String[] { edittext.getText().toString().trim()}";
Cursor mCur = mDb.rawQuery(sql, null);
if (mCur!=null)
{
mCur.moveToNext();
}
return mCur;
}
catch (SQLException mSQLException)
{
Log.e(TAG, "getTestData >>"+ mSQLException.toString());
throw mSQLException;
}
}
and call this method from your class like:
TestAdapter mDbHelper = new TestAdapter(urContext);
mDbHelper.createDatabase();
mDbHelper.open();
Cursor testdata = mDbHelper.get_tag_Data();
mDbHelper.close();
EDIT:
Declare below method into your database class,
public List<String> getQuestions(String difficulty) {
public static List<String> question_Set;
question_Set = new ArrayList<String>();
Cursor c = mDb.rawQuery(
"select * from table_name where column_name = ?", new String[] { difficulty });
while (c.moveToNext()) {
question_Set.add(c.getString(1).trim());
}
return question_Set;
}
Now call like
DB.getQuestions(edittext.getText().toString().trim()); // DB is your database class name
Related
I am trying to write a simple content provider and populate a ListView using these references:
https://developer.android.com/reference/android/app/ListActivity.html
http://www.newthinktank.com/2015/01/make-android-apps-21/
I looked at this thread but it does not seem to be my issue:
SimpleCursorAdapter to populate ListView
The database seems to work, but when I try to bind to my ListView it gives an error of a missing column '_id', but I have it since I can log the contents of the database without problems. Code snippets below:
Logging the database (This WORKS!):
public void logAllPatients() {
// Projection contains the columns we want
String[] projection = new String[]{"id", "name"};
// Pass the URL, projection and I'll cover the other options below
Cursor cursor = resolver.query(CONTENT_URL, projection, null, null, null);
// Cycle through and display every row of data
if (cursor.moveToFirst()) {
do {
String patientList = "";
String id = cursor.getString(cursor.getColumnIndex("id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
patientList = patientList + id + " : " + name + "\n";
Log.d(TEST_CONTENT_PROVIDER, patientList);
} while (cursor.moveToNext());
}
}
trying to populate the listview (missing column?, why)?
private void bindAllPatients() {
try {
// Projection contains the columns we want
String[] projection = new String[]{"id", "name"};
Cursor cursor = resolver.query(CONTENT_URL, projection, null, null, null);
if (cursor != null) {
startManagingCursor(cursor);
cursor.moveToFirst();
// Now create a new list adapter bound to the cursor.
// SimpleListAdapter is designed for binding to a Cursor.
ListAdapter adapter = new SimpleCursorAdapter(
this, // Context.
android.R.layout.two_line_list_item,
cursor, // Pass in the cursor to bind to.
new String[]{"id", "name"}, // Array of cursor columns to bind to.
new int[]{R.id.my_id, R.id.my_name}, 0);
// Parallel array of which template objects to bind to those columns.
// Bind to our new adapter.
setListAdapter(adapter);
cursor.close();
}
} catch (Exception e) {
Log.e(TEST_CONTENT_PROVIDER, e.toString());
}
}
The output log:
D/GMO_CONTENT_PROVIDER: 9 : Joe
D/GMO_CONTENT_PROVIDER: 10 : Mary
E/GMO_CONTENT_PROVIDER: java.lang.IllegalArgumentException: column '_id' does not exist
here's the database creation:
private SQLiteDatabase sqlDB;
static final String DATABASE_NAME = "myPatients";
static final String TABLE_NAME = "patients";
static final String CREATE_DB_TABLE = "CREATE TABLE " + TABLE_NAME +
"(id INTEGER PRIMARY KEY AUTOINCREMENT, " + " name TEXT NOT NULL);";
// bunch of code
#Override
public void onCreate(SQLiteDatabase sqlDB) {
try {
sqlDB.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
sqlDB.execSQL(CREATE_DB_TABLE);
} catch (Exception e) {
Log.e(TEST_CONTENT_PROVIDER, e.toString());
}
}
and the query override, which works!
#Nullable
#Override
public Cursor query(#NonNull Uri uri, #Nullable String[] projection, #Nullable String selection, #Nullable String[] selectionArgs, #Nullable String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(TABLE_NAME);
switch (uriMatcher.match(uri)) {
case uriCode:
queryBuilder.setProjectionMap(values);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
Cursor cursor = queryBuilder.query(sqlDB, projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
any help is greatly appreciated!
The correct answer:
Android column '_id' does not exist?
"SimpleCursorAdapter requires that the Cursor's result set must include a column named exactly "_id"."
I'm writing an app that manipulates with database consists of 3 tables. I created this database from json file using models (Worker model, specialty model) with getters and setters. Now I want to get specific info from this database. I'v already made it but my code is pretty silly. What I need is to change the architecture of my app but I don't know how exactly it should looks like.
This is the examples of my methods, and they are pretty week
This is how I add info into database. I like it, I think it's correct:
public void addWorker(Worker worker){
List<Specialty> specialty;
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
//fixind names
String f_name = fixName(worker.getF_name());
String l_name = fixName(worker.getL_name());
String birthday = fixDate(worker.getBirthday());
values.put(KEY_F_NAME, f_name);
values.put(KEY_L_NAME, l_name);
values.put(KEY_BIRTHDAY, birthday);
values.put(KEY_AVATR_URL, worker.getAvart_url());
specialty = worker.getSpecialty();
long worker_id = db.insert(TABLE_WORKERS,null,values);
//add unique specialty
for (Specialty spec: specialty){
createRelations(worker_id, spec.getSpecialty_id());
if (getCount(spec.getSpecialty_id()) == 0){
addSpecialty(spec);
}
}
}
And this is how I take info from database:
public String[] getFullInfo(String worker_name){
String selectQuery = "HUGE QUERY HERE "where workers.f_name =?";
Log.e(LOG_TAG, selectQuery);
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, new String [] {worker_name});
String[] details = new String[5];
c.moveToFirst();
while (c.isAfterLast() == false){
details[0] = c.getString(c.getColumnIndex(KEY_F_NAME));
details[1] = c.getString(c.getColumnIndex(KEY_L_NAME));
details[2] = c.getString(c.getColumnIndex(KEY_BIRTHDAY));
details[3] = c.getString(c.getColumnIndex("age"));
details[4] = c.getString(c.getColumnIndex(KEY_SPEC_NAME));
c.moveToNext();
}
return details;
}
This is my another query and it has different return type:
public List<Map<String ,String>> getWorkerListBySpec(String spec_name){
String selectQuery = "HUGE QUERY HERE
"where specialty.spec_name=?";
Log.e(LOG_TAG, selectQuery);
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, new String [] {spec_name});
//making list of workers
List<Map<String ,String>> data = new ArrayList<Map<String,String>>();
c.moveToFirst();
while (c.isAfterLast() == false){
Map<String,String> datum = new HashMap<String,String>(2);
datum.put(KEY_F_NAME, c.getString(c.getColumnIndex(KEY_F_NAME)));
datum.put(KEY_L_NAME, c.getString(c.getColumnIndex(KEY_L_NAME)));
datum.put(KEY_BIRTHDAY, c.getString(c.getColumnIndex(KEY_BIRTHDAY)));
data.add(datum);
c.moveToNext();
}
return data;
}
and the third one, which also have different return type:
public List<String> getAllSpecs_Names(){
List<String> spec_names = new ArrayList<String>();
String selectQuery = "select * from " + TABLE_SPECIALTY;
Log.e(LOG_TAG, selectQuery);
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, null);
if (c.moveToFirst()){
do{
spec_names.add(c.getString(c.getColumnIndex(KEY_SPEC_NAME)));
}while (c.moveToNext());
}
return spec_names;
}
I know, that this is all wrong.
Please tell me how I should make all my queries.
It will be good if you give me the link to check how the app should look like
instead of returning a List or Map, you should better return a own CursorWrapper
so you could could look like this:
public WorkerCursor getWorkerListBySpec(String spec_name){
String selectQuery = "HUGE QUERY HERE
"where specialty.spec_name=?";
Log.e(LOG_TAG, selectQuery);
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery(selectQuery, new String [] {spec_name});
return new WorkerCursor(cursor);
}
public static class WorkerCursor extends CursorWrapper {
/**
* Creates a cursor wrapper.
*
* #param cursor The underlying cursor to wrap.
*/
public WorkerCursor(Cursor cursor) {
super(cursor);
}
public Worker getWorker() {
return getWorkerAtCursor();
}
public Worker getWorker(int position) {
if (moveToPosition(position)) {
return getWorkerCursor();
} else {
return null;
}
}
private Worker getWorkerAtCursor() {
if (isBeforeFirst() || isAfterLast()) {
return null;
}
worker worker = new Worker();
worker.name = c.getString(c.getColumnIndex(KEY_F_NAME));
....
return worker;
}
}
and the same for your List, just with a other CursorWrapper
and don't forget to close the CursorWrapper, when it's no more needed, like in onDestroy of Activity and so
I'm trying to load an sqlite table as an arraylist so that i can use the data in it. I'm not too sure about the sqlite queries but i already have a class built to manipulate the strings as is, which is what i'm more comfortable with. I can load an individual row but i'm not sure how to get the whole table as an arraylist.
I have the following method in my main method
public void ShowCNData()
{
TestAdapter mDbHelper = new TestAdapter(this);
mDbHelper.createDatabase();
mDbHelper.open();
String allData = mDbHelper.getCYData().get(1)[1];
thing.setText(allData);
mDbHelper.close();
}
and the following method in my dbAdapter/Helper class
public ArrayList<String[]> getCYData()
{
ArrayList<String[]> CYData = new ArrayList<String[]>();
try
{
String sql ="SELECT * FROM cnYears ";
Cursor mCur = null;
do
{
mCur = mDb.rawQuery(sql, null);
CYData.add(new String[] {mCur.getString(0),mCur.getString(1),mCur.getString(2),mCur.getString(3),mCur.getString(4)});
}
while (mCur.moveToNext());
return CYData;
}
catch (SQLException mSQLException)
{
Log.e(TAG, "getTestData >>"+ mSQLException.toString());
throw mSQLException;
}
}
How do i load the data into my ArrayList?
Without actual log information, I'd guess your NullPointerException occurs when you get an empty cursor. Try it this way:
//initialize arraylist, execute query etc.
if (cursor.moveToFirst()) {
do {
String[] entry = new String[dataSize];
//pull your data here
data[0] = cursor.getInt(0);
data[1] = cursor.getString(1);
//...
list.add(entry);
} while (cursor.moveToNext());
}
// return arraylist
I have a SQLite table of this tipe
Table Vehicles:
CATEGORY COUNTRY ID NAME EMAIL
A GE 1 BMW sample1#salple.it
A GE 2 Lamborghini sample2#salple.it
B GE 3 BMW sample3#salple.it
I want to select all the entries that have a specified name or a specified category and pass all the parameters how each row in a constructor
Vehicle(String category, String country, int id, String name, String email)
I have implemented this adapter using some tutorials:
public class TestAdapter
{
protected static final String TAG = "DataAdapter";
private final Context mContext;
private SQLiteDatabase mDb;
private DataBaseHelper mDbHelper;
public TestAdapter(Context context)
{
this.mContext = context;
mDbHelper = new DataBaseHelper(mContext);
}
public TestAdapter createDatabase() throws SQLException
{
try
{
mDbHelper.createDataBase();
}
catch (IOException mIOException)
{
Log.e(TAG, mIOException.toString() + " UnableToCreateDatabase");
throw new Error("UnableToCreateDatabase");
}
return this;
}
public TestAdapter open() throws SQLException
{
try
{
mDbHelper.openDataBase();
mDbHelper.close();
mDb = mDbHelper.getReadableDatabase();
}
catch (SQLException mSQLException)
{
Log.e(TAG, "open >>"+ mSQLException.toString());
throw mSQLException;
}
return this;
}
public void close()
{
mDbHelper.close();
}
public boolean SaveVehicles(String category , String country, String id, String name, String email)
{
try
{
ContentValues cv = new ContentValues();
cv.put("Category", category);
cv.put("Country", country);
cv.put("id", id);
cv.put("Name", name);
cv.put("Email", email);
mDb.insert("Vehicles", null, cv);
Log.d("SaveVehicles", "informationsaved");
return true;
}
catch(Exception ex)
{
Log.d("SaveVehicles", ex.toString());
return false;
}
}
}
But I don't know how I could implement the various get methods that I need, to meet a solution to my problem.
Creating an object from a SQL query would look something like this
/**
* #return Returns a list of all objects.
*/
public ArrayList<Object> getAllObjects()
{
// Select All Query
String selectQuery = "SELECT * FROM SOME_TABLE";
// Get the isntance of the database
SQLiteDatabase db = this.getWritableDatabase();
//get the cursor you're going to use
Cursor cursor = db.rawQuery(selectQuery, null);
//this is optional - if you want to return one object
//you don't need a list
ArrayList<Object> objectList = new ArrayList<Object>();
//you should always use the try catch statement incase
//something goes wrong when trying to read the data
try
{
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
//the .getString(int x) method of the cursor returns the column
//of the table your query returned
Object object= new Object(Integer.parseInt(cursor.getString(0)),
Integer.parseInt(cursor.getString(1)),
Integer.parseInt(cursor.getString(2)),
cursor.getString(3),
cursor.getString(4),
cursor.getString(5),
Boolean.parseBoolean(cursor.getString(6))
);
// Adding contact to list
objectList.add(object);
} while (cursor.moveToNext());
}
}
catch (SQLiteException e)
{
Log.d("SQL Error", e.getMessage());
return null;
}
finally
{
//release all your resources
cursor.close();
db.close();
}
return objectList;
}
The code above assumes you have some table in your database named "SOME_TABLE" and that you have an object that takes 7 parameters but you should be able to alter the snippet to make it work for you.
You need to query your database for the data, and then iterate through the returned cursor to pull out the data you need and put it into strings to feed into your constructor.
The query would look something like this (using the info you provided and the query method):
public Cursor fetchList(String category) {
return mDb.query("Vehicles", new String[] { "CATEGORY", "COUNTRY", "ID", "NAME", "EMAIL" }, "Category =" + category,
null, null, null, null);
}
Note that this is a basic query and subject to SQL injection attacks, It should be parameterized to make it less vulnerable, unless you are not going to allow the user to type in the category and rather have them pick from a list you provide.
Anyway, that would return your data in a cursor, with one row for each record that matched the search parameters. From there, you would need to iterate through the returned cursor and pull the data out of it and into strings you can use.
I have written a small android app that grabs some data and displays it in a ListView.
I want to have the list sorted in ascending order (no prob). But when I add a new item it stays at the bottom of the list even when the view/app is reloaded. It seems the only data that is being sorted is the entries that were created in the database OnCreate() method.
I'm not sure what code to provide but i'll start by showing you snippets of the DBAdapter class, then from the main app class.
Database construction query:
private static final String DATABASE_CREATE =
"create table "+ DATABASE_TABLE
+ "("
+ FIELD_ROWID+" integer primary key autoincrement, "
+ FIELD_NAME +" varchar(30) not null, " + FIELD_TELEPHONE + " varchar(20) not null, "
+ FIELD_ADDRESS + " text not null,"
+ FIELD_URL + " varchar(255) not null);";
Function to get list of data:
public Cursor getRestaurants()
{
Cursor result = null;
try{
result = db.query(DATABASE_TABLE, new String[] {FIELD_ROWID, FIELD_NAME}, null, null, null, null, FIELD_NAME+" ASC");
}
catch (Exception e)
{
Log.v("applog", e.getMessage());
}
return result;
}
Here is a snippet of the main method. Here you can see that I am calling the getRestaurants() function shown above. I'm stumped as to why the data isn't being sorted.
Any advice greatly appreciated. Thanks in advance.
public class Assignment2 extends ListActivity {
// Set up some global variables.
private static final int ADD_NEW_ID = Menu.FIRST;
private static final int CLOSE_APP_ID = ADD_NEW_ID+1;
private final DBAdapter db = new DBAdapter(this);
private static CursorAdapter curAdapter = null;
private static Cursor rawData = null;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
db.open(); // Open connection to restaurant db.
rawData = db.getRestaurants();
Log.v("applog", rawData.getCount()+" Restaurants loaded from DB.");
if(rawData.getCount() == 0)
{
Toast.makeText(getApplicationContext(), "No restaurants found.", Toast.LENGTH_SHORT).show();
}
try
{
/* The following two arrays are used to map DB fields to ListView items
* From a custom layout file.
*/
// Array of db fields to be used when converting cursor to ListView
String[] strFields = { "name", BaseColumns._ID };
// Array of listview id's to be used when populating the ListView
int[] intFields = { R.id.first };
curAdapter = new SimpleCursorAdapter(this, R.layout.row, rawData, strFields, intFields);
}
catch (Exception e)
{
Log.v("applog", e.getMessage());
}
// Apply the converter cursor to the current ListView
setListAdapter(curAdapter);
db.close(); // Close connection to restaurant db.
Im not sure exactly what your problem is but, it all looks good minus these lines of code I have when I get a callback from my new data insert
if(cursor!=null)cursor.requery();
adapter.notifyDataSetChanged();
Hopefully this will fix your issue.