how to separate [String] by "-" and make multiple column on android? - java

I'm working on a Searchable dictionary. Its Raw database is separated by "-" like
ColumnA(Key_Word) ColumnB(Key_defination)
Apple - One kind of Fruit
Mango - One fruit also
But I want to make it 3 column, (Column C will be Key_details)
ColumnA ColumnB ColumnC (Key_details)
Apple - One kind of Fruit - Round shape
Mango - One fruit also - Found in Bangladesh
When people search A, application will show Column B and C. The reason why i splited string is I want to show Coumn B and C on different window. How to do that? Here is my source-
/**
* Contains logic to return specific words from the dictionary, and
* load the dictionary table when it needs to be created.
*/
public class DictionaryDatabase {
private static final String TAG = "DictionaryDatabase";
//The columns we'll include in the dictionary table
public static final String KEY_WORD = SearchManager.SUGGEST_COLUMN_TEXT_1;
public static final String KEY_DEFINITION = SearchManager.SUGGEST_COLUMN_TEXT_2;
private static final String DATABASE_NAME = "dictionary";
private static final String FTS_VIRTUAL_TABLE = "FTSdictionary";
private static final int DATABASE_VERSION = 2;
private final DictionaryOpenHelper mDatabaseOpenHelper;
private static final HashMap<String,String> mColumnMap = buildColumnMap();
public DictionaryDatabase(Context context) {
mDatabaseOpenHelper = new DictionaryOpenHelper(context);
}
private static HashMap<String,String> buildColumnMap() {
HashMap<String,String> map = new HashMap<String,String>();
map.put(KEY_WORD, KEY_WORD);
map.put(KEY_DEFINITION, KEY_DEFINITION);
map.put(BaseColumns._ID, "rowid AS " +
BaseColumns._ID);
map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " +
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
map.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID, "rowid AS " +
SearchManager.SUGGEST_COLUMN_SHORTCUT_ID);
return map;
}
public Cursor getWord(String rowId, String[] columns) {
String selection = "rowid = ?";
String[] selectionArgs = new String[] {rowId};
return query(selection, selectionArgs, columns);
}
public Cursor getWordMatches(String query, String[] columns) {
String selection = KEY_WORD + " MATCH ?";
String[] selectionArgs = new String[] {query+"*"};
return query(selection, selectionArgs, columns);
}
private Cursor query(String selection, String[] selectionArgs, String[] columns) {
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(FTS_VIRTUAL_TABLE);
builder.setProjectionMap(mColumnMap);
Cursor cursor = builder.query(mDatabaseOpenHelper.getReadableDatabase(),
columns, selection, selectionArgs, null, null, null);
if (cursor == null) {
return null;
} else if (!cursor.moveToFirst()) {
cursor.close();
return null;
}
return cursor;
}
private static class DictionaryOpenHelper extends SQLiteOpenHelper {
private final Context mHelperContext;
private SQLiteDatabase mDatabase;
private static final String FTS_TABLE_CREATE =
"CREATE VIRTUAL TABLE " + FTS_VIRTUAL_TABLE +
" USING fts3 (" +
KEY_WORD + ", " +
KEY_DEFINITION + ");";
DictionaryOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mHelperContext = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
mDatabase = db;
mDatabase.execSQL(FTS_TABLE_CREATE);
loadDictionary();
}
private void loadDictionary() {
new Thread(new Runnable() {
public void run() {
try {
loadWords();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
}
private void loadWords() throws IOException {
Log.d(TAG, "Loading words...");
final Resources resources = mHelperContext.getResources();
InputStream inputStream = resources.openRawResource(R.raw.definitions);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String line;
while ((line = reader.readLine()) != null) {
String[] strings = TextUtils.split(line, "-");
if (strings.length < 2) continue;
long id = addWord(strings[0].trim(), strings[1].trim());
if (id < 0) {
Log.e(TAG, "unable to add word: " + strings[0].trim());
}
}
} finally {
reader.close();
}
Log.d(TAG, "DONE loading words.");
}
public long addWord(String word, String definition) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_WORD, word);
initialValues.put(KEY_DEFINITION, definition);
return mDatabase.insert(FTS_VIRTUAL_TABLE, null, initialValues);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + FTS_VIRTUAL_TABLE);
onCreate(db);
}
}
}

String[] arr = string.split("-");
String#split(String regex)
Returns the array of strings computed by splitting this string around
matches of the given regular expression.
EDIT:
long id = addWord(strings[0].trim(), strings[1].trim());
Above line should be:
long id = addWord(strings[0].trim(), strings[1].trim(),strings[2].trim());
And change your addWord function as I mentioned below.
public long addWord(String word, String definition,String details) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_WORD, word);
initialValues.put(KEY_DEFINITION, definition);
initialValues.put(KEY_DETAILS, details);
return mDatabase.insert(FTS_VIRTUAL_TABLE, null, initialValues);
}

