In my android app on 4.2.1 I want to create a contact with some read only fields. For example, the contact the app creates has a home phone number which is read only in the UI. I will create a separate account where all these contacts are created.
I was looking at the android documentation and understand that all these contact fields become part of the Data table. But I dont see any column which can make the field read only.
There isn't a way to do this. Apps that work with the Contacts Provider have to request permission to write to it. If the user grants this permission to the app, then it can write to the Contacts provider.
The only thing you can do is create your own MIME type for the Data table, encrypt the data, and store each piece of data in a row that has that MIME type. Other apps can still see your data, but they have no way of figuring out what it is.
The Contacts Provider is a public repository, and you have to use it according to the rules it provides.
Related
In my android application I would like to display the mobile user's contacts (names, profile picture ) displaying first the contacts that have already installed and registrered that application (the matching is made by contact's email).
Trying to loop over each contact and match if their email is already registered (in an external SQLITE table) don't seems to be an efficient way.
I would like to directly add (somewhere in the address book ?) the extra data "isRegistered = true/false) and order my addreess book query by this value to scroll the address book.
Is it possible? How to implement this in detail ?
OPTION 1
I think the most efficient way would be what you thought about initially, with a slight improvement:
store the list of registered emails (for the user's contacts) in a local SQLite DB.
read the entire list of emails on application launch, and store them in a HashSet
When sorting the contacts, create a custom Comparator to first check if the contact is an app user or not, and only then fallback to name compare.
OPTION 2
If you still want to check the option of storing the custom value in the Contacts DB, and integrate it into your query, you need to create a SyncAdapter.
This is basically a service that is able to sync contacts to/from a server into your own RawContact, which is then aggregated into one-or-more existing RawContacts, like Google does for Google Contacts.
You can set it to be notified when a new contact is added, and have your SyncAdapter add the needed info to the contact so it'll show links to your app.
If you go to your phone settings > accounts, you can see Whatsapp and Google's SyncAdapters there, where you can turn them off/on.
To create a sync adapter, you can follow the official docs, or this great tutorial.
Let me try and clarify my intentions.
I'm developing an app that accesses to the Android contacts provider. I have already implemented a mechanism for pulling contacts from the contacts provider and storing the results in an SQLite table. Currently, when I query for the results of a contact's _ID, I can retrieve all the data for that contact, phone numbers, email addresses, etc.
However, in order to specify which of those my app should use on future occasions, I have to store the resulting contact data (e.g. CommonDataKinds.Phone.NUMBER, CommonDataKinds.Phone.TYPE etc) in the SQL table.
This presents a problem if the data in the Android contacts provider has changed. One solution I have considered is to re-query the _ID and store the data that has changed. However, implementing such a solution requires gathering all data for that contact, making it difficult to determine the correct contact data to use.
My question is thus:
Is there a unique record key used in the Android Provider's contact data, in the same way as there is in the Provider's contact entry itself? A phone number or email address equivalent of Contact._ID?
Failing that, does the Android contacts provider store the last modified date and time? I'm hoping that if I can't reference the contact data in the provider, I can at least run a check to see if anything has changed since the contact was selected for use in the app, allowing my app to alert the user that the data has changed.
Yoi may use ContentObserver with the help of a service to monitor for contacts change or update.
for example-
extend contentObserver-
public class Contact_change extends ContentObserver
register contentobserver-
Contact_change changeObserver = new Contact_change();
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true,chageobserver);
By using this you can monitor for contact changes and update your database.
So while looking to see what was possible, I've come across some interesting findings by doing a localised record dump to my tablet.
I incorrectly referred to the phone _ID when asking my question. It's there, but it references individual records in any given contact. This might be useful, it might be exactly what I hoped, but it might also be a dead end.
So far, I've retrieved a contact using the Android Contacts Provider, which returns the contact's data including the fields that follow
ContactsContract.Contacts._ID
ContactsContract.Contacts.DISPLAY_NAME
After assigning the _ID to a String and using it in a query, I initially searched for the _ID in the ContactsContract.Data._ID field, which did not work as intended.
That's when I realised I was doing it wrong. I needed to apply the search to ContactsContract.Data.CONTACT_ID, which then retrieved all related data records for my selected contact.
Having corrected the error and re-ran my query, I found a series of records for the CONTACT_ID, each of which had its' own unique _ID (with the exception of photos and binary data, which all had a null reference to _ID instead.
Now the question is: Does this data reference change even if a phone number, email address or IM entry is modified, as opposed to deleted and re-created? I'll probably find out through further testing, but I wanted to ask if anyone had already tried this first.
Ultimately, I am hoping my internal SQL table can store only the CONTACT_ID and the _ID for each entry, relying on callbacks to the Android Provider to pull the relevant values. That way, I can be sure the data displayed in my app is up to date between the app and the stored contact data on the device.
Combined with the change notifier code provided here, I should be able to alert the user to any changes that may require action on their part.
Update:
More investigation reveals that the UID associated with a given contact entry is preserved through entry edits.
The UID is lost obviously on deletion, and in my brief testing, I have not found UID's being recycled. This solves a referential integrity issue for me at least, as that UID won't suddenly reference another record out of nowhere.
The upshot for anyone else wanting to reference individual entries in the Contacts Provider is that it's possible, and you can store only the _ID and still retrieve individual entries in the provider.
I want to add one field(column) to contact fields,that i can set value for that field in code and mobile user can not see that field in contact properties.In this way i can use contact information without create another database to copy contact database.
Is this possible?
please help me
I don't think you can modify the contacts database directly (or at least not without rooting the device first).
If you want to add additional information to a stored contact, I think your best option would be to actually create a new database. Just create a new table with columns [CONTACT_ID, YOUR_NEW_FIELD] and store that extra piece of information on the contact there. Also, that way you won't be polluting the contact's database with your app's proprietary information, which would have no meaning if the user removed your app.
I am interested in your opinions on the best way to keep a robust reference to a contact starting android 2.0. I have read a lot regarding this issue but i don't know which technique is advisable and if there's any new ones. Below are the 3 options i found so far:
1- Don't use your own db. Extend the contacts.contract to write your data
2 - Use ContentObserver to keep track of any changes made to the contacts. This technique would however require your application to be running
3- Store all RAW contact IDs related to a CONTACT_ID in your db and infer the content of the aggregate contact from all its constituent RAW contacts
In my case i need to keep a separate db and i was wondering if there's any other new technique of keeping the CONTACT_ID current after aggregations and dis-aggregations...
Please advise
I am playing with the new Contacts API at the moment, writing an app which is also a source of contact data. I can't recommend #3 at all. To get all of "my" contact data I simply store them with a magic value in the RawContacts.SYNC1 field and query the contacts content provider for that when my app starts up.
Re. your question, don't use CONTACT_IDs, as they are volatile. Use the lookup API, i.e. if you have a raw contact ID, use RawContacts.getContactLookupUri() to get to the Contact. Likewise if some API gives you a contact ID, use Contacts.getLookupUri() to get a persistent identifier you can use later on.
I'm pretty sure it's not viable to do what I'd like to based on some initial research, but I figured it couldn't hurt to ask the community of experts here in case someone knows a way.
I'd like to create a custom field for contacts that the user is able to edit from the main Contacts app; however, the user should only be allowed to select from a list of four specific values. A short list of string values would be ideal, but an int with a min/max range would suffice.
I'm interested in knowing if it's possible either way, but also wondering if it make sense to go this route performance wise. More specifically, would it be better to look up a contact (based on a phone number) each time a call or SMS message is received or better to store my own set of data (consisting of name, numbers, and the custom field) and just syncing contact info in a thread every so often? Or syncing contacts the first time the app is run and then registering for changes using ContentObserver?
Here is a similar question with an answer that explains how to add a custom field to a contact.
Thanks in advance.
I don't see the purpose to have your own set of data against contacts stored in your separate database, as you obviously will run into sync issues. You can use the mimetype and store whatever you want against the contact, in the manner you linked.
Whenever you want to looup contacts you can do that by using your custom mimetype. You get the contact id (from ContactsContract.Data.CONTENT_URI), and then you run another query to get the contact details (from ContactsContract.Contacts.CONTENT_URI). Please note these are different tables.
I'd like to create a custom field for contacts that the user is able to edit from the main Contacts app
I don't see that possible, editable from the main app, when you use your custom mimetypes, and you don't have much options here. The main contact app will display only the fields that are in SDK. You can store details against contacts but they won't show up in the inbuilt edit contact screen.