This is my project for Android. I've tried to create a new table column: KEY_EXAMPLE. But it doesn't work. I'll put my code below and I would like to fix this. Can someone help me, please? It's very important. I'm a newbie. The KEY_EXAMPLE doesn't work. This is my code and what I'm trying to do this workout.
DictionaryDatabase.Java
public class DictionaryDatabase {
private static final String TAG = "DictionaryDatabase";
public static final String KEY_WORD = SearchManager.SUGGEST_COLUMN_TEXT_1;
public static final String KEY_DEFINITION = SearchManager.SUGGEST_COLUMN_TEXT_2;
public static final String KEY_EXAMPLE = SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA;
private static final String DATABASE_NAME = "dictionary";
private static final String FTS_VIRTUAL_TABLE = "FTSdictionary";
private static final int DATABASE_VERSION = 3;
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(KEY_EXAMPLE, KEY_EXAMPLE);
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 +
KEY_EXAMPLE + ");";
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(), strings[2].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, String example) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_WORD, word);
initialValues.put(KEY_DEFINITION, definition);
initialValues.put(KEY_EXAMPLE, example);
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);
}
}
}
DictionaryProvider.Java
public class DictionaryProvider extends ContentProvider {
String TAG = "DictionaryProvider";
public static String AUTHORITY = "com.pesquisa.dicionario.searchabledict.DictionaryProvider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/dictionary");
public static final String WORDS_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE +
"/vnd.pesquisa.dicionario.searchabledict";
public static final String DEFINITION_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE +
"/vnd.pesquisa.dicionario.searchabledict";
private DictionaryDatabase mDictionary;
private static final int SEARCH_WORDS = 0;
private static final int GET_WORD = 1;
private static final int SEARCH_SUGGEST = 2;
private static final int REFRESH_SHORTCUT = 3;
private static final UriMatcher sURIMatcher = buildUriMatcher();
private static UriMatcher buildUriMatcher() {
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(AUTHORITY, "dictionary", SEARCH_WORDS);
matcher.addURI(AUTHORITY, "dictionary/#", GET_WORD);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT, REFRESH_SHORTCUT);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/*", REFRESH_SHORTCUT);
return matcher;
}
#Override
public boolean onCreate() {
mDictionary = new DictionaryDatabase(getContext());
return true;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
switch (sURIMatcher.match(uri)) {
case SEARCH_SUGGEST:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return getSuggestions(selectionArgs[0]);
case SEARCH_WORDS:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return search(selectionArgs[0]);
case GET_WORD:
return getWord(uri);
case REFRESH_SHORTCUT:
return refreshShortcut(uri);
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
}
private Cursor getSuggestions(String query) {
query = query.toLowerCase();
String[] columns = new String[] {
BaseColumns._ID,
DictionaryDatabase.KEY_WORD,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
return mDictionary.getWordMatches(query, columns);
}
private Cursor search(String query) {
query = query.toLowerCase();
String[] columns = new String[] {
BaseColumns._ID,
DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION,
DictionaryDatabase.KEY_EXAMPLE};
return mDictionary.getWordMatches(query, columns);
}
private Cursor getWord(Uri uri) {
String rowId = uri.getLastPathSegment();
String[] columns = new String[] {
DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION,
DictionaryDatabase.KEY_EXAMPLE};
return mDictionary.getWord(rowId, columns);
}
private Cursor refreshShortcut(Uri uri) {
String rowId = uri.getLastPathSegment();
String[] columns = new String[] {
BaseColumns._ID,
DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION,
DictionaryDatabase.KEY_EXAMPLE,
SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
return mDictionary.getWord(rowId, columns);
}
#Override
public String getType(Uri uri) {
switch (sURIMatcher.match(uri)) {
case SEARCH_WORDS:
return WORDS_MIME_TYPE;
case GET_WORD:
return DEFINITION_MIME_TYPE;
case SEARCH_SUGGEST:
return SearchManager.SUGGEST_MIME_TYPE;
case REFRESH_SHORTCUT:
return SearchManager.SHORTCUT_MIME_TYPE;
default:
throw new IllegalArgumentException("Unknown URL " + uri);
}
}
#Override
public Uri insert(Uri uri, ContentValues values) {
throw new UnsupportedOperationException();
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException();
}
#Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException();
}
}
SenseDictionary.Java (the Main Activity)
public class SenseDictionary extends Activity {
private TextView mTextView;
private ListView mListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
mTextView = (TextView) findViewById(R.id.text);
mListView = (ListView) findViewById(R.id.list);
handleIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Intent wordIntent = new Intent(this, WordActivity.class);
wordIntent.setData(intent.getData());
startActivity(wordIntent);
} else if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
showResults(query);
}
}
private void showResults(String query) {
Cursor cursor = managedQuery(DictionaryProvider.CONTENT_URI, null, null,
new String[] {query}, null);
if (cursor == null) {
mTextView.setText(getString(R.string.no_results, new Object[] {query}));
} else {
int count = cursor.getCount();
String countString = getResources().getQuantityString(R.plurals.search_results,
count, new Object[] {count, query});
mTextView.setText(countString);
String[] from = new String[] { DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION,
DictionaryDatabase.KEY_EXAMPLE};
int[] to = new int[] { R.id.word,
R.id.definition,
R.id.example};
SimpleCursorAdapter words = new SimpleCursorAdapter(this,
R.layout.result, cursor, from, to);
mListView.setAdapter(words);
mListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent wordIntent = new Intent(getApplicationContext(), WordActivity.class);
Uri data = Uri.withAppendedPath(DictionaryProvider.CONTENT_URI,
String.valueOf(id));
wordIntent.setData(data);
startActivity(wordIntent);
}
});
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search:
onSearchRequested();
return true;
default:
return false;
}
}
}
WordActivity
public class WordActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.word);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
Uri uri = getIntent().getData();
Cursor cursor = managedQuery(uri, null, null, null, null);
if (cursor == null) {
finish();
} else {
cursor.moveToFirst();
TextView word = (TextView) findViewById(R.id.word);
TextView definition = (TextView) findViewById(R.id.definition);
TextView example = (TextView) findViewById(R.id.example);
int wIndex = cursor.getColumnIndexOrThrow(DictionaryDatabase.KEY_WORD);
int dIndex = cursor.getColumnIndexOrThrow(DictionaryDatabase.KEY_DEFINITION);
int eIndex = cursor.getColumnIndexOrThrow(DictionaryDatabase.KEY_EXAMPLE);
word.setText(cursor.getString(wIndex));
definition.setText(cursor.getString(dIndex));
example.setText(cursor.getString(eIndex));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search:
onSearchRequested();
return true;
case android.R.id.home:
Intent intent = new Intent(this, SenseDictionary.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return false;
}
}
}
I would like to help you, but there are some issues.
First: You only posted the question an hour ago. In general, the stackoverflow community is not eagerly waiting for the next question to come in. You'll have to be patient.
Second: You've only posted your program. There may be someone out there who's willing to go through it step by step to figure out the problem, and I wish him or her luck, but I'd hesitate to do it. stackoverflow isn't my full-time job, so I can't spend 15-20 minutes just figuring out what (if anything) your program does.
It's not a simple program. You have a database, a content provider, and two activities.
Third: Your program doesn't have a single comment. Makes it even harder to debug.
Fourth: You said "I've tried to create a new table column: KEY_EXAMPLE. But it doesn't work." What happens? Why do you think it's not working? What do you expect it to do?
stackoverflow "works" when you have a specific question or problem that has you stumped. It works the worst when you ask, in essence, "fix my program for me".
Having said all this, I'll venture an off-the-wall guess: Did you run this app before and create a previous version of the database? If so, I don't see any place that you're deleting the previous version. You won't be able to create a new version, including the new column, until you delete the old version. You can do this in Settings > Apps > appname > Clear Data, or you can put it into the program itself.
Good luck!
Related
I'm building a searchView for my map, therefore I made the Locaionrovider Class extending ContentProvider and created AUTHORITY & CONTENT_UR in it.
in the SearchableLocation Activity I called CONTENT_UR but it gives this error:
cannot resolve CONTENT_URI
I tried to figure out the problem but didn't succeed.
Here's SearchableLocations:
public class SearchableLocations extends Activity {
private TextView mTextView;
private ListView mListView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search_main);
mTextView = (TextView) findViewById(R.id.text);
mListView = (ListView) findViewById(R.id.search_list);
handleIntent(getIntent());
}
protected void onNewIntent (Intent intent){
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Intent nameIntent= new Intent(this, NameActivity.class);
nameIntent.setData(intent.getData());
startActivity(nameIntent);
}else if (Intent.ACTION_SEARCH.equals(intent.getAction())){
String query = intent.getStringExtra(SearchManager.QUERY);
showResults(query);
}
}
#SuppressLint("StringFormatInvalid")
private void showResults (String query ){
Cursor cursor= getContentResolver().query(LocationProvider.CONTENT_URI,
null, null, new String[]{query}, null);
if (cursor ==null){
mTextView.setText(getString(R.string.noresult, new Object[]
{query}));
} else {
int count = cursor.getCount();
String countString = getResources().getQuantityString(
R.plurals.search_results,count, new Object[] {count,query}
);
mTextView.setText(countString);
String [] from = new String[] {
LocationDatabase.KET_NAME,
// LocationDatabase.KEY_LOCATION
};
int[] to = new int[]{
R.id.name,
// R.id.location
};
SimpleCursorAdapter names = new SimpleCursorAdapter(
this, R.layout.search_result, cursor, from, to
);
mListView.setAdapter(names);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent nameIntent = new Intent(getApplicationContext(),
NameActivity.class );
Uri data = Uri.withAppendedPath(LocationProvider.CONTENT_URI,
String.valueOf(id));
nameIntent.setData(data);
startActivity(nameIntent);
}
});
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
}
return true;
}
LocationProvider
public class LocationProvider extends ContentProvider {
String TAG="LocationProvider";
public static String AUTHORITY="com.playpersia.bicyclemap.LocationProvider";
public static final Uri CONTENT_URI =Uri.parse("content://" +AUTHORITY + "location");
// MIME types used for searching words or looking up a single location
public static final String LOCATION_MIME_TYPE= ContentResolver.CURSOR_DIR_BASE_TYPE +
"/vnd.com.playpersia.bicyclemap";
public static final String DEFINITION_MIME_TYPE =ContentResolver.CURSOR_DIR_BASE_TYPE +
"/vnd.com.playpersia.bicyclemap";
private LocationDatabase mLocation;
//UriMatcher
private static final int SEARCH_NAMES=0;
private static final int GET_NAMES=1;
private static final int SEARCH_SUGGEST=2;
private static final int REFRESH_SHORTCUT=3;
private static final UriMatcher sURIMATCHER= buildUriMatcher();
private static UriMatcher buildUriMatcher(){
UriMatcher matcher= new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(AUTHORITY , "location", SEARCH_NAMES);
matcher.addURI(AUTHORITY, "location/#", GET_NAMES);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY,SEARCH_SUGGEST);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY +
"/*", SEARCH_SUGGEST);
matcher.addURI(AUTHORITY,SearchManager.SUGGEST_URI_PATH_SHORTCUT,REFRESH_SHORTCUT);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT
+"/*", REFRESH_SHORTCUT);
return matcher;
}
#Override
public boolean onCreate() {
mLocation= new LocationDatabase(getContext());
return true;
}
#Nullable
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
switch (sURIMATCHER.match(uri))
{
case SEARCH_SUGGEST:
if (selectionArgs == null){
throw new IllegalArgumentException(
"selectionArgs nust be provided for the Uri:" + uri);
}
return getSuggestion(selectionArgs[0]);
case SEARCH_NAMES:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return search(selectionArgs[0]);
case GET_NAMES:
return getName(uri);
case REFRESH_SHORTCUT:
return refreshShortcut(uri);
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
}
private Cursor getSuggestion(String query) {
query=query.toLowerCase();
String[] columns = new String[]{
BaseColumns._ID,
LocationDatabase.KET_NAME,
LocationDatabase.KEY_LOCATION,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID
};
return mLocation.getNameMatches(query, columns);
}
private Cursor search (String query){
query=query.toLowerCase();
String[] columns = new String[]{
BaseColumns._ID,
LocationDatabase.KET_NAME,
LocationDatabase.KEY_LOCATION,
};
return mLocation.getNameMatches(query, columns);
Have you registered your content provider in your Manifest?
You should end up with something similar:
<provider android:name=".LocationProvider"
android:authorities="${applicationId}.LocationProvider"
android:exported="false"
android:label="#string/provider_locations" />
Change name and authorities properties accordingly with your app if needed
it's the first time I'm using the content provider.
so I have this:
public class ContactsContentProvider extends ContentProvider {
private ContactsDatabaseHelper dbHelper;
private static final UriMatcher uriMatcher =
new UriMatcher(UriMatcher.NO_MATCH);
private static final int ONE_CONTACT = 1;
private static final int CONTACTS = 2;
private static final int CONTACT = 3;
static {
uriMatcher.addURI(ContactsDatabaseDescription.AUTHORITY,
Contact.TABLE_NAME + "/#", ONE_CONTACT);
uriMatcher.addURI(ContactsDatabaseDescription.AUTHORITY,
Contact.TABLE_NAME, CONTACTS);
uriMatcher.addURI(ContactsDatabaseDescription.AUTHORITY,
Contact.TABLE_NAME + "/*" , CONTACT);
}
#Override
public boolean onCreate() {
dbHelper = new ContactsDatabaseHelper(getContext());
return true;
}
#Override
public String getType(Uri uri) {
return null;
}
#Override
public Cursor query(Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(Contact.TABLE_NAME);
switch (uriMatcher.match(uri)) {
case ONE_CONTACT:
queryBuilder.appendWhere(
Contact._ID + "=" + uri.getLastPathSegment());
break;
case CONTACTS:
break;
default:
throw new UnsupportedOperationException(
getContext().getString(R.string.invalid_query_uri) + uri);
}
Cursor cursor = queryBuilder.query(dbHelper.getReadableDatabase(),
projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
// insert a new contact in the database
#Override
public Uri insert(Uri uri, ContentValues values) {
Uri newContactUri = null;
switch (uriMatcher.match(uri)) {
case CONTACTS:
// insert the new contact--success yields new contact's row id
long rowId = dbHelper.getWritableDatabase().insert(
Contact.TABLE_NAME, null, values);
if (rowId > 0) {
newContactUri = Contact.buildContactUri(rowId);
getContext().getContentResolver().notifyChange(uri, null);
}
else
throw new SQLException(
getContext().getString(R.string.insert_failed) + uri);
break;
default:
throw new UnsupportedOperationException(
getContext().getString(R.string.invalid_insert_uri) + uri);
}
return newContactUri;
}
#Override
public int update(Uri uri, ContentValues values,
String selection, String[] selectionArgs) {
int numberOfRowsUpdated; // 1 if update successful; 0 otherwise
switch (uriMatcher.match(uri)) {
case ONE_CONTACT:
String id = uri.getLastPathSegment();
numberOfRowsUpdated = dbHelper.getWritableDatabase().update(
Contact.TABLE_NAME, values, Contact._ID + "=" + id,
selectionArgs);
break;
default:
throw new UnsupportedOperationException(
getContext().getString(R.string.invalid_update_uri) + uri);
}
if (numberOfRowsUpdated != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return numberOfRowsUpdated;
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int numberOfRowsDeleted;
switch (uriMatcher.match(uri)) {
case ONE_CONTACT:
String id = uri.getLastPathSegment();
numberOfRowsDeleted = dbHelper.getWritableDatabase().delete(
Contact.TABLE_NAME, Contact._ID + "=" + id, selectionArgs);
break;
default:
throw new UnsupportedOperationException(
getContext().getString(R.string.invalid_delete_uri) + uri);
}
if (numberOfRowsDeleted != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return numberOfRowsDeleted;
}
}
My database is
public class ContactsDatabaseDescription {
public static final String AUTHORITY =
"com.example.afran.bdcontacts.data";
private static final Uri BASE_CONTENT_URI =
Uri.parse("content://" + AUTHORITY);
public static final class Contact implements BaseColumns {
public static final String TABLE_NAME = "contacts"; // table's name
public static final Uri CONTENT_URI =
BASE_CONTENT_URI.buildUpon().appendPath(TABLE_NAME).build();
public static final String COLUMN_FIRST_NAME = "firstName";
public static final String COLUMN_LAST_NAME = "lastName";
public static final String COLUMN_EMAIL = "email";
public static final String COLUMN_TYPE = "type";
public static Uri buildContactUri(long id) {
return ContentUris.withAppendedId(CONTENT_URI, id);
}
}
}
and on this fragment I read one last name (search) and I want to find the contact and I do not know how
public class DetailFragment extends Fragment
implements LoaderManager.LoaderCallbacks<Cursor> {
public interface DetailFragmentListener {
void onContactDeleted();
void onEditContact(Uri contactUri);
}
private static final int CONTACT_LOADER = 0;
private DetailFragmentListener listener;
private Uri contactUri;
private TextView prenomTextView;
private TextView nomTextView;
private TextView emailTextView;
private TextView typeTextView;
#Override
public void onAttach(Context context) {
super.onAttach(context);
listener = (DetailFragmentListener) context;
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
setHasOptionsMenu(true);
Bundle arguments = getArguments();
if (arguments != null)
contactUri = arguments.getParcelable(MainActivity.CONTACT_URI);
View view =
inflater.inflate(R.layout.fragment_detail, container, false);
prenomTextView = (TextView) view.findViewById(R.id.firstNameTextView);
nomTextView = (TextView) view.findViewById(R.id.lastNameTextView);
emailTextView = (TextView) view.findViewById(R.id.emailTextView);
typeTextView = (TextView) view.findViewById(R.id.typeTextView);
getLoaderManager().initLoader(CONTACT_LOADER, null, this);
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_main, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_edit:
listener.onEditContact(contactUri);
return true;
case R.id.action_delete:
deleteContact();
return true;
case R.id.action_search:
searchContact();
return true;
}
return super.onOptionsItemSelected(item);
}
private void searchContact() {
final EditText input = new EditText(getContext());
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.menuitem_recherche);
builder.setMessage(R.string.label_lastName);
builder.setView(input);
builder.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString();
return;
}
});
builder.setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
return;
}
});
builder.create().show();
}
private void deleteContact() {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.confirm_title);
builder.setMessage(R.string.confirm_message);
builder.setPositiveButton(R.string.button_delete, new DialogInterface.OnClickListener() {
#Override
public void onClick(
DialogInterface dialog, int button) {
getActivity().getContentResolver().delete(
contactUri, null, null);
listener.onContactDeleted();
}
}
);
builder.setNegativeButton(R.string.button_cancel, null);
builder.create().show();
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
CursorLoader cursorLoader;
switch (id) {
case CONTACT_LOADER:
cursorLoader = new CursorLoader(getActivity(),
contactUri,
null,
null,
null,
null);
break;
default:
cursorLoader = null;
break;
}
return cursorLoader;
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (data != null && data.moveToFirst()) {
int firstIndex = data.getColumnIndex(ContactsDatabaseDescription.Contact.COLUMN_FIRST_NAME);
int lastIndex = data.getColumnIndex(ContactsDatabaseDescription.Contact.COLUMN_LAST_NAME);
int emailIndex = data.getColumnIndex(ContactsDatabaseDescription.Contact.COLUMN_EMAIL);
int typeIndex = data.getColumnIndex(ContactsDatabaseDescription.Contact.COLUMN_TYPE);
prenomTextView.setText(data.getString(firstIndex));
nomTextView.setText(data.getString(lastIndex));
emailTextView.setText(data.getString(emailIndex));
typeTextView.setText(data.getString(typeIndex));
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) { }
}
It is simple to search for a match of any column in your table. You simply need the contentUri, and where and whereArgs parameters for the query. Ensure your Uri points to the whole table. Assuming you want to match columns called "first_name" and "surname" with Strings called firstName and surname.
String where = "first_name =? and surname =?";
String[] whereArgs = {firstName, surname};
You can use parentheses and "and" and "or" to construct more complex queries. With numerical fields you can use > and < etc. You must ensure whereArgs has as many elements as where has "?"
So I am trying to refresh a list fragment when an item is deleted. The way I have it right now restarts the loader which causes a stutter in the UI when the loader is actually restarting.
I am restarting the loader in the listViewLongClick() method.
Here is my code for the adapter and list fragment:
public class EntriesListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
private SimpleCursorAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_entries_list, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initButton();
fillData();
listViewLongClick()
}
private void listViewLongClick() { assignmentsListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, final View view, int i, long l) {
String entryId = ((TextView) view.findViewById(R.id.assignment_id)).getText().toString();
Uri uri = ElicitContract.Assignments.buildAssignmentIdUri(assignmentId);
mContentResolver.delete(uri, null, null);
getLoaderManager().restartLoader(0, null, AssignmentsListFragment.this);
fillData();
return true;
});
}
private void fillData() {
String[] from = new String[]{EntriesContract.EntriesColumns.ENTRIES_TITLE, EntriesContract.EntriesColumns.ENTRIES_DETAIL};
int[] to = new int[]{R.id.entries_title, R.id.entries_description};
getLoaderManager().initLoader(0, null, this);
adapter = new SimpleCursorAdapter(getActivity(), R.layout.custom_entries, null, from, to, 0);
setListAdapter(adapter);
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = {EntriesContract.EntriesColumns.ENTRIES_ID, EntriesContract.EntriesColumns.ENTRIES_TITLE, EntriesContract.EntriesColumns.ENTRIES_DETAIL};
CursorLoader cursorLoader = new CursorLoader(getActivity(), EntriesContract.ENTRIES_BASE_CONTENT_URI, projection, null, null, null);
return cursorLoader;
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
#Override
public void onResume() {
super.onResume();
fillData();
}
}
Here is my content provider code:
public class ElicitProvider extends ContentProvider {
private static final String TAG = ElicitProvider.class.getSimpleName();
private EntriesDatabase entriesDatabase; // Get a copy of the database.
private static final UriMatcher sUriMatcher = buildUriMatcher();
private static final int ENTRIES = 1;
private static final int ENTRIES_ID = 2;
private static UriMatcher buildUriMatcher() {
final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
final String authority = EntriesContract.CONTENT_AUTHORITY;
matcher.addURI(authority, "entries", ENTRIES);
matcher.addURI(authority, "entries/*", ENTRIES_ID);
return matcher;
}
#Override
public boolean onCreate() {
entriesDatabase = new EntriesDatabase(getContext()); // Creating a new instance of the Elicit Database.
return true;
}
#Override
public String getType(Uri uri) {
final int match = sUriMatcher.match(uri);
switch (match) {
case ENTRIES:
return EntriesContract.Entries.CONTENT_ENTRIES_TYPE;
case ENTRIES_ID:
return EntriesContract.Entries.CONTENT_ENTRIES_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
}
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
final SQLiteDatabase db = entriesDatabase.getReadableDatabase();
final int match = sUriMatcher.match(uri);
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(EntriesContract.ENTRIES_PATH);
switch (match) {
case ENTRIES:
break;
case ENTRIES_ID:
String id = EntriesContract.Entries.getEntryId(uri);
queryBuilder.appendWhere(BaseColumns._ID + "=" + id);
break;
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
return cursor;
}
#Override
public Uri insert(Uri uri, ContentValues contentValues) {
final SQLiteDatabase db = entriesDatabase.getWritableDatabase();
final int match = sUriMatcher.match(uri);
long recordId;
switch (match) {
case ENTRIES:
recordId = db.insertOrThrox(EntriesDatabase.Tables.ENTRIES, null, contentValues);
return EntriesContract.Entxies.buildentryIdUri(String.valueOf(recordId));
default:
throw new IllegalArgumentEception("Unknown Uri: " + uri);
}
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
if (uri.equals(EntriesContract.BASE_CONTENT_URI)) {
deleteDatabase();x
return 0;
}
final SQLiteDatabase db = entriesDatabase.getWritableDatabase();
final int match = sUriMatcher.match(uri);
switch (match) {
case ENTRIES_ID:
String id = uri.getLastPathSegment();
String selectionCriteria = BaseColumns._ID + "=" + id + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ")" : "");
return db.delete(EntriesDatabase.Tables.ENTRIES, selectionCriteria, selectionArgs);
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
}
#Override
public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) {
final SQLiteDatabase db = entriesDatabase.getWritableDatabase();
final int match = sUriMatcher.match(uri);
String selectionCriteria = selection;
switch (match) {
case ENTRIES:
break;
case ENTRIES_ID:
String id = EntriesContract.Entries.getentryId(uri);
selectionCriteria = BaseColumns._ID + "=" + id + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ")" : "");
break;
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
int updateCount = db.update(EntriesDatabase.Tables.ENTRIES, contentValues, selectionCriteria, selectionArgs);
return updateCount;
}
// Delete the instance of the database and create a new one
public void deleteDatabase() {
entriesDatabase.close();
EntriesDatabase.deleteDatabase(getContext());
entriesDatabase = new EntriesDatabase(getContext());
}
}
I am also thinking that this is not the most efficient method of refreshing a list fragment.
I took a look at other similar issues and they said to use entriesListView.notifyDataSetChanged() but I don't know where to put it and how to use it because if I replace this line with getLoaderManager().restartLoader then it gives me a null pointer error.
To summarize, my question is how would I dynamically refresh a listFragment without restarting the loader which I think is less efficient and causes a stutter in the UI.
Thank you to everyone in advance for helping me out!
I have followed the below tutorial http://www.vogella.de/articles/AndroidSQLite/article.htm
But getting this exception after clicking on "confirm" button
01-20 10:18:14.585: E/AndroidRuntime(2006): Caused by: java.lang.IllegalArgumentException: Unknown URL content://com.example.todos.contentprovider/todos
01-20 10:18:14.585: E/AndroidRuntime(2006): at android.content.ContentResolver.insert(ContentResolver.java:910)
01-20 10:18:14.585: E/AndroidRuntime(2006): at com.example.todos.TodoDetailActivity.saveState(TodoDetailActivity.java:122)
01-20 10:18:14.585: E/AndroidRuntime(2006): at com.example.todos.TodoDetailActivity.onPause(TodoDetailActivity.java:100)
TodoDetailActivity
public class TodoDetailActivity extends Activity {
private Spinner mCategory;
private EditText mTitleText;
private EditText mBodyText;
private Uri todoUri;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.todo_edit);
mCategory = (Spinner) findViewById(R.id.category);
mTitleText = (EditText) findViewById(R.id.todo_edit_summary);
mBodyText = (EditText) findViewById(R.id.todo_edit_description);
Button confirmButton = (Button) findViewById(R.id.todo_edit_button);
Bundle extras = getIntent().getExtras();
// check from the saved Instance
todoUri = (bundle == null) ? null : (Uri) bundle
.getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE);
// Or passed from the other activity
if (extras != null) {
todoUri = extras
.getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE);
fillData(todoUri);
}
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (TextUtils.isEmpty(mTitleText.getText().toString())) {
makeToast();
} else {
setResult(RESULT_OK);
finish();
}
}
});
}
private void fillData(Uri uri) {
String[] projection = { TodoTable.COLUMN_SUMMARY,
TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY };
Cursor cursor = getContentResolver().query(uri, projection, null, null,
null);
if (cursor != null) {
cursor.moveToFirst();
String category = cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_CATEGORY));
for (int i = 0; i < mCategory.getCount(); i++) {
String s = (String) mCategory.getItemAtPosition(i);
if (s.equalsIgnoreCase(category)) {
mCategory.setSelection(i);
}
}
mTitleText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_SUMMARY)));
mBodyText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_DESCRIPTION)));
// always close the cursor
cursor.close();
}
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState();
outState.putParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);
}
#Override
protected void onPause() {
super.onPause();
saveState();
}
private void saveState() {
String category = (String) mCategory.getSelectedItem();
String summary = mTitleText.getText().toString();
String description = mBodyText.getText().toString();
// only save if either summary or description
// is available
if (description.length() == 0 && summary.length() == 0) {
return;
}
ContentValues values = new ContentValues();
values.put(TodoTable.COLUMN_CATEGORY, category);
values.put(TodoTable.COLUMN_SUMMARY, summary);
values.put(TodoTable.COLUMN_DESCRIPTION, description);
if (todoUri == null) {
// New todo
todoUri = getContentResolver().insert(
MyTodoContentProvider.CONTENT_URI, values);
} else {
// Update todo
getContentResolver().update(todoUri, values, null, null);
}
}
private void makeToast() {
Toast.makeText(TodoDetailActivity.this, "Please maintain a summary",
Toast.LENGTH_LONG).show();
}
}
MyTodoContentProvider
public class MyTodoContentProvider extends ContentProvider{
//database
private TodoDatabaseHelper database;
//Used for the uriMatcher
private static final int TODOS = 10;
private static final int TODO_ID = 20;
private static final String AUTHORITY = "com.example.todos.contentprovider";
private static final String BASE_PATH = "todos";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY+ "/" + BASE_PATH);
public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE +"/todos";
public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/todo";
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
sURIMatcher.addURI(AUTHORITY, BASE_PATH, TODOS);
sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", TODO_ID);
}
#Override
public boolean onCreate()
{
database = new TodoDatabaseHelper(getContext());
return false;
}
#Override
public Cursor query(Uri uri,String[] projection, String selection,
String[] selectionArgs, String sortOrder)
{
// Uisng SQLiteQueryBuilder instead of query() method
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
// check if the caller has requested a column which does not exists
checkColumns(projection);
//set the table
queryBuilder.setTables(TodoTable.TABLE_TODO);
int uriType = sURIMatcher.match(uri);
switch (uriType) {
case TODOS:
break;
case TODO_ID:
// adding the ID to the original query
queryBuilder.appendWhere(TodoTable.COLUMN_ID + "="
+ uri.getLastPathSegment());
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
SQLiteDatabase db = database.getWritableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection,
selectionArgs, null, null, sortOrder);
// make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
#Override
public String getType(Uri uri) {
return null;
}
#Override
public Uri insert(Uri uri, ContentValues values)
{
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
long id = 0;
switch (uriType) {
case TODOS:
id = sqlDB.insert(TodoTable.TABLE_TODO, null, values);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_PATH + "/" + id);
}
#Override
public int delete(Uri uri, String selection,String[] selectionArgs)
{
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsDeleted = 0;
switch (uriType) {
case TODOS:
rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,selection, selectionArgs);
break;
case TODO_ID:
String id = uri.getLastPathSegment();
if(TextUtils.isEmpty(selection))
{
rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,TodoTable.COLUMN_ID + "=" + id,null);
}
else
{
rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,TodoTable.COLUMN_ID + "=" + id + "and" + selection ,selectionArgs);
}
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
#Override
public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs)
{
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDb = database.getWritableDatabase();
int rowsUpdated = 0;
switch (uriType) {
case TODOS:
rowsUpdated = sqlDb.update(TodoTable.TABLE_TODO, values, selection, selectionArgs);
break;
case TODO_ID:
String id = uri.getLastPathSegment();
if(TextUtils.isEmpty(selection))
{
rowsUpdated = sqlDb.update(TodoTable.TABLE_TODO, values, TodoTable.COLUMN_ID + "=" + id, null);
}
else
{
rowsUpdated = sqlDb.update(TodoTable.TABLE_TODO, values, TodoTable.COLUMN_ID + "=" + id + "and" + selection, selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
private void checkColumns(String[] projection)
{
String[] available = {TodoTable.COLUMN_CATEGORY,TodoTable.COLUMN_SUMMARY,TodoTable.COLUMN_DESCRIPTION,TodoTable.COLUMN_ID};
HashSet<String> requestedColumns = new HashSet<String>(Arrays.asList(projection));
HashSet<String> availableColumns = new HashSet<String>(Arrays.asList(available));
if(projection != null)
{
if (!availableColumns.containsAll(requestedColumns)) {
throw new IllegalArgumentException("Unknown columns in projection");
}
}
}
}
TodoDatabaseHelper
public class TodoDatabaseHelper extends SQLiteOpenHelper{
private static final String DATABASE_NAME = "todotable.db";
private static final int DATABASE_VERSION = 1;
public TodoDatabaseHelper(Context context)
{
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
//Method is called during creation of database
#Override
public void onCreate(SQLiteDatabase database)
{
TodoTable.onCreate(database);
}
// Method is called during an upgrade of the database,
// e.g. if you increase the database version
#Override
public void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion) {
TodoTable.onUpgrade(database, oldVersion, newVersion);
}
}
You are using
private static final String AUTHORITY = "com.example.todos.contentprovider";
// It should same as you defined in manifest
So this
Caused by: java.lang.IllegalArgumentException: Unknown URL content://com.example.todos.contentprovider/todos
So make sure you define your ContentProvider with same authority in manifest.xml
<provider
android:authorities="com.example.todos.contentprovider"
android:name=".YOUR_ContentProvider" >
</provider>
Hope this will work for you.
Also ensure that you give android:exported="true" in manifest.xml, also ensure they are placed inside </application> not inside </activity>.
<provider
android:name="com.example.todos.contentprovider"
android:authorities="com.example.todos.contentprovider.MyTodoContentProvider"
android:exported="true">
</provider>
Hi, Everybody. I think almost everyone knows "searchable dictionary" android sample project. My question is: how can I show the list of words from definitions.txt on main screen?
Everybody knows if one of us click on search button it shows part of the entries from database. I would like to show all entries in ListView on Main Activity.
I'm a newbie. Can someone help me??? Thanks!
DictionaryDatabase.Java
public class WordActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.word);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
Uri uri = getIntent().getData();
Cursor cursor = managedQuery(uri, null, null, null, null);
if (cursor == null) {
finish();
} else {
cursor.moveToFirst();
TextView word = (TextView) findViewById(R.id.word);
TextView definition = (TextView) findViewById(R.id.definition);
int wIndex = cursor.getColumnIndexOrThrow(DictionaryDatabase.KEY_WORD);
int dIndex = cursor.getColumnIndexOrThrow(DictionaryDatabase.KEY_DEFINITION);
word.setText(cursor.getString(wIndex));
definition.setText(cursor.getString(dIndex));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search:
onSearchRequested();
return true;
case android.R.id.home:
Intent intent = new Intent(this, SenseDictionary.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return false;
}
}
}
DictionaryProvider.Java
public class DictionaryProvider extends ContentProvider {
String TAG = "DictionaryProvider";
public static String AUTHORITY = "com.pesquisa.dicionario.searchabledict.DictionaryProvider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/dictionary");
public static final String WORDS_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE +
"/vnd.pesquisa.dicionario.searchabledict";
public static final String DEFINITION_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE +
"/vnd.pesquisa.dicionario.searchabledict";
private DictionaryDatabase mDictionary;
private static final int SEARCH_WORDS = 0;
private static final int GET_WORD = 1;
private static final int SEARCH_SUGGEST = 2;
private static final int REFRESH_SHORTCUT = 3;
private static final UriMatcher sURIMatcher = buildUriMatcher();
private static UriMatcher buildUriMatcher() {
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(AUTHORITY, "dictionary", SEARCH_WORDS);
matcher.addURI(AUTHORITY, "dictionary/#", GET_WORD);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT, REFRESH_SHORTCUT);
matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/*", REFRESH_SHORTCUT);
return matcher;
}
#Override
public boolean onCreate() {
mDictionary = new DictionaryDatabase(getContext());
return true;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
switch (sURIMatcher.match(uri)) {
case SEARCH_SUGGEST:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return getSuggestions(selectionArgs[0]);
case SEARCH_WORDS:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return search(selectionArgs[0]);
case GET_WORD:
return getWord(uri);
case REFRESH_SHORTCUT:
return refreshShortcut(uri);
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
}
private Cursor getSuggestions(String query) {
query = query.toLowerCase();
String[] columns = new String[] {
BaseColumns._ID,
DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
return mDictionary.getWordMatches(query, columns);
}
private Cursor search(String query) {
query = query.toLowerCase();
String[] columns = new String[] {
BaseColumns._ID,
DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION};
return mDictionary.getWordMatches(query, columns);
}
private Cursor getWord(Uri uri) {
String rowId = uri.getLastPathSegment();
String[] columns = new String[] {
DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION};
return mDictionary.getWord(rowId, columns);
}
private Cursor refreshShortcut(Uri uri) {
String rowId = uri.getLastPathSegment();
String[] columns = new String[] {
BaseColumns._ID,
DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION,
SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID};
return mDictionary.getWord(rowId, columns);
}
#Override
public String getType(Uri uri) {
switch (sURIMatcher.match(uri)) {
case SEARCH_WORDS:
return WORDS_MIME_TYPE;
case GET_WORD:
return DEFINITION_MIME_TYPE;
case SEARCH_SUGGEST:
return SearchManager.SUGGEST_MIME_TYPE;
case REFRESH_SHORTCUT:
return SearchManager.SHORTCUT_MIME_TYPE;
default:
throw new IllegalArgumentException("Unknown URL " + uri);
}
}
#Override
public Uri insert(Uri uri, ContentValues values) {
throw new UnsupportedOperationException();
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException();
}
#Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException();
}
}
SenseDictionary.Java
public class SenseDictionary extends Activity {
private TextView mTextView;
private ListView mListView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextView = (TextView) findViewById(R.id.text);
mListView = (ListView) findViewById(R.id.list);
handleIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
Intent wordIntent = new Intent(this, WordActivity.class);
wordIntent.setData(intent.getData());
startActivity(wordIntent);
} else if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
showResults(query);
}
}
private void showResults(String query) {
Cursor cursor = managedQuery(DictionaryProvider.CONTENT_URI, null, null,
new String[] {query}, null);
if (cursor == null) {
mTextView.setText(getString(R.string.no_results, new Object[] {query}));
} else {
int count = cursor.getCount();
String countString = getResources().getQuantityString(R.plurals.search_results,
count, new Object[] {count, query});
mTextView.setText(countString);
String[] from = new String[] { DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION };
int[] to = new int[] { R.id.word,
R.id.definition };
SimpleCursorAdapter words = new SimpleCursorAdapter(this,
R.layout.result, cursor, from, to);
mListView.setAdapter(words);
mListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent wordIntent = new Intent(getApplicationContext(), WordActivity.class);
Uri data = Uri.withAppendedPath(DictionaryProvider.CONTENT_URI,
String.valueOf(id));
wordIntent.setData(data);
startActivity(wordIntent);
}
});
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search:
onSearchRequested();
return true;
default:
return false;
}
}
}
WordActivity.Java
public class WordActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.word);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
Uri uri = getIntent().getData();
Cursor cursor = managedQuery(uri, null, null, null, null);
if (cursor == null) {
finish();
} else {
cursor.moveToFirst();
TextView word = (TextView) findViewById(R.id.word);
TextView definition = (TextView) findViewById(R.id.definition);
int wIndex = cursor.getColumnIndexOrThrow(DictionaryDatabase.KEY_WORD);
int dIndex = cursor.getColumnIndexOrThrow(DictionaryDatabase.KEY_DEFINITION);
word.setText(cursor.getString(wIndex));
definition.setText(cursor.getString(dIndex));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search:
onSearchRequested();
return true;
case android.R.id.home:
Intent intent = new Intent(this, SenseDictionary.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return false;
}
}
}
Run a the Stream and give it path to textfile.
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) {
reader.toString();
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.");
}
after that if you want your own words to display, change the contents of the definitions.txt file , located in Layout/raw folder.