how to get the saved words in android dictionary - android

I'm developing an app that can add words to UserDictionary and query from it.
when running the app on tablet device it work fine.
but when running it on non tablet device
and save an auto corrected word to my word list and query for it, it didn't retrieve the words.
so what I should to do to query and select all saved auto corrected word.
// this to add word to dictionary
Uri dic = UserDictionary.Words.CONTENT_URI;
UserDictionary.Words.addWord(this, "word", 100, UserDictionary.Words.LOCALE_TYPE_ALL);
// this to query
Uri dic = UserDictionary.Words.CONTENT_URI;
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(dic, null, null, null, null);
while (cursor.moveToNext()){
String word = cursor.getString(cursor.getColumnIndex(UserDictionary.Words.WORD));
int id = cursor.getInt(cursor.getColumnIndex(UserDictionary.Words._ID));
String app = cursor.getString(cursor.getColumnIndex(UserDictionary.Words.APP_ID));
int frequency = cursor.getInt(cursor.getColumnIndex(UserDictionary.Words.FREQUENCY));
String locale = cursor.getString(cursor.getColumnIndex(UserDictionary.Words.LOCALE));
Log.i("", "word: "+word+"\nId: "+id+"\nAppID: "+app+"\nfrequency: "+frequency+"\nLocale: "+locale);
}

To add a word, the Javadoc suggests using UserDicrionary.Words.addWord.
To use the spellcheker, above Android 4.0, there's a framework, along with a few examples of its use. Hope these help.

Related

How to get the base alphabet of a foreign word and sort them accordingly like in device local contact?

For example, let's say that a local contact have multiple Japanese contacts with the name たなか, つなき, and てるてる. In the local contact these names will be sorted under the section index letter た.
For what I've read, it is possible to sort them via collate, but how do you sort them to index た or even know that they should go to the た index?
Thank you.
The API has a trick for returning that list of alphabet letters, and optionally also including counts per character.
See official docs for EXTRA_ADDRESS_BOOK_INDEX:
https://developer.android.com/reference/android/provider/ContactsContract.Contacts.html#EXTRA_ADDRESS_BOOK_INDEX
Example code:
Uri uri = Contacts.CONTENT_URI.buildUpon()
.appendQueryParameter(Contacts.EXTRA_ADDRESS_BOOK_INDEX, "true")
.build();
Cursor cursor = getContentResolver().query(uri,
new String[] {Contacts.DISPLAY_NAME},
null, null, null);
Bundle bundle = cursor.getExtras();
if (bundle.containsKey(Contacts.EXTRA_ADDRESS_BOOK_INDEX_TITLES) && bundle.containsKey(Contacts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS)) {
String sections[] = bundle.getStringArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
// sections will now contain an array of characters that represent the first letter of each available contact name
// optionally - if you need counts per letter - int counts[] = bundle.getIntArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
}

Android: performance cost of content provider queries within queries

Writing this on the fly, so I apologize for the code sample. This is NOT real code, it's something I wrote in a plain text editor on the fly. No compile checking, couldn't remember all the exact class and method names, etc. It's just a written concept of what I'm trying to do, I'm looking for feedback on the broader concepts.
I'm working on retrieving a list of contacts from the content provider. I want to be able to filter the results based on the contact's account name. the user will be presented with all available accounts, and will select which ones are to be used, and then that will be used in the retrieval method.
The thing is, the account name is in RawContacts, and the rest of the info I want (display name, lookupID) is in Contacts. I know that ContactsContract.Contacts.Entity is the shortcut to access all of this, so this code sample is what I'm planning to do.
Again, this is written on the fly with no IDE or looking up methods or anything. I'm sure my syntax is bad in many places, but this shows the concept I'm trying to do.
private static final URI URI = ContactsContract.Contacts.URI;
private static final String[] FIRST_PROJECTION = new String[]{
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.LOOKUP_KEY
};
private String[] acceptedAccountNames = {Accepted Account Names Will Go Here (dynamic)};
private static final String[] SECOND_PROJECTION = new String[]{
ContactsContract.Contacts.Entity.ACCOUNT_NAME //This is whatever the entity -> RawContacts field name would be
};
public List<Contact> loadContacts(Context context){
List<Contact> contacts = new ArrayList<>();
ContentProvider provider = context.getContentProvider();
Cursor contactsCursor = provider.query(URI, FIRST_PROJECTION, null, null);
contactsCursor.movetoFirst();
while(!contactsCursor.isAtLast()){
String name = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
long lookupKey = contactsCursor.getLong(contactsCursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri idUri = Uri.makeWithId(URI, lookupKey);
Uri entityUri = Uri.makeWithTableName(idUri, "entity");
Cursor contactEntityCursor = provider.query(entityUri, SECOND_PROJECTION, null, null);
contactEntityCursor.moveToFirst();
String accountName = contactEntityCursor.getString(contactEntityCursor.getColumnIndex(ContactsContract.Contacts.Entity.ACCOUNT_NAME));
if(Arrays.asList(acceptedAccountNames).contains(accountName)){
Contact contact = new Contact(lookupKey, name);
contacts.add(contact);
}
contactsCursor.moveToNext();
}
return contacts;
}
As you can see, I create a cursor while looping over another cursor. I'm essentially creating a new cursor for each contact in the list.
My question is twofold:
1) What would be the performance implications of this? With a large enough list, would this severely hurt app performance?
2) Is there a better way to do this? As in, a way to do this in a single query, getting all the data I'm looking for in the cursor.
Thanks so much in advance.

