title: How to get Android device owner's user profile data using Xamarin/C#
body: <p>I'm building an app for Android 4.0 (Ice Cream Sandwich) and higher, and would like to get the device owner's user profile info such as:</p>
  
  <p>DisplayName, Email, Phone, Job Title, Company, Office Location, Website and Url</p>
  
  <p>I've tried different methods from different Stackoverflow posts that I read, including going to the phone's accounts to querying the user profile (ContactsContract.Profile.ContentUri). No dice. I've checked the permissions for ReadOwnerData and ReadProfile.</p>
  
  <p>Right now I'm querying the Contacts with this code, but the managed query is returning with a count of 0.</p>
  
  <pre><code>var c = act.ManagedQuery (ContactsContract.Profile.ContentUri, null, null, null, null);
  int count = c.Count;
  string[] columnNames = c.GetColumnNames();
  bool b = c.MoveToFirst();
  int position = c.Position;
  if (position == 0) {
      do {
          for (int j = 0; j &lt; columnNames.Length; j++) {
              string columnName = columnNames[j];
              try {
                  string columnValue = c.GetString(c.GetColumnIndex(columnName));
              } catch {}
              if (c.GetString(c.GetColumnIndex("is_user_profile")) == "1") {
                  if (c.GetString(c.GetColumnIndex("has_email")) == "1") {
                      //var cEmail = ManagedQuery (ContactsContract.Data.ContentUri, null, ContactsContract.Data.InterfaceConsts.HasPhoneNumber + "!=0 AND (" + ContactsContract.Data.InterfaceConsts.Mimetype + "=? OR " + ContactsContract.Data.InterfaceConsts.Mimetype + "=?)", new String[]{ ContactsContract.CommonDataKinds.Email.ContentItemType, ContactsContract.CommonDataKinds.Phone.ContentItemType, ContactsContract.Contacts.InterfaceConsts.Id }, null);
                      var cEmail = act.ManagedQuery (ContactsContract.CommonDataKinds.Email.ContentUri, null, ContactsContract.CommonDataKinds.Email.InterfaceConsts.Type + " = ?", new String[]{ c.GetString(c.GetColumnIndex(BaseColumns.Id)) }, null);
                      string[] columnNamesEmail = cEmail.GetColumnNames();
                      if (cEmail.Count &gt; 0) {
                          cEmail.MoveToFirst();
                          do {
                              sEmail = cEmail.GetString(cEmail.GetColumnIndex(ContactsContract.CommonDataKinds.Email.InterfaceConsts.Type));
                              //sEmail = cEmail.GetString(cEmail.GetColumnIndex(ContactsContract.CommonDataKinds.Email.InterfaceConsts.Data));
                              //sEmail = cEmail.GetString(cEmail.GetColumnIndex(ContactsContract.CommonDataKinds.Email.InterfaceConsts.ContactId));
                          } while (cEmail.MoveToNext());
                      }
                      cEmail.Close();
                  }
                  if (c.GetString(c.GetColumnIndex("has_phone_number")) == "1") {
                      var cPhone = act.ManagedQuery (ContactsContract.CommonDataKinds.Phone.ContentUri, null, ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId + " = ?", new String[]{ c.GetString(c.GetColumnIndex(BaseColumns.Id)) }, null);
                      string[] columnNamesPhone = cPhone.GetColumnNames();
                      if (cPhone.Count &gt; 0) {
                          cPhone.MoveToFirst();
                          do {
                              sPhone = cPhone.GetString(cPhone.GetColumnIndex(ContactsContract.CommonDataKinds.Phone.InterfaceConsts.Type));
                          } while (cPhone.MoveToNext());
                      }
                      cPhone.Close();
                  }
              }
          }
      } while (c.MoveToNext());
  }
  c.Close();
  </code></pre>
  
  <p>This part of the code returns with a count of 0:</p>
  
  <pre><code>if (cEmail.Count &gt; 0) {
  </code></pre>
  
  <p>Can someone point out how I can rewrite this query?</p>
  
  <pre><code>var cEmail = act.ManagedQuery (ContactsContract.CommonDataKinds.Email.ContentUri, null, ContactsContract.CommonDataKinds.Email.InterfaceConsts.Type + " = ?", new String[]{ c.GetString(c.GetColumnIndex(BaseColumns.Id)) }, null);
  </code></pre>
  
  <p>Or should I go back to querying the user profile or accounts? Here's the code I was using for them:</p>
  
  <p>Accounts:</p>
  
  <pre><code>Account[] accounts = AccountManager.Get (Context).GetAccounts ();
  foreach (Account acc in accounts) {
      --- can only get DisplayName and ID
  }
  </code></pre>
  
  <p>User Profile:</p>
  
  <pre><code>var uri = ContactsContract.Profile.ContentUri;
  
  string[] projection = { 
      ContactsContract.CommonDataKinds.StructuredName.DisplayName, 
      ContactsContract.CommonDataKinds.Email.Address,
      ContactsContract.CommonDataKinds.Phone.Number,
      ContactsContract.CommonDataKinds.Organization.Title,
      ContactsContract.CommonDataKinds.Organization.Company,
      ContactsContract.CommonDataKinds.Organization.OfficeLocation,
      ContactsContract.CommonDataKinds.Website.Url };
  
  var cursor = ManagedQuery (uri, projection, null, null, null);
  
  if (cursor.MoveToFirst ()) {
      do {
          sDisplayName = cursor.GetString (cursor.GetColumnIndex (projection [0]));
          sEmail = cursor.GetString (cursor.GetColumnIndex (projection [1]));
          sPhone = cursor.GetString (cursor.GetColumnIndex (projection [2]));
          sTitle = cursor.GetString (cursor.GetColumnIndex (projection [3]));
          sCompany = cursor.GetString (cursor.GetColumnIndex (projection [4]));
          sOfficeLocation = cursor.GetString (cursor.GetColumnIndex (projection [5]));
          sWebsite = cursor.GetString (cursor.GetColumnIndex (projection [6]));
  
  
      } while (cursor.MoveToNext());
  }
  </code></pre>