A better way to handle the tokenization is by using StringTokenizer
StringTokenizer token = new StringTokenizer(str,"-");
To access the tokens,
while(token.hasNext())
{
String tmp = token.nextToken();
...
}

Related

Null Pointer Exception in Android Content Provider [duplicate]

Im trying to store a particular columns data in a method and call that method in another classes String [] where a spinner will access that array to display the columns rows for the user to select which will then get stored in another database.
Im getting nulpointerexception and when I try and open() the database the database gets locked. Sorry for sounding like a complete amateur, relatively new to android. Thank you in advance for any help.
Here is my code when I call getInstance() and getCPnames() in my main class
String[] carParks = CarParkDb.getInstance().getCpnames();
Here is my code for the database:
package com.example.parkangel;
import java.util.ArrayList;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class CarParkDb {
public static final String KEY_ID = "_id";
public static final String KEY_CPNAME = "cpname";
public static final String KEY_COST = "cost";
private static final String DATABASE_NAME = "CPDB";
private static final String DATABASE_TABLE = "CPTable";
private static final int DATABASE_VERSION = 1;
private CPDbHelper cpdbHelper;
private Context ourContext;
private SQLiteDatabase ourDatabase;
private static CarParkDb instance;
private static class CPDbHelper extends SQLiteOpenHelper{
public CPDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" +
KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_CPNAME + " TEXT NOT NULL, " + KEY_COST + " TEXTNOT NULL);");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values('1','LearningResource Center','2');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values ('2','ParkandRide','1');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values ('3','deHavilland Campus','2');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values('4','MultiStorey Building','2');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values('5','Reception','2');");
}
public void onOpen(final SQLiteDatabase db) {
super.onOpen(db);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
public CarParkDb (final Context c)
{
this.cpdbHelper= new CPDbHelper(c);
establishDb();
//ourContext = c;
}
public void establishDb()
{
if (this.ourDatabase == null)
{
this.ourDatabase = this.cpdbHelper.getWritableDatabase();
}
}
public CarParkDb() {
// TODO Auto-generated constructor stub
}
public CarParkDb open() throws SQLException
{
System.out.println ("running open");
cpdbHelper = new CPDbHelper(ourContext);
ourDatabase = cpdbHelper.getWritableDatabase();
return this;
}
public void close()
{
ourDatabase.close();
}
/*public long createEntry(String cpname, String cost){
ContentValues cv = new ContentValues();
cv.put(KEY_CPNAME, cpname);
cv.put(KEY_COST, cost);
return ourDatabase.insert(DATABASE_TABLE, null, cv);
}*/
public String getData() {
// TODO Auto-generated method stub
//open();
String[] columns = new String[] {KEY_ID, KEY_CPNAME, KEY_COST};
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null,null,null, null, null);
String result = " ";
int iRow = c.getColumnIndexOrThrow(KEY_ID);
int iCpname = c.getColumnIndexOrThrow(KEY_CPNAME);
int iCost = c.getColumnIndexOrThrow(KEY_COST);
for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
result = result + c.getString(iRow) + " " +c.getString(iCpname) + " " + c.getString(iCost) + " " + "\n";
c.close();
ourDatabase.close();
}
return result;
}
public static CarParkDb getInstance()
{
synchronized(CarParkDb.class)
{
if (instance == null)
{
instance = new CarParkDb();
}
return instance;
}
}
public String[] getCpnames()
{
//open();
if (ourDatabase == null) System.out.println ("is null");
Cursor c = null;
ArrayList<String> list = new ArrayList<String>();
ourDatabase = cpdbHelper.getReadableDatabase();
//SQLiteDatabase db = cpdbHelper.getReadableDatabase();
String query = "SELECT " + KEY_CPNAME + " FROM " + DATABASE_TABLE;
{
c = this.ourDatabase.rawQuery(query, null);
int iCpname = c.getColumnIndexOrThrow(KEY_CPNAME);
if (c.moveToFirst())
{
do
{
list.add(c.getString(iCpname));;
}
while (c.moveToNext());
}
if (c != null && !c.isClosed())
{
c.close();
ourDatabase.close();
}
return list.toArray(new String[]{});
}
}
}
**LogCat**
03-12 01:32:39.759: E/AndroidRuntime(4176): Caused by:java.lang.NullPointerException
03-12 01:32:39.759: E/AndroidRuntime(4176):
at com.example.parkangel.CarParkDb.getCpnames(CarParkDb.java:191)
03-12 01:32:39.759: E/AndroidRuntime(4176):
at com.example.parkangel.BookTicket.<init>(BookTicket.java:22)
03-12 01:32:39.759: E/AndroidRuntime(4176):
at java.lang.Class.newInstanceImpl(Native Method)
03-12 01:32:39.759: E/AndroidRuntime(4176):
at java.lang.Class.newInstance(Class.java:1208)
The database doesn't get locked. The "locked" thinkg is just a NPE in a method called getDatabaseLocked() and it's caused by a null Context passed to SQLiteOpenHelper in constructor that manifests itself with getWritableDatabase() or getReadableDatabase().
To fix the NPE in getDatabaseLocked(), make sure ourContext in open() is not null. As of now, you've never initialized ourContext and it's always null. Uncomment the //ourContext = c; in constructor and move it above the establishDb(), remove the other no-argument constructor and pass in a Context for example as suggested by Merlevede.
The NPE stacktrace in your question is when you call getCpNames() with open() commented out and are trying to call a method on a null ourDatabase object reference. Uncomment the open() there once it's fixed. The stacktrace also says you're trying to call getCpNames() in object initialization phase e.g. when initializing a member variable. That might be too early, for example an activity cannot be used as a Context until onCreate().
Some other things in your code you'd hit next:
in onCreate(): + KEY_COST + " TEXTNOT NULL) - add space between TEXT and NOT
in getData(): you're closing the cursor and database in the loop where you're accessing the cursor. Do it after the loop. The code shouldn't compile as you're not returning anything from a non-void function in case moveToFirst() returns false.
Try updating your getInstance() code with this:
public static CarParkDb getInstance(Context c) // <-- added context as parameter
{
synchronized(CarParkDb.class)
{
if (instance == null)
{
instance = new CarParkDb(c); // <-- used context in constructor
}
return instance;
}
}
The problem seems to be that you're using a constructor (for CarParkDb) that does nothing. You have another constructor that takes a Context as parameter and initializes some of the objects that you're using later.