compare phone number in android contacts database

I have a phone number with country code like +91XXXXXXXXXX. and a phone number in my android contacts database is in the form of XX XX XXXXXX. How to compare them in sqlite database query.
Any help would be appreciable....
I need this to update or delete the existing phone number in android database.
Note
Phone number can be of any country. Above is just the example.
you can try the code below
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode("Pass phone number here"));
Cursor c = getContentResolver().query(uri, new String[]{PhoneLookup.NUMBER}, null, null, null);
if(c.getCount()>0){
c.moveToFirst();
System.out.println(c.getString(c.getColumnIndex(PhoneLookup.NUMBER)));
}
c.close();
There can be multiple ways to do this:
As you see below here:
String yourInputString = "+91XXXXXXXXXX";
String dbContactString = "XX XX XXXXXX";
both have different format; so we must have to extract substring ("XXXXXXXXXX") from first string and also have to remove whitespaces ("XXXXXXXXXX") from the second string!
yourInputString = yourInputString.substring(2); // 2 is start index and result will be "XXXXXXXXXX"
dbContactString = dbContactString.replaceAll("\\s+",""); // replaces all whitespaces and result will be "XXXXXXXXXX"
now, both have same format so you can easily compare them with equals().
yourInputString.equals(dbContactString) is the way.
It returns true if yourInputString is equals to dbContactString in value. Else, it will return false.
Hope this helps!

Get Android contacts with type-to-filter functionality, restricted to a specific account

I'm trying to:
Display a list of contacts
Let the user search through them by typing a query
Limit search results only to a specific Google/Gmail account.
This is how I build the URI for the cursor:
// User is searching for 'jo'
String query = "jo";
Uri uri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(query));
// Restrict the query to contacts from 'example#gmail.com'
Uri.Builder builder = uri.buildUpon();
builder.appendQueryParameter(
ContactsContract.DIRECTORY_PARAM_KEY, String.valueOf(ContactsContract.Directory.DEFAULT));
builder.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, "example#gmail.com");
builder.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, "com.google");
uri = builder.build();
This is the final URI:
content://com.android.contacts/contacts/filter/jo?directory=0&account_name=example%40gmail.com&account_type=com.google
Currently, this shows search results from all accounts on the phone.
NOTE: If I use Contacts.CONTENT_URI instead of Contacts.CONTENT_FILTER_URI, then specifying the directory/account works as expected, but I can no longer use 'type-to-filter' style search.
The documentation does state:
The most important use case for Directories is search. A Directory
provider is expected to support at least Contacts.CONTENT_FILTER_URI.
Could anyone help point out what I might be doing wrong?
I added your code in Google's example for contact retrieving, and with a couple of changes it worked perfectly with my Google for Work account.
The changes I made were:
remove the line with DIRECTORY_PARAM_KEY, as I didn't find it to make any difference
removed ContactsQuery.SELECTION from the return statement, because that constant prevents "invisible" contacts from being displayed.
The changes were made to ContactsListFragment.java
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// If this is the loader for finding contacts in the Contacts Provider
// (the only one supported)
if (id == ContactsQuery.QUERY_ID) {
Uri contentUri;
// There are two types of searches, one which displays all contacts and
// one which filters contacts by a search query. If mSearchTerm is set
// then a search query has been entered and the latter should be used.
if (mSearchTerm == null) {
// Since there's no search string, use the content URI that searches the entire
// Contacts table
contentUri = ContactsQuery.CONTENT_URI;
} else {
// Since there's a search string, use the special content Uri that searches the
// Contacts table. The URI consists of a base Uri and the search string.
contentUri = Uri.withAppendedPath(ContactsQuery.FILTER_URI, Uri.encode(mSearchTerm));
}
// HERE COMES YOUR CODE (except the DIRECTORY_PARAM_KEY line)
Uri.Builder builder = contentUri.buildUpon();
builder.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, "example#mycompany.com");
builder.appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, "com.google");
contentUri = builder.build();
// Returns a new CursorLoader for querying the Contacts table. No arguments are used
// for the selection clause. The search string is either encoded onto the content URI,
// or no contacts search string is used. The other search criteria are constants. See
// the ContactsQuery interface.
return new CursorLoader(getActivity(),
contentUri,
ContactsQuery.PROJECTION,
null, // I REMOVED SELECTION HERE
null,
ContactsQuery.SORT_ORDER);
}
Log.e(TAG, "onCreateLoader - incorrect ID provided (" + id + ")");
return null;
}

Xamarin.Mobile Contacts API takes up a lot of time while fetching contacts?

I'm using Xamarin.Mobile Component for Android to fetch contacts using the code:
var book = new AddressBook (Activity) {PreferContactAggregation = true};
var contData = data.Data;
var cur = Activity.ManagedQuery (contData, null, null, null, null);
Contact myContact = null;
var lookupKeyList = new List<string> ();
while (cur.MoveToNext ()) {
lookupKeyList.Add (cur.GetString (cur.GetColumnIndexContactsContract.Contacts.InterfaceConsts.LookupKey)));
}
myContact = book.Where (c => c.Id == lookupKeyList [0]).First ();
This code is part of picking a contact from the phone book and receiving the data on OnActivityResult method.
Unfortunately, this code is taking up too much time on some devices and is instantaneous on others. I guess its related to Contact Aggregation but I am not sure. Any pointers?
Sounds like an Android issue, not necessarily a Xamarin issue. Take a look at the question Getting name and email from contact list is very slow. One of the things this answer does is use a Projection in the query to get all the columns in one go.

Categories

Resources