From f11e3dffcc047aeb24a206509566e8a190b7e336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com> Date: Wed, 21 Oct 2015 14:39:30 -0400 Subject: [PATCH] contacts: handle missing permission on Android 6.0 * Query permission status and request it if not granted * Every contact query handles permission denial case Tuleap: #31 Change-Id: I95944a74b0d7b8f29a2a85b9d5a97d321b177693 --- .../cx/ring/client/ConversationActivity.java | 23 +- .../java/cx/ring/client/HomeActivity.java | 50 +-- .../cx/ring/fragments/CallListFragment.java | 3 +- .../ring/fragments/ContactListFragment.java | 6 +- .../java/cx/ring/fragments/MenuFragment.java | 2 +- .../java/cx/ring/loaders/ContactsLoader.java | 10 +- .../java/cx/ring/loaders/HistoryLoader.java | 12 +- .../main/java/cx/ring/model/CallContact.java | 113 +++---- .../cx/ring/service/CallManagerCallBack.java | 2 +- .../java/cx/ring/service/LocalService.java | 285 +++++++++--------- 10 files changed, 252 insertions(+), 254 deletions(-) diff --git a/ring-android/app/src/main/java/cx/ring/client/ConversationActivity.java b/ring-android/app/src/main/java/cx/ring/client/ConversationActivity.java index a493abdf6..1e3f315f9 100644 --- a/ring-android/app/src/main/java/cx/ring/client/ConversationActivity.java +++ b/ring-android/app/src/main/java/cx/ring/client/ConversationActivity.java @@ -52,7 +52,6 @@ import android.widget.TextView; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; -import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -101,18 +100,20 @@ public class ConversationActivity extends AppCompatActivity { conversation = service.getConversation(conv_id); if (conversation == null) { long contact_id = CallContact.contactIdFromId(conv_id); - CallContact contact; + CallContact contact = null; if (contact_id >= 0) contact = service.findContactById(contact_id); - else if (preferredNumber != null && !preferredNumber.isEmpty()) { - contact = service.findContactByNumber(preferredNumber); - if (contact == null) - contact = CallContact.ContactBuilder.buildUnknownContact(conv_id); - } else { - contact = service.findContactByNumber(conv_id); - if (contact == null) - contact = CallContact.ContactBuilder.buildUnknownContact(conv_id); - preferredNumber = conv_id; + if (contact == null) { + if (preferredNumber != null && !preferredNumber.isEmpty()) { + contact = service.findContactByNumber(preferredNumber); + if (contact == null) + contact = CallContact.buildUnknown(conv_id); + } else { + contact = service.findContactByNumber(conv_id); + if (contact == null) + contact = CallContact.buildUnknown(conv_id); + preferredNumber = conv_id; + } } conversation = service.startConversation(contact); } diff --git a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java index ffd2c5c46..de2090da9 100644 --- a/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java +++ b/ring-android/app/src/main/java/cx/ring/client/HomeActivity.java @@ -138,21 +138,6 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); - // Bind to LocalService - - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(LocalService.ACTION_CONF_UPDATE); - intentFilter.addAction(LocalService.ACTION_ACCOUNT_UPDATE); - registerReceiver(receiver, intentFilter); - - if (!mBound && LocalService.checkContactPermissions(this)) { - Log.i(TAG, "onStart: Binding service..."); - /*Intent intent = new Intent(this, SipService.class); - startService(intent); - bindService(intent, mConnection, Context.BIND_AUTO_CREATE);*/ - Intent intent = new Intent(this, LocalService.class); - bindService(intent, mConnection, Context.BIND_AUTO_CREATE); - } toolbar = (Toolbar) findViewById(R.id.main_toolbar); setSupportActionBar(toolbar); @@ -184,6 +169,20 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call mNavigationDrawer.setDrawerListener(mDrawerToggle); + // Bind to LocalService + + String[] toRequest = LocalService.checkRequiredPermissions(this); + if (toRequest.length > 0) { + ActivityCompat.requestPermissions(this, toRequest, LocalService.PERMISSIONS_REQUEST); + } else if (!mBound) { + Log.i(TAG, "onCreate: Binding service..."); + /*Intent intent = new Intent(this, SipService.class); + startService(intent); + bindService(intent, mConnection, Context.BIND_AUTO_CREATE);*/ + Intent intent = new Intent(this, LocalService.class); + startService(intent); + bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + } } final BroadcastReceiver receiver = new BroadcastReceiver() { @@ -229,13 +228,24 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call Log.w(TAG, "onRequestPermissionsResult"); switch (requestCode) { - case LocalService.PERMISSIONS_REQUEST_READ_CONTACTS: { + case LocalService.PERMISSIONS_REQUEST: { + if (grantResults.length == 0) { + finish(); + return; + } + for (int grantResult : grantResults) { + if (grantResult != PackageManager.PERMISSION_GRANTED) { + finish(); + return; + } + } // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Log.w(TAG, "onRequestPermissionsResult granted"); if (!mBound) { Intent intent = new Intent(this, LocalService.class); + startService(intent); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @@ -370,8 +380,8 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call @Override protected void onDestroy() { super.onDestroy(); - unregisterReceiver(receiver); if (mBound) { + unregisterReceiver(receiver); unbindService(mConnection); mBound = false; } @@ -402,6 +412,10 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call Log.i(TAG, "onServiceConnected " + className.getClassName()); LocalService.LocalBinder binder = (LocalService.LocalBinder) s; service = binder.getService(); + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(LocalService.ACTION_CONF_UPDATE); + intentFilter.addAction(LocalService.ACTION_ACCOUNT_UPDATE); + registerReceiver(receiver, intentFilter); fContent = new CallListFragment(); if (fMenuHead != null) @@ -590,7 +604,7 @@ public class HomeActivity extends AppCompatActivity implements LocalService.Call args.putParcelable(SipCall.ACCOUNT, usedAccount); args.putInt(SipCall.STATE, SipCall.State.NONE); args.putInt(SipCall.TYPE, SipCall.Direction.OUTGOING); - args.putParcelable(SipCall.CONTACT, CallContact.ContactBuilder.buildUnknownContact(to)); + args.putParcelable(SipCall.CONTACT, CallContact.ContactBuilder.buildUnknown(to)); try { launchCallActivity(new SipCall(args)); diff --git a/ring-android/app/src/main/java/cx/ring/fragments/CallListFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/CallListFragment.java index bc842b04e..327c8a5fd 100644 --- a/ring-android/app/src/main/java/cx/ring/fragments/CallListFragment.java +++ b/ring-android/app/src/main/java/cx/ring/fragments/CallListFragment.java @@ -60,7 +60,6 @@ import cx.ring.R; import cx.ring.adapters.ContactPictureTask; import cx.ring.adapters.ContactsAdapter; import cx.ring.adapters.StarredContactsAdapter; -import cx.ring.client.AccountWizard; import cx.ring.client.ConversationActivity; import cx.ring.client.HomeActivity; import cx.ring.client.NewConversationActivity; @@ -260,7 +259,7 @@ public class CallListFragment extends Fragment implements SearchView.OnQueryText getLoaderManager().restartLoader(LoaderConstants.CONTACT_LOADER, b, this); newcontact.setVisibility(View.VISIBLE); ((TextView)newcontact.findViewById(R.id.display_name)).setText("Call \"" + query + "\""); - CallContact contact = CallContact.ContactBuilder.buildUnknownContact(query); + CallContact contact = CallContact.buildUnknown(query); newcontact.setTag(contact); return true; } diff --git a/ring-android/app/src/main/java/cx/ring/fragments/ContactListFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/ContactListFragment.java index 02ce5e7af..cc41c2a6f 100644 --- a/ring-android/app/src/main/java/cx/ring/fragments/ContactListFragment.java +++ b/ring-android/app/src/main/java/cx/ring/fragments/ContactListFragment.java @@ -51,10 +51,8 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; -import android.view.MotionEvent; import android.view.View; import android.view.View.MeasureSpec; -import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; @@ -66,8 +64,6 @@ import android.widget.SearchView; import android.widget.SearchView.OnQueryTextListener; import android.widget.TextView; -import java.util.ArrayList; - public class ContactListFragment extends Fragment implements OnQueryTextListener, LoaderManager.LoaderCallbacks<ContactsLoader.Result> { public static final String TAG = "ContactListFragment"; ContactsAdapter mListAdapter; @@ -206,7 +202,7 @@ public class ContactListFragment extends Fragment implements OnQueryTextListener getLoaderManager().restartLoader(LoaderConstants.CONTACT_LOADER, b, this); newcontact.setVisibility(View.VISIBLE); ((TextView)newcontact.findViewById(R.id.display_name)).setText("Call \"" + newText + "\""); - CallContact contact = CallContact.ContactBuilder.buildUnknownContact(newText); + CallContact contact = CallContact.buildUnknown(newText); newcontact.setTag(contact); return true; } diff --git a/ring-android/app/src/main/java/cx/ring/fragments/MenuFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/MenuFragment.java index 808aa2cc2..e1805a492 100644 --- a/ring-android/app/src/main/java/cx/ring/fragments/MenuFragment.java +++ b/ring-android/app/src/main/java/cx/ring/fragments/MenuFragment.java @@ -187,7 +187,7 @@ public class MenuFragment extends Fragment { } }); - CallContact user = CallContact.ContactBuilder.buildUserContact(getActivity().getContentResolver()); + CallContact user = CallContact.buildUserContact(getActivity()); new ContactPictureTask(getActivity(), (ImageView) inflatedView.findViewById(R.id.user_photo), user).run(); ((TextView) inflatedView.findViewById(R.id.user_name)).setText(user.getDisplayName()); diff --git a/ring-android/app/src/main/java/cx/ring/loaders/ContactsLoader.java b/ring-android/app/src/main/java/cx/ring/loaders/ContactsLoader.java index 0a08ba3da..243a508f9 100644 --- a/ring-android/app/src/main/java/cx/ring/loaders/ContactsLoader.java +++ b/ring-android/app/src/main/java/cx/ring/loaders/ContactsLoader.java @@ -24,7 +24,9 @@ package cx.ring.loaders; import java.util.ArrayList; import cx.ring.model.CallContact; +import cx.ring.service.LocalService; +import android.Manifest; import android.content.AsyncTaskLoader; import android.content.ContentResolver; import android.content.Context; @@ -86,12 +88,14 @@ public class ContactsLoader extends AsyncTaskLoader<ContactsLoader.Result> } @Override - public Result loadInBackground() { - ContentResolver cr = getContext().getContentResolver(); - + public Result loadInBackground() + { long startTime = System.nanoTime(); final Result res = new Result(); + if (!LocalService.checkPermission(getContext(), Manifest.permission.READ_CONTACTS)) + return res; + ContentResolver cr = getContext().getContentResolver(); if (baseUri != null) { Cursor result = cr.query(baseUri, CONTACTS_ID_PROJECTION, SELECT, null, Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); if (result == null) diff --git a/ring-android/app/src/main/java/cx/ring/loaders/HistoryLoader.java b/ring-android/app/src/main/java/cx/ring/loaders/HistoryLoader.java index c33bc3651..6dd99e219 100644 --- a/ring-android/app/src/main/java/cx/ring/loaders/HistoryLoader.java +++ b/ring-android/app/src/main/java/cx/ring/loaders/HistoryLoader.java @@ -67,11 +67,10 @@ public class HistoryLoader extends AsyncTaskLoader<ArrayList<HistoryEntry>> { try { List<HistoryCall> list = historyManager.getAll(); - CallContact.ContactBuilder builder = CallContact.ContactBuilder.getInstance(); for (HistoryCall call : list) { CallContact contact; if (call.getContactID() == CallContact.DEFAULT_ID) { - contact = CallContact.ContactBuilder.buildUnknownContact(call.getNumber()); + contact = CallContact.buildUnknown(call.getNumber()); } else { Cursor result = getContext().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, ContactsContract.Contacts._ID + " = ?", @@ -82,11 +81,10 @@ public class HistoryLoader extends AsyncTaskLoader<ArrayList<HistoryEntry>> { int iPhoto = result.getColumnIndex(ContactsContract.Contacts.PHOTO_ID); if (result.moveToFirst()) { - builder.startNewContact(result.getLong(iID), result.getString(iKey), result.getString(iName), result.getLong(iPhoto)); - builder.addPhoneNumber(call.getNumber(), 0, null); - contact = builder.build(); + contact = new CallContact(result.getLong(iID), result.getString(iKey), result.getString(iName), result.getLong(iPhoto)); + contact.addPhoneNumber(call.getNumber(), 0); } else { - contact = CallContact.ContactBuilder.buildUnknownContact(call.getNumber()); + contact = CallContact.buildUnknown(call.getNumber()); } result.close(); } @@ -130,7 +128,7 @@ public class HistoryLoader extends AsyncTaskLoader<ArrayList<HistoryEntry>> { String contactName = entry.get(ServiceConstants.history.DISPLAY_NAME_KEY); String number_called = entry.get(ServiceConstants.history.PEER_NUMBER_KEY); if (contactName.isEmpty()) { - contact = ContactBuilder.buildUnknownContact(number_called); + contact = ContactBuilder.buildUnknown(number_called); } else { contact = ContactBuilder.getInstance().buildSimpleContact(contactName, number_called); } diff --git a/ring-android/app/src/main/java/cx/ring/model/CallContact.java b/ring-android/app/src/main/java/cx/ring/model/CallContact.java index 396cf20fa..d1e06a667 100644 --- a/ring-android/app/src/main/java/cx/ring/model/CallContact.java +++ b/ring-android/app/src/main/java/cx/ring/model/CallContact.java @@ -46,9 +46,15 @@ import android.provider.ContactsContract; import android.provider.ContactsContract.Profile; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.support.annotation.NonNull; +import android.util.Log; -public class CallContact implements Parcelable { - public static int DEFAULT_ID = 0; +import cx.ring.R; + +public class CallContact implements Parcelable +{ + static final String TAG = CallContact.class.getSimpleName(); + public static final int DEFAULT_ID = 0; + private static final String[] PROFILE_PROJECTION = new String[] { Profile._ID, Profile.LOOKUP_KEY, Profile.DISPLAY_NAME_PRIMARY, Profile.PHOTO_ID }; private long id; private String key; @@ -78,6 +84,41 @@ public class CallContact implements Parcelable { isUser = user; } + public static CallContact buildUnknown(String to) { + ArrayList<Phone> phones = new ArrayList<>(); + phones.add(new Phone(to, 0)); + + return new CallContact(-1, null, to, 0, phones, "", false); + } + + public static CallContact buildUnknown(String to, int type) { + ArrayList<Phone> phones = new ArrayList<>(); + phones.add(new Phone(to, type)); + return new CallContact(-1, null, to, 0, phones, "", false); + } + + public static CallContact buildUserContact(Context c) { + CallContact result = null; + try { + Cursor mProfileCursor = c.getContentResolver().query(Profile.CONTENT_URI, PROFILE_PROJECTION, null, null, null); + if (mProfileCursor != null) { + if (mProfileCursor.moveToFirst()) { + String key = mProfileCursor.getString(mProfileCursor.getColumnIndex(Profile.LOOKUP_KEY)); + String displayName = mProfileCursor.getString(mProfileCursor.getColumnIndex(Profile.DISPLAY_NAME_PRIMARY)); + + if (displayName == null || displayName.isEmpty()) + displayName = c.getResources().getString(R.string.me); + result = new CallContact(mProfileCursor.getLong(mProfileCursor.getColumnIndex(Profile._ID)), key, displayName, + mProfileCursor.getLong(mProfileCursor.getColumnIndex(Profile.PHOTO_ID)), new ArrayList<Phone>(), "", true); + } + mProfileCursor.close(); + } + } catch (Exception e) { + Log.w(TAG, e); + } + return result == null ? new CallContact(-1, null, c.getResources().getString(R.string.me), 0, new ArrayList<Phone>(), "", true) : result; + } + public void setContactInfos(String k, String displayName, long photo_id) { key = k; mDisplayName = displayName; @@ -188,74 +229,6 @@ public class CallContact implements Parcelable { return stared; } - public static class ContactBuilder { - - long contactID; - String key; - String contactName; - long contactPhoto; - ArrayList<Phone> phones; - String contactMail; - - public ContactBuilder startNewContact(long id, String k, String displayName, long photo_id) { - contactID = id; - key = k; - contactName = displayName; - contactPhoto = photo_id; - phones = new ArrayList<>(); - return this; - } - - public ContactBuilder addPhoneNumber(String num, int type, String label) { - phones.add(new Phone(num, type, label)); - return this; - } - - public ContactBuilder addSipNumber(String num, int type, String label) { - phones.add(new Phone(num, type, label, NumberType.SIP)); - return this; - } - - public CallContact build() { - return new CallContact(contactID, key, contactName, contactPhoto, phones, contactMail, false); - } - - public static ContactBuilder getInstance() { - return new ContactBuilder(); - } - - public static CallContact buildUnknownContact(String to) { - ArrayList<Phone> phones = new ArrayList<>(); - phones.add(new Phone(to, 0)); - - return new CallContact(-1, null, to, 0, phones, "", false); - } - public static CallContact buildUnknownContact(String to, int type) { - ArrayList<Phone> phones = new ArrayList<>(); - phones.add(new Phone(to, type)); - return new CallContact(-1, null, to, 0, phones, "", false); - } - - public static CallContact buildUserContact(ContentResolver c) { - String[] mProjection = new String[] { Profile._ID, Profile.LOOKUP_KEY, Profile.DISPLAY_NAME_PRIMARY, Profile.PHOTO_ID }; - Cursor mProfileCursor = c.query(Profile.CONTENT_URI, mProjection, null, null, null); - CallContact result; - if (mProfileCursor.getCount() > 0) { - mProfileCursor.moveToFirst(); - String key = mProfileCursor.getString(mProfileCursor.getColumnIndex(Profile.LOOKUP_KEY)); - String displayName = mProfileCursor.getString(mProfileCursor.getColumnIndex(Profile.DISPLAY_NAME_PRIMARY)); - - result = new CallContact(mProfileCursor.getLong(mProfileCursor.getColumnIndex(Profile._ID)), key, displayName, - mProfileCursor.getLong(mProfileCursor.getColumnIndex(Profile.PHOTO_ID)), new ArrayList<Phone>(), "", true); - } else { - result = new CallContact(-1, null, "Me", 0, new ArrayList<Phone>(), "", true); - } - mProfileCursor.close(); - return result; - } - - } - @Override public int describeContents() { return 0; diff --git a/ring-android/app/src/main/java/cx/ring/service/CallManagerCallBack.java b/ring-android/app/src/main/java/cx/ring/service/CallManagerCallBack.java index 4da8065b7..c0b1615d9 100644 --- a/ring-android/app/src/main/java/cx/ring/service/CallManagerCallBack.java +++ b/ring-android/app/src/main/java/cx/ring/service/CallManagerCallBack.java @@ -131,7 +131,7 @@ public class CallManagerCallBack extends Callback { toSend.setClass(mService, CallActivity.class); toSend.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - CallContact unknown = CallContact.ContactBuilder.buildUnknownContact(from); + CallContact unknown = CallContact.buildUnknown(from); SipCall newCall = new SipCall(callID, accountID, from, SipCall.Direction.INCOMING); newCall.setContact(unknown); diff --git a/ring-android/app/src/main/java/cx/ring/service/LocalService.java b/ring-android/app/src/main/java/cx/ring/service/LocalService.java index 34e5a91b2..3da1a133d 100644 --- a/ring-android/app/src/main/java/cx/ring/service/LocalService.java +++ b/ring-android/app/src/main/java/cx/ring/service/LocalService.java @@ -86,7 +86,9 @@ public class LocalService extends Service public static final String AUTHORITY = "cx.ring"; public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY); - public static final int PERMISSIONS_REQUEST_READ_CONTACTS = 57; + public static final int PERMISSIONS_REQUEST = 57; + + public final static String[] REQUIRED_RUNTIME_PERMISSIONS = {Manifest.permission.READ_CONTACTS, Manifest.permission.RECORD_AUDIO}; private ISipService mService = null; private final ContactsContentObserver contactContentObserver = new ContactsContentObserver(); @@ -288,8 +290,17 @@ public class LocalService extends Service return super.onUnbind(intent); } - public static boolean checkContactPermissions(Context c) { - return ContextCompat.checkSelfPermission(c, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED; + public static boolean checkPermission(Context c, String permission) { + return ContextCompat.checkSelfPermission(c, permission) == PackageManager.PERMISSION_GRANTED; + } + + public static String[] checkRequiredPermissions(Context c) { + ArrayList<String> perms = new ArrayList<>(); + for (String p : REQUIRED_RUNTIME_PERMISSIONS) { + if (!checkPermission(c, p)) + perms.add(p); + } + return perms.toArray(new String[perms.size()]); } public ISipService getRemoteService() { @@ -299,6 +310,8 @@ public class LocalService extends Service public List<Account> getAccounts() { return accounts; } public List<Account> getIP2IPAccount() { return ip2ip_account; } public Account getAccount(String account_id) { + if (account_id == null || account_id.isEmpty()) + return null; for (Account acc : all_accounts) if (acc.getAccountID().equals(account_id)) return acc; @@ -445,97 +458,102 @@ public class LocalService extends Service private static void lookupDetails(@NonNull ContentResolver res, @NonNull CallContact c) { Log.w(TAG, "lookupDetails " + c.getKey()); - - Cursor cPhones = res.query( - ContactsContract.CommonDataKinds.Phone.CONTENT_URI, - CONTACTS_PHONES_PROJECTION, ID_SELECTION, - new String[]{String.valueOf(c.getId())}, null); - if (cPhones != null) { - final int iNum = cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); - final int iType = cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE); - final int iLabel = cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL); - while (cPhones.moveToNext()) { - c.addNumber(cPhones.getString(iNum), cPhones.getInt(iType), cPhones.getString(iLabel), CallContact.NumberType.TEL); - Log.w(TAG,"Phone:"+cPhones.getString(cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); + try { + Cursor cPhones = res.query( + ContactsContract.CommonDataKinds.Phone.CONTENT_URI, + CONTACTS_PHONES_PROJECTION, ID_SELECTION, + new String[]{String.valueOf(c.getId())}, null); + if (cPhones != null) { + final int iNum = cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); + final int iType = cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE); + final int iLabel = cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.LABEL); + while (cPhones.moveToNext()) { + c.addNumber(cPhones.getString(iNum), cPhones.getInt(iType), cPhones.getString(iLabel), CallContact.NumberType.TEL); + Log.w(TAG,"Phone:"+cPhones.getString(cPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); + } + cPhones.close(); } - cPhones.close(); - } - - Uri baseUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, c.getId()); - Uri targetUri = Uri.withAppendedPath(baseUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY); - Cursor cSip = res.query(targetUri, - CONTACTS_SIP_PROJECTION, - ContactsContract.Data.MIMETYPE + "=?", - new String[]{ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE}, null); - if (cSip != null) { - final int iSip = cSip.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS); - final int iType = cSip.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.TYPE); - final int iLabel = cSip.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.LABEL); - while (cSip.moveToNext()) { - c.addNumber(cSip.getString(iSip), cSip.getInt(iType), cSip.getString(iLabel), CallContact.NumberType.SIP); - Log.w(TAG, "SIP phone:" + cSip.getString(iSip)); + + Uri baseUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, c.getId()); + Uri targetUri = Uri.withAppendedPath(baseUri, ContactsContract.Contacts.Data.CONTENT_DIRECTORY); + Cursor cSip = res.query(targetUri, + CONTACTS_SIP_PROJECTION, + ContactsContract.Data.MIMETYPE + "=?", + new String[]{ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE}, null); + if (cSip != null) { + final int iSip = cSip.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS); + final int iType = cSip.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.TYPE); + final int iLabel = cSip.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.LABEL); + while (cSip.moveToNext()) { + c.addNumber(cSip.getString(iSip), cSip.getInt(iType), cSip.getString(iLabel), CallContact.NumberType.SIP); + Log.w(TAG, "SIP phone:" + cSip.getString(iSip)); + } + cSip.close(); } - cSip.close(); + } catch(Exception e) { + Log.w(TAG, e); } } public static CallContact findByKey(@NonNull ContentResolver res, String key) { Log.e(TAG, "findByKey " + key); - - final CallContact.ContactBuilder builder = CallContact.ContactBuilder.getInstance(); - Cursor result = res.query(Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, key), CONTACT_PROJECTION, - null, null, null); - CallContact contact = null; - if (result != null && result.moveToFirst()) { - int iID = result.getColumnIndex(ContactsContract.Data._ID); - int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY); - int iName = result.getColumnIndex(ContactsContract.Data.DISPLAY_NAME); - int iPhoto = result.getColumnIndex(ContactsContract.Data.PHOTO_ID); - int iStared = result.getColumnIndex(ContactsContract.Data.STARRED); - long cid = result.getLong(iID); - - Log.w(TAG, "Contact id:" + cid + " key:" + result.getString(iKey)); - - builder.startNewContact(cid, result.getString(iKey), result.getString(iName), result.getLong(iPhoto)); + try { + Cursor result = res.query(Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, key), CONTACT_PROJECTION, + null, null, null); + if (result == null) + return null; + if (result.moveToFirst()) { + int iID = result.getColumnIndex(ContactsContract.Data._ID); + int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY); + int iName = result.getColumnIndex(ContactsContract.Data.DISPLAY_NAME); + int iPhoto = result.getColumnIndex(ContactsContract.Data.PHOTO_ID); + int iStared = result.getColumnIndex(ContactsContract.Data.STARRED); + long cid = result.getLong(iID); + + Log.w(TAG, "Contact id:" + cid + " key:" + result.getString(iKey)); + + contact = new CallContact(cid, result.getString(iKey), result.getString(iName), result.getLong(iPhoto)); + if (result.getInt(iStared) != 0) + contact.setStared(); + lookupDetails(res, contact); + } result.close(); - - contact = builder.build(); - if (result.getInt(iStared) != 0) - contact.setStared(); - lookupDetails(res, contact); + } catch(Exception e) { + Log.w(TAG, e); } return contact; } public static CallContact findById(@NonNull ContentResolver res, long id) { Log.e(TAG, "findById " + id); - - final CallContact.ContactBuilder builder = CallContact.ContactBuilder.getInstance(); - Cursor result = res.query(ContactsContract.Contacts.CONTENT_URI, CONTACT_PROJECTION, - ContactsContract.Contacts._ID + " = ?", - new String[]{String.valueOf(id)}, null); - if (result == null) - return null; - CallContact contact = null; - if (result.moveToFirst()) { - int iID = result.getColumnIndex(ContactsContract.Data._ID); - int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY); - int iName = result.getColumnIndex(ContactsContract.Data.DISPLAY_NAME); - int iPhoto = result.getColumnIndex(ContactsContract.Data.PHOTO_ID); - int iStared = result.getColumnIndex(ContactsContract.Contacts.STARRED); - long cid = result.getLong(iID); - - Log.w(TAG, "Contact id:" + cid + " key:" + result.getString(iKey)); - - builder.startNewContact(cid, result.getString(iKey), result.getString(iName), result.getLong(iPhoto)); - contact = builder.build(); - if (result.getInt(iStared) != 0) - contact.setStared(); - lookupDetails(res, contact); + try { + Cursor result = res.query(ContactsContract.Contacts.CONTENT_URI, CONTACT_PROJECTION, + ContactsContract.Contacts._ID + " = ?", + new String[]{String.valueOf(id)}, null); + if (result == null) + return null; + + if (result.moveToFirst()) { + int iID = result.getColumnIndex(ContactsContract.Data._ID); + int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY); + int iName = result.getColumnIndex(ContactsContract.Data.DISPLAY_NAME); + int iPhoto = result.getColumnIndex(ContactsContract.Data.PHOTO_ID); + int iStared = result.getColumnIndex(ContactsContract.Contacts.STARRED); + long cid = result.getLong(iID); + + Log.w(TAG, "Contact id:" + cid + " key:" + result.getString(iKey)); + + contact = new CallContact(cid, result.getString(iKey), result.getString(iName), result.getLong(iPhoto)); + if (result.getInt(iStared) != 0) + contact.setStared(); + lookupDetails(res, contact); + } + result.close(); + } catch(Exception e) { + Log.w(TAG, e); } - result.close(); return contact; } @@ -553,42 +571,39 @@ public class LocalService extends Service @NonNull public static CallContact findContactBySipNumber(@NonNull ContentResolver res, String number) { - final CallContact.ContactBuilder builder = CallContact.ContactBuilder.getInstance(); - Cursor result = res.query(ContactsContract.Data.CONTENT_URI, - DATA_PROJECTION, - ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?", - new String[]{number, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE}, null); - if (result == null) { - Log.w(TAG, "findContactBySipNumber " + number + " can't find contact."); - return CallContact.ContactBuilder.buildUnknownContact(number); - } - int icID = result.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID); - int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY); - int iName = result.getColumnIndex(ContactsContract.Data.DISPLAY_NAME); - int iPhoto = result.getColumnIndex(ContactsContract.Data.PHOTO_ID); - int iPhotoThumb = result.getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI); - int iStared = result.getColumnIndex(ContactsContract.Contacts.STARRED); - ArrayList<CallContact> contacts = new ArrayList<>(1); - while (result.moveToNext()) { - long cid = result.getLong(icID); - builder.startNewContact(cid, result.getString(iKey), result.getString(iName), result.getLong(iPhoto)); - CallContact contact = builder.build(); - if (result.getInt(iStared) != 0) - contact.setStared(); - lookupDetails(res, contact); - contacts.add(contact); - } - result.close(); - - //lookupDetails(res, contact); - /*if (contact == null) { - Log.w(TAG, "Can't find contact with number " + number); - contact = CallContact.ContactBuilder.buildUnknownContact(number); - }*/ + try { + Cursor result = res.query(ContactsContract.Data.CONTENT_URI, + DATA_PROJECTION, + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?", + new String[]{number, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE}, null); + if (result == null) { + Log.w(TAG, "findContactBySipNumber " + number + " can't find contact."); + return CallContact.buildUnknown(number); + } + int icID = result.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID); + int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY); + int iName = result.getColumnIndex(ContactsContract.Data.DISPLAY_NAME); + int iPhoto = result.getColumnIndex(ContactsContract.Data.PHOTO_ID); + int iPhotoThumb = result.getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI); + int iStared = result.getColumnIndex(ContactsContract.Contacts.STARRED); + + while (result.moveToNext()) { + long cid = result.getLong(icID); + CallContact contact = new CallContact(cid, result.getString(iKey), result.getString(iName), result.getLong(iPhoto)); + if (result.getInt(iStared) != 0) + contact.setStared(); + lookupDetails(res, contact); + contacts.add(contact); + } + result.close(); + //lookupDetails(res, contact); + } catch(Exception e) { + Log.w(TAG, e); + } if (contacts.isEmpty()) { Log.w(TAG, "findContactBySipNumber " + number + " can't find contact."); - return CallContact.ContactBuilder.buildUnknownContact(number); + return CallContact.buildUnknown(number); } return contacts.get(0); } @@ -596,34 +611,32 @@ public class LocalService extends Service @NonNull public static CallContact findContactByNumber(@NonNull ContentResolver res, String number) { //Log.w(TAG, "findContactByNumber " + number); - - final CallContact.ContactBuilder builder = CallContact.ContactBuilder.getInstance(); - Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); - Cursor result = res.query(uri, PHONELOOKUP_PROJECTION, null, null, null); - if (result == null) { - Log.w(TAG, "findContactByNumber " + number + " can't find contact."); - return findContactBySipNumber(res, number); - } - if (!result.moveToFirst()) { + CallContact c = null; + try { + Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); + Cursor result = res.query(uri, PHONELOOKUP_PROJECTION, null, null, null); + if (result == null) { + Log.w(TAG, "findContactByNumber " + number + " can't find contact."); + return findContactBySipNumber(res, number); + } + if (result.moveToFirst()) { + int iID = result.getColumnIndex(ContactsContract.Contacts._ID); + int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY); + int iName = result.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); + int iPhoto = result.getColumnIndex(ContactsContract.Contacts.PHOTO_ID); + c = new CallContact(result.getLong(iID), result.getString(iKey), result.getString(iName), result.getLong(iPhoto)); + lookupDetails(res, c); + Log.w(TAG, "findContactByNumber " + number + " found " + c.getDisplayName()); + } result.close(); + } catch(Exception e) { + Log.w(TAG, e); + } + if (c == null) { Log.w(TAG, "findContactByNumber " + number + " can't find contact."); - return findContactBySipNumber(res, number); - } - int iID = result.getColumnIndex(ContactsContract.Contacts._ID); - int iKey = result.getColumnIndex(ContactsContract.Data.LOOKUP_KEY); - int iName = result.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); - int iPhoto = result.getColumnIndex(ContactsContract.Contacts.PHOTO_ID); - builder.startNewContact(result.getLong(iID), result.getString(iKey), result.getString(iName), result.getLong(iPhoto)); - result.close(); - CallContact contact = builder.build(); - lookupDetails(res, contact); - /*if (contact == null) { - Log.w(TAG, "Can't find contact with number " + number); - contact = CallContact.ContactBuilder.buildUnknownContact(number); - }*/ - Log.w(TAG, "findContactByNumber " + number + " found " + contact.getDisplayName()); - - return contact; + c = findContactBySipNumber(res, number); + } + return c; } private class ConversationLoader extends AsyncTask<Void, Void, Map<String, Conversation>> { -- GitLab