Why am I getting "Attempt to invoke interface method 'int android.database.Cursor.getCount()' on a null object reference"? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
So I am getting
Attempt to invoke interface method 'int android.database.Cursor.getCount()' on a null object reference
when trying to get into my MovieDetailActivity to see MovieDetails with a Favourite Button. Based on the state of the movie (if it's favourited or not) the button should change its text accordingly to add or remove the movie to the favourites list.
But all I am getting is a crash when trying to entering the screen.
screenshot from the Logs
Here is my isMovieFavourited method:
public boolean isMovieFavourited(String id){
mSelectionClause = FavouritesContract.FavouritesAdd.COLUMN_MOVIE_ID + " = ?";
mSelectionArgs[0] = id;
Cursor mCursor = getContentResolver().query(
FavouritesContract.FavouritesAdd.CONTENT_URI,
mProjection,
mSelectionClause,
mSelectionArgs,
null);
if(mCursor.getCount() <= 0){
mCursor.close();
mFavourites.setText(getString(R.string.add_to_favourites));
return false;
}
mCursor.close();
mFavourites.setText(getString(R.string.remove_from_favourites));
return true;
}
Here is my FavouritesContract class:
public class FavouritesContract {
public static final String AUTHORITY = "com.riceplant.popularmovies";
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + AUTHORITY);
public static final String PATH_FAVOURITES = "favourites";
public static final class FavouritesAdd implements BaseColumns {
public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon()
.appendPath(PATH_FAVOURITES)
.build();
public static final String TABLE_NAME = "favorites";
public static final String COLUMN_MOVIE_ID = "movieId";
public static final String COLUMN_MOVIE_NAME = "movieName";
public static final String COLUMN_MOVIE_POSTER = "moviePoster";
public static final String COLUMN_MOVIE_RATE = "movieRate";
public static final String COLUMN_MOVIE_RELEASE = "movieRelease";
public static final String COLUMN_MOVIE_OVERVIEW = "movieOverview";
}
}
EDIT:
Here is my Content Provider class:
public class FavouritesContentProvide extends ContentProvider{
public static final int FAVOURITES = 700;
public static final int FAVOURITES_WITH_ID = 701;
private static final UriMatcher sUriMatcher = buildUriMatcher();
private static UriMatcher buildUriMatcher() {
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(FavouritesContract.AUTHORITY, FavouritesContract.PATH_FAVOURITES, FAVOURITES);
uriMatcher.addURI(FavouritesContract.AUTHORITY, FavouritesContract.PATH_FAVOURITES + "/#", FAVOURITES_WITH_ID);
return uriMatcher;
}
private FavouritesDbHelper mFavouritesDbHelper;
#Override
public boolean onCreate() {
Context context = getContext();
mFavouritesDbHelper = new FavouritesDbHelper(context);
return true;
}
#Nullable
#Override
public Cursor query(#NonNull Uri uri, #Nullable String[] projection, #Nullable String selection, #Nullable String[] selectionArgs, #Nullable String sortOrder) {
final SQLiteDatabase db = mFavouritesDbHelper.getReadableDatabase();
int match = sUriMatcher.match(uri);
Cursor returnCursor;
switch (match){
case FAVOURITES:
returnCursor = db.query(TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder);
break;
case FAVOURITES_WITH_ID:
String id = uri.getPathSegments().get(1);
String mSelection = "_id=?";
String[] mSelectionArgs = new String[]{id};
returnCursor = db.query(TABLE_NAME,
projection,
mSelection,
mSelectionArgs,
null,
null,
sortOrder);
break;
default:
throw new UnsupportedOperationException("Unknown uri: "+ uri);
}
returnCursor.setNotificationUri(getContext().getContentResolver(), uri);
return returnCursor;
}
#Nullable
#Override
public String getType(#NonNull Uri uri) {
int match = sUriMatcher.match(uri);
switch (match){
case FAVOURITES:
return "vnd.android.cursor.dir" + "/" + FavouritesContract.AUTHORITY + "/" + FavouritesContract.PATH_FAVOURITES;
case FAVOURITES_WITH_ID:
return "vnd.android.cursor.item" + "/" + FavouritesContract.AUTHORITY + "/" + FavouritesContract.PATH_FAVOURITES;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
}
#Nullable
#Override
public Uri insert(#NonNull Uri uri, #Nullable ContentValues values) {
final SQLiteDatabase db = mFavouritesDbHelper.getWritableDatabase();
int match = sUriMatcher.match(uri);
Uri returnUri; //Uri to be returned
switch (match){
case FAVOURITES:
long id = db.insert(TABLE_NAME, null, values);
if (id > 0 ){
returnUri = ContentUris.withAppendedId(FavouritesContract.FavouritesAdd.CONTENT_URI, id);
} else {
throw new android.database.SQLException("Failed to insert row into" + uri);
}
break;
default:
throw new UnsupportedOperationException("Unknow uri: " +uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return returnUri;
}
#Override
public int delete(#NonNull Uri uri, #Nullable String selection, #Nullable String[] selectionArgs) {
final SQLiteDatabase db = mFavouritesDbHelper.getWritableDatabase();
int match = sUriMatcher.match(uri);
int favoritesDeleted;
switch (match) {
case FAVOURITES:
favoritesDeleted = db.delete(TABLE_NAME, selection, selectionArgs);
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
if (favoritesDeleted != 0){
getContext().getContentResolver().notifyChange(uri,null);
}
return favoritesDeleted;
}
#Override
public int update(#NonNull Uri uri, #Nullable ContentValues values, #Nullable String selection, #Nullable String[] selectionArgs) {
int favoriteUpdated;
int match = sUriMatcher.match(uri);
switch (match){
case FAVOURITES_WITH_ID:
String id = uri.getPathSegments().get(1);
favoriteUpdated = mFavouritesDbHelper.getWritableDatabase()
.update(TABLE_NAME, values, "_id=?", new String[]{id});
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
if (favoriteUpdated != 0){
getContext().getContentResolver().notifyChange(uri, null);
}
return favoriteUpdated;
}
}
Here is the Dbhelper class:
public class FavouritesDbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "favourites.db";
private static final int DATABASE_VERSION = 3;
public FavouritesDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
final String SQL_CREATE_FAVOURITES_TABLE = "CREATE TABLE " +
FavouritesAdd.TABLE_NAME + " (" +
FavouritesAdd._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
FavouritesAdd.COLUMN_MOVIE_ID + " INTEGER NOT NULL," +
FavouritesAdd.COLUMN_MOVIE_NAME + " TEXT NOT NULL," +
FavouritesAdd.COLUMN_MOVIE_POSTER + " TEXT NOT NULL," +
FavouritesAdd.COLUMN_MOVIE_RATE + " TEXT NOT NULL," +
FavouritesAdd.COLUMN_MOVIE_RELEASE + " TEXT NOT NULL," +
FavouritesAdd.COLUMN_MOVIE_OVERVIEW + " TEXT NOT NULL" +
"); ";
sqLiteDatabase.execSQL(SQL_CREATE_FAVOURITES_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + FavouritesAdd.TABLE_NAME);
onCreate(sqLiteDatabase);
}
}
I am pretty new to this, so please don't hesitate to ask if you need more code samples or anything else.
Thanks in advance!
There are 3 circumstances where the ContentResolver.query method can return null (and yes it is documented that it can return null):
The Uri provider cannot be acquired.
The provider query returned null.
A RemoteException occurred executing the query.
(You can see for yourself in source of ContentResolver.java)
(2) seems unlikely given your code posted. (I glanced at it and it seems like a null result would not be possible - and in theory an SQLiteDatabase.query() can never return null and even if it did you'd get a null pointer at the setNotificationUri call which you didn't.)
(3) cannot comment based on info provided - most likely would mean your provider is accessed across a network or other link.
However
(1) Is worth investigating - does the URI provided actually define a configured provider. Specifically - did you define a <provider> element in your manifest file - reference here . If so then add that portion of the manifest to your post. Have you done anything with the provider successfully? If yes then perhaps the particular URI is not quite right.

How can I implement a query for SQLite in Android to account for blank letters?

I am writing an Android application that queries a database with 170,000 dictionary words. (It has 31 columns: _id, word, sortedWord, length, and count_A, count_B, count_C, ... count_Z)
Here is the code for my Dictionary database helper
public class DictionaryDbHelper extends SQLiteOpenHelper {
private static final String TAG = "DataBaseHelper";
// The Android's default system path of your application database.
private static String DB_PATH = "/data/data/com.rabbitfighter.wordsleuth/databases/";
// Database name
private static String DB_NAME = "dictionary.db";
// Database, and context
private SQLiteDatabase myDataBase;
private final Context myContext;
// Table name
public static final String TABLE_NAME = "dictionary";
// Table columns
public static final String UID = "_id";
// Word
public static final String COLUMN_NAME_WORD = "word";
// Length
public static final String COLUMN_NAME_WORD_LENGTH = "length";
// For all the letters, A-Z.
public static final String COLUMN_NAME_COUNT_A = "count_A";
public static final String COLUMN_NAME_COUNT_B = "count_B";
public static final String COLUMN_NAME_COUNT_C = "count_C";
public static final String COLUMN_NAME_COUNT_D = "count_D";
public static final String COLUMN_NAME_COUNT_E = "count_E";
public static final String COLUMN_NAME_COUNT_F = "count_F";
public static final String COLUMN_NAME_COUNT_G = "count_G";
public static final String COLUMN_NAME_COUNT_H = "count_H";
public static final String COLUMN_NAME_COUNT_I = "count_I";
public static final String COLUMN_NAME_COUNT_J = "count_J";
public static final String COLUMN_NAME_COUNT_K = "count_K";
public static final String COLUMN_NAME_COUNT_L = "count_L";
public static final String COLUMN_NAME_COUNT_M = "count_M";
public static final String COLUMN_NAME_COUNT_N = "count_N";
public static final String COLUMN_NAME_COUNT_O = "count_O";
public static final String COLUMN_NAME_COUNT_P = "count_P";
public static final String COLUMN_NAME_COUNT_Q = "count_Q";
public static final String COLUMN_NAME_COUNT_R = "count_R";
public static final String COLUMN_NAME_COUNT_S = "count_S";
public static final String COLUMN_NAME_COUNT_T = "count_T";
public static final String COLUMN_NAME_COUNT_U = "count_U";
public static final String COLUMN_NAME_COUNT_V = "count_V";
public static final String COLUMN_NAME_COUNT_W = "count_W";
public static final String COLUMN_NAME_COUNT_X = "count_X";
public static final String COLUMN_NAME_COUNT_Y = "count_Y";
public static final String COLUMN_NAME_COUNT_Z = "count_Z";
/**
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
* #param context
*/
public DictionaryDbHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
/* ------------------------ */
/* --- Override Methods --- */
/* ------------------------ */
/**
* On creation
* #param db - the database
*/
public void onCreate(SQLiteDatabase db) {
//Nothing to do here
}
/**
* On upgrade
* #param db - the database
* #param oldVersion - the old database version int
* #param newVersion - the new database version int
*/
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "Database " + db + " version " + oldVersion + " upgraded to " + newVersion);
}
/**
* On downgrade
* #param db - the database
* #param oldVersion - the old database version int
* #param newVersion - the new database version int
*/
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "Database " + db + " version " + oldVersion + " downgraded to " + newVersion);
}
/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException{
if(checkDataBase()){
//do nothing - database already exist
Log.i(TAG, "Database already exists... Nothing to do.");
}else{
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase();
Log.i(TAG, "Successfully copied database");
} catch (IOException e) {
Log.i(TAG, "Error copying");
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* #return true if it exists, false if it doesn't
*/
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
//database doesn't exist yet.
Log.i(TAG, "Database doesn't exist yet");
}
// Check for null db
if(checkDB != null){
checkDB.close();
Log.i(TAG, "Closed dict database");
}
// Return null or not null
return checkDB != null;
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException {
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the input file to the output file
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException {
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
#Override
public synchronized void close() {
if(myDataBase != null) {
Log.i(TAG, "Closing dictionary database");
myDataBase.close();
}
super.close();
}
/* -------------------------- */
/* --- Database retrieval --- */
/* -------------------------- */
/**
* Get the Anagrams in the database
* #return the number of anagrams
*/
public ArrayList<Result> getMatches(
// Params. Yeah, I know...
int count_A, int count_B, int count_C, int count_D, int count_E, int count_F,
int count_G, int count_H, int count_I, int count_J, int count_K, int count_L,
int count_M, int count_N, int count_O, int count_P, int count_Q, int count_R,
int count_S, int count_T, int count_U, int count_V, int count_W, int count_X,
int count_Y, int count_Z, int count_WILDCARDS
) {
// Get the database helper to get access to everything...
SQLiteDatabase db = this.getWritableDatabase();
// List to hold matches
ArrayList<Result> resultList = new ArrayList<>();
// Here are the columns we care about in our search
String[] columns = {
UID,
COLUMN_NAME_WORD,
COLUMN_NAME_WORD_LENGTH,
COLUMN_NAME_COUNT_A,
COLUMN_NAME_COUNT_B,
COLUMN_NAME_COUNT_C,
COLUMN_NAME_COUNT_D,
COLUMN_NAME_COUNT_E,
COLUMN_NAME_COUNT_F,
COLUMN_NAME_COUNT_G,
COLUMN_NAME_COUNT_H,
COLUMN_NAME_COUNT_I,
COLUMN_NAME_COUNT_J,
COLUMN_NAME_COUNT_K,
COLUMN_NAME_COUNT_L,
COLUMN_NAME_COUNT_M,
COLUMN_NAME_COUNT_N,
COLUMN_NAME_COUNT_O,
COLUMN_NAME_COUNT_P,
COLUMN_NAME_COUNT_Q,
COLUMN_NAME_COUNT_R,
COLUMN_NAME_COUNT_S,
COLUMN_NAME_COUNT_T,
COLUMN_NAME_COUNT_U,
COLUMN_NAME_COUNT_V,
COLUMN_NAME_COUNT_W,
COLUMN_NAME_COUNT_X,
COLUMN_NAME_COUNT_Y,
COLUMN_NAME_COUNT_Z,
};
String[] selectionArgs = null;
// The selection (WHERE ...)
String selection =
COLUMN_NAME_COUNT_A +"<="+ count_A + " AND " +
COLUMN_NAME_COUNT_B +"<="+ count_B + " AND " +
COLUMN_NAME_COUNT_C +"<="+ count_C + " AND " +
COLUMN_NAME_COUNT_D +"<="+ count_D + " AND " +
COLUMN_NAME_COUNT_E +"<="+ count_E + " AND " +
COLUMN_NAME_COUNT_F +"<="+ count_F + " AND " +
COLUMN_NAME_COUNT_G +"<="+ count_G + " AND " +
COLUMN_NAME_COUNT_H +"<="+ count_H + " AND " +
COLUMN_NAME_COUNT_I +"<="+ count_I + " AND " +
COLUMN_NAME_COUNT_J +"<="+ count_J + " AND " +
COLUMN_NAME_COUNT_K +"<="+ count_K + " AND " +
COLUMN_NAME_COUNT_L +"<="+ count_L + " AND " +
COLUMN_NAME_COUNT_M +"<="+ count_M + " AND " +
COLUMN_NAME_COUNT_N +"<="+ count_N + " AND " +
COLUMN_NAME_COUNT_O +"<="+ count_O + " AND " +
COLUMN_NAME_COUNT_P +"<="+ count_P + " AND " +
COLUMN_NAME_COUNT_Q +"<="+ count_Q + " AND " +
COLUMN_NAME_COUNT_R +"<="+ count_R + " AND " +
COLUMN_NAME_COUNT_S +"<="+ count_S + " AND " +
COLUMN_NAME_COUNT_T +"<="+ count_T + " AND " +
COLUMN_NAME_COUNT_U +"<="+ count_U + " AND " +
COLUMN_NAME_COUNT_V +"<="+ count_V + " AND " +
COLUMN_NAME_COUNT_W +"<="+ count_W + " AND " +
COLUMN_NAME_COUNT_X +"<="+ count_X + " AND " +
COLUMN_NAME_COUNT_Y +"<="+ count_Y + " AND " +
COLUMN_NAME_COUNT_Z +"<="+ count_Z;
String groupBy = null;
String having = null;
String orderBy = null;
// Query the database
Cursor cursor = db.query(
TABLE_NAME, // Table name
columns, // Columns
selection, // Selection
selectionArgs, // Selection arguments
groupBy, // Group by...
having, // having
orderBy // Order by
);
while (cursor.moveToNext()) {
int columnResult = cursor.getColumnIndex(COLUMN_NAME_WORD);
// Add the result to the list to return
resultList.add(new Result(cursor.getString(columnResult)));
}
cursor.close();
// Return the list
return resultList;
}
}//EOF
And here is where I query the Dictionary in another class:
How can I query for wildcards given my current setup? I am new to sql, so any suggestions would be greatly appreciated... I am looking for a parameter for the WHERE clause to allow for up to 2 wildcards, each of which could be anything from A-Z.
Here is an example of how i'm doing a lookup now, from my search service:
DictionaryDbHelper helper = DictionaryDbHelper(this);
ArrayList<Result> matches = helper.getMatches(
this.getQuery().getCount_A(), this.getQuery().getCount_B(),
this.getQuery().getCount_C(), this.getQuery().getCount_D(),
this.getQuery().getCount_E(), this.getQuery().getCount_F(),
this.getQuery().getCount_G(), this.getQuery().getCount_H(),
this.getQuery().getCount_I(), this.getQuery().getCount_J(),
this.getQuery().getCount_K(), this.getQuery().getCount_L(),
this.getQuery().getCount_M(), this.getQuery().getCount_N(),
this.getQuery().getCount_O(), this.getQuery().getCount_P(),
this.getQuery().getCount_Q(), this.getQuery().getCount_R(),
this.getQuery().getCount_S(), this.getQuery().getCount_T(),
this.getQuery().getCount_U(), this.getQuery().getCount_V(),
this.getQuery().getCount_W(), this.getQuery().getCount_X(),
this.getQuery().getCount_Y(), this.getQuery().getCount_Z(),0 // wildcards not in use yet
)

get mp3 files from path

I'm trying to get mp3 files from a folder path of my system to list it in my listView, but unfortunately there's always the same error. (java.lang.NullPointerException: Attempt to get length of null array)
class Mp3Filter implements FilenameFilter{
public boolean accept(File dir, String name){
return (name.endsWith(".mp3"));
}
}
private static final String SD_PATH = new String(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).toString());
public void searchForSongs() {
ListView listView;
listView = (ListView) findViewById(R.id.listView);
File f = new File(SD_PATH);
try {
if (f.listFiles(new Mp3Filter()).length > 0){
for (File file : f.listFiles(new Mp3Filter())){
list.add(file.getName());
}
}
}
catch(Exception e) {
textView2.setText(""+e);
return;
}
final ArrayAdapter songList = new ArrayAdapter(this, android.R.layout.simple_list_item_1, list);
listView.setAdapter(songList);
}
Here is your solution use the following code to Read the MP3 file from the Specific Folder..
First of all Create 1 Model class as Given Below, to GET and SET Files in list.
AudioModel.class
public class AudioModel {
String aPath;
String aName;
String aAlbum;
String aArtist;
public String getaPath() {
return aPath;
}
public void setaPath(String aPath) {
this.aPath = aPath;
}
public String getaName() {
return aName;
}
public void setaName(String aName) {
this.aName = aName;
}
public String getaAlbum() {
return aAlbum;
}
public void setaAlbum(String aAlbum) {
this.aAlbum = aAlbum;
}
public String getaArtist() {
return aArtist;
}
public void setaArtist(String aArtist) {
this.aArtist = aArtist;
}
}
Now We have our Model Class Now use the below code to Read the all MP3 files from your Folder.
This will return list of all MP3 Files with Music NAME, PATH, ARTIST, ALBUM and if you wants more detail please refer Media.Store.Audio doc..
https://developer.android.com/reference/android/provider/MediaStore.Audio.html
public List<AudioModel> getAllAudioFromDevice(final Context context) {
final List<AudioModel> tempAudioList = new ArrayList<>();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.Audio.AudioColumns.DATA, MediaStore.Audio.AudioColumns.ALBUM, MediaStore.Audio.ArtistColumns.ARTIST,};
Cursor c = context.getContentResolver().query(uri, projection, MediaStore.Audio.Media.DATA + " like ? ", new String[]{"%yourFolderName%"}, null);
if (c != null) {
while (c.moveToNext()) {
AudioModel audioModel = new AudioModel();
String path = c.getString(0);
String album = c.getString(1);
String artist = c.getString(2);
String name = path.substring(path.lastIndexOf("/") + 1);
audioModel.setaName(name);
audioModel.setaAlbum(album);
audioModel.setaArtist(artist);
audioModel.setaPath(path);
Log.e("Name :" + name, " Album :" + album);
Log.e("Path :" + path, " Artist :" + artist);
tempAudioList.add(audioModel);
}
c.close();
}
return tempAudioList;
}
To Read Files of Specific Folder, use below Query and write your folder name in Query..
Cursor c = context.getContentResolver().query(uri,
projection,
MediaStore.Audio.Media.DATA + " like ? ",
new String[]{"%yourFolderName%"}, // yourFolderName
null);
If you wants All Files of device use below Query..
Cursor c = context.getContentResolver().query(uri,
projection,
null,
null,
null);
Don't forget to add Storage Permission .. enjoy.

How to properly write SQLite update function with string comparison in the where cluse

I have a table with two columns first is date and the second is a counter. I do not have a primary key but the date acts as one. So my code checks if the current date exists in the table, if so it will only increment the counter other wise it will add a new entry. The existence of the current date is only possible at the last row. here is the code:
SQLiteOpenHelper implementation:
public class SqliteHelperInstance extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "app_stats";
public static final String TABLE_NAME = "day_stats";
public static final String COLUMN_DATE = "date";
public static final String COLUMN_CIGCOUNT = "cigcount";
public static final int DATABASE_VERSION = 1;
private static final String CREATE_DB = "create table " + TABLE_NAME + " ( " + COLUMN_DATE + " text, "
+ COLUMN_CIGCOUNT + " integer );";
public SqliteHelperInstance(Context context){
super(context,DATABASE_NAME , null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(CREATE_DB);
}
}
The implementation of database manager:
public class DbManager {
private SqliteHelperInstance sqlHelper;
private SQLiteDatabase database;
private String[] columns = { SqliteHelperInstance.COLUMN_DATE, SqliteHelperInstance.COLUMN_CIGCOUNT};
public DbManager(Context context){
sqlHelper = new SqliteHelperInstance(context);
}
public void addEntry(Calendar cal){
ContentValues values = new ContentValues();
String dateEntry = dateFormatter(cal);
Cursor cursor = database.query(SqliteHelperInstance.TABLE_NAME, null, null, null, null, null,
SqliteHelperInstance.COLUMN_DATE + " DESC LIMIT 1");
//check if the last entered date is equal to the current date
if(cursor.moveToFirst()){
String lastDate = cursor.getString(0);
if(lastDate.equalsIgnoreCase(dateEntry)){
//the cigNum should be updated for the current date
int cigNum = cursor.getInt(1);
cigNum ++;
values.put(SqliteHelperInstance.COLUMN_DATE,lastDate);
values.put(SqliteHelperInstance.COLUMN_CIGCOUNT, cigNum);
int i = database.update(SqliteHelperInstance.TABLE_NAME, values,SqliteHelperInstance.COLUMN_DATE + " = " + lastDate , null);
if(i == 0){
Log.d("Tag", "No row is affected");
}
}
else{
//the last date is different than current day so we need to add a new entry
DbEntry newEntry = new DbEntry();
newEntry.setDate(dateEntry);
values.put(SqliteHelperInstance.COLUMN_DATE, dateEntry);
values.put(SqliteHelperInstance.COLUMN_CIGCOUNT, newEntry.getCigNum());
database.insert(SqliteHelperInstance.TABLE_NAME, null, values);
}
}
else{
//its the first time that the application is loading
DbEntry newEntry = new DbEntry();
newEntry.setDate(dateEntry);
newEntry.setCignum(1);
values.put(SqliteHelperInstance.COLUMN_DATE, dateEntry);
values.put(SqliteHelperInstance.COLUMN_CIGCOUNT, newEntry.getCigNum());
Log.i(null, "values are set");
database.insert(SqliteHelperInstance.TABLE_NAME, null, values);
}
}
But when I run the application, I keep getting 0 row affected by the update function.I assume the comparison in the where clause is not returning any particular row. can anyone help me with this issue?
Try getting the lastDate like this:
String lastDate = cursor.getString(cursor.getColumnIndex(SqliteHelperInstance.COLUMN_DATE));
Also, you should use parameterized queries:
int i = database.update(SqliteHelperInstance.TABLE_NAME, values,SqliteHelperInstance.COLUMN_DATE + " = ?", new String[]{ lastDate });
Other than that, I'm not sure what could be wrong.

Categories

Resources