Added back the sync mechanism for contacts
This commit is contained in:
parent
5a40d15e1b
commit
182888f824
7 changed files with 173 additions and 164 deletions
|
@ -78,7 +78,7 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<data android:mimeType="vnd.android.cursor.item/org.linphone.profile" /> <!-- Change package ! -->
|
<data android:mimeType="@string/sync_mimetype" /> <!-- Change package in res/values/non_localizable_custom.xml ! -->
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<string name="default_stun">stun.linphone.org</string>
|
<string name="default_stun">stun.linphone.org</string>
|
||||||
|
|
||||||
<string name="sync_account_type">org.linphone</string> <!-- Change package ! -->
|
<string name="sync_account_type">org.linphone</string> <!-- Change package ! -->
|
||||||
<string name="sync_mimetype">vnd.android.cursor.item/org.linphone.profile</string> <!-- Change package, leave .profile at the end ! -->
|
<string name="sync_mimetype">vnd.android.cursor.item/org.linphone.profile</string> <!-- Change package, leave .profile at the end. Also change res/xml/contacts.xml ! -->
|
||||||
|
|
||||||
<bool name="assistant_use_linphone_login_as_first_fragment">false</bool>
|
<bool name="assistant_use_linphone_login_as_first_fragment">false</bool>
|
||||||
<bool name="hide_in_call_stats">false</bool>
|
<bool name="hide_in_call_stats">false</bool>
|
||||||
|
|
|
@ -174,7 +174,7 @@ public class ContactsManager extends ContentObserver {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initializeSyncAccount(Context context, ContentResolver contentResolver) {
|
public void initializeSyncAccount(Context context, ContentResolver contentResolver) {
|
||||||
initializeContactManager(context,contentResolver);
|
initializeContactManager(context, contentResolver);
|
||||||
AccountManager accountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
|
AccountManager accountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
|
||||||
|
|
||||||
Account[] accounts = accountManager.getAccountsByType(context.getPackageName());
|
Account[] accounts = accountManager.getAccountsByType(context.getPackageName());
|
||||||
|
@ -330,6 +330,7 @@ public class ContactsManager extends ContentObserver {
|
||||||
Log.e(e);
|
Log.e(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString(int resourceID) {
|
public String getString(int resourceID) {
|
||||||
return context.getString(resourceID);
|
return context.getString(resourceID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,13 +103,10 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
||||||
private static final int FIRST_LOGIN_ACTIVITY = 101;
|
private static final int FIRST_LOGIN_ACTIVITY = 101;
|
||||||
private static final int REMOTE_PROVISIONING_LOGIN_ACTIVITY = 102;
|
private static final int REMOTE_PROVISIONING_LOGIN_ACTIVITY = 102;
|
||||||
private static final int CALL_ACTIVITY = 19;
|
private static final int CALL_ACTIVITY = 19;
|
||||||
private static final int PERMISSIONS_REQUEST_CONTACTS = 200;
|
|
||||||
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 201;
|
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 201;
|
||||||
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO_INCOMING_CALL = 203;
|
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO_INCOMING_CALL = 203;
|
||||||
private static final int PERMISSIONS_REQUEST_EXTERNAL_FILE_STORAGE_WRITE = 204;
|
|
||||||
private static final int PERMISSIONS_REQUEST_CAMERA = 205;
|
|
||||||
private static final int PERMISSIONS_REQUEST_OVERLAY = 206;
|
private static final int PERMISSIONS_REQUEST_OVERLAY = 206;
|
||||||
private static final int PERMISSIONS_REQUEST_EXTERNAL_FILE_STORAGE_READ = 207;
|
private static final int PERMISSIONS_REQUEST_SYNC = 207;
|
||||||
|
|
||||||
private static LinphoneActivity instance;
|
private static LinphoneActivity instance;
|
||||||
|
|
||||||
|
@ -174,9 +171,12 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO rework
|
if (getResources().getBoolean(R.bool.use_linphone_tag)) {
|
||||||
if (getResources().getBoolean(R.bool.use_linphone_tag) && getPackageManager().checkPermission(Manifest.permission.WRITE_SYNC_SETTINGS, getPackageName()) == PackageManager.PERMISSION_GRANTED) {
|
if (getPackageManager().checkPermission(Manifest.permission.WRITE_SYNC_SETTINGS, getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||||
ContactsManager.getInstance().initializeSyncAccount(getApplicationContext(), getContentResolver());
|
checkSyncPermission();
|
||||||
|
} else {
|
||||||
|
ContactsManager.getInstance().initializeSyncAccount(getApplicationContext(), getContentResolver());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ContactsManager.getInstance().initializeContactManager(getApplicationContext(), getContentResolver());
|
ContactsManager.getInstance().initializeContactManager(getApplicationContext(), getContentResolver());
|
||||||
}
|
}
|
||||||
|
@ -1167,23 +1167,23 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkAndRequestReadExternalStoragePermission() {
|
public void checkAndRequestReadExternalStoragePermission() {
|
||||||
checkAndRequestPermission(Manifest.permission.READ_EXTERNAL_STORAGE, PERMISSIONS_REQUEST_EXTERNAL_FILE_STORAGE_READ);
|
checkAndRequestPermission(Manifest.permission.READ_EXTERNAL_STORAGE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkAndRequestExternalStoragePermission() {
|
public void checkAndRequestExternalStoragePermission() {
|
||||||
checkAndRequestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, PERMISSIONS_REQUEST_EXTERNAL_FILE_STORAGE_WRITE);
|
checkAndRequestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkAndRequestCameraPermission() {
|
public void checkAndRequestCameraPermission() {
|
||||||
checkAndRequestPermission(Manifest.permission.CAMERA, PERMISSIONS_REQUEST_CAMERA);
|
checkAndRequestPermission(Manifest.permission.CAMERA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkAndRequestReadContactsPermission() {
|
public void checkAndRequestReadContactsPermission() {
|
||||||
checkAndRequestPermission(Manifest.permission.READ_CONTACTS, PERMISSIONS_REQUEST_CONTACTS);
|
checkAndRequestPermission(Manifest.permission.READ_CONTACTS, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkAndRequestWriteContactsPermission() {
|
public void checkAndRequestWriteContactsPermission() {
|
||||||
checkAndRequestPermission(Manifest.permission.WRITE_CONTACTS, PERMISSIONS_REQUEST_CONTACTS);
|
checkAndRequestPermission(Manifest.permission.WRITE_CONTACTS, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkAndRequestCallPermissions(boolean isIncomingCall) {
|
public void checkAndRequestCallPermissions(boolean isIncomingCall) {
|
||||||
|
@ -1217,6 +1217,10 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
||||||
ActivityCompat.requestPermissions(this, permissions, 0);
|
ActivityCompat.requestPermissions(this, permissions, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkSyncPermission() {
|
||||||
|
checkAndRequestPermission(Manifest.permission.WRITE_SYNC_SETTINGS, PERMISSIONS_REQUEST_SYNC);
|
||||||
|
}
|
||||||
|
|
||||||
public void checkAndRequestPermission(String permission, int result) {
|
public void checkAndRequestPermission(String permission, int result) {
|
||||||
if (getPackageManager().checkPermission(permission, getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
if (getPackageManager().checkPermission(permission, getPackageName()) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
@ -1233,6 +1237,13 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
||||||
case PERMISSIONS_REQUEST_RECORD_AUDIO_INCOMING_CALL:
|
case PERMISSIONS_REQUEST_RECORD_AUDIO_INCOMING_CALL:
|
||||||
startActivity(new Intent(this, CallIncomingActivity.class));
|
startActivity(new Intent(this, CallIncomingActivity.class));
|
||||||
break;
|
break;
|
||||||
|
case PERMISSIONS_REQUEST_SYNC:
|
||||||
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
ContactsManager.getInstance().initializeSyncAccount(getApplicationContext(), getContentResolver());
|
||||||
|
} else {
|
||||||
|
ContactsManager.getInstance().initializeContactManager(getApplicationContext(), getContentResolver());
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,10 +48,11 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
private static final long serialVersionUID = 9015568163905205244L;
|
private static final long serialVersionUID = 9015568163905205244L;
|
||||||
|
|
||||||
private transient LinphoneFriend friend;
|
private transient LinphoneFriend friend;
|
||||||
private String fullName, firstName, lastName, androidId;
|
private String fullName, firstName, lastName, androidId, androidRawId, androidTagId;
|
||||||
private transient Uri photoUri, thumbnailUri;
|
private transient Uri photoUri, thumbnailUri;
|
||||||
private List<LinphoneNumberOrAddress> addresses;
|
private List<LinphoneNumberOrAddress> addresses;
|
||||||
private transient ArrayList<ContentProviderOperation> changesToCommit;
|
private transient ArrayList<ContentProviderOperation> changesToCommit;
|
||||||
|
private transient ArrayList<ContentProviderOperation> changesToCommit2;
|
||||||
private boolean hasSipAddress;
|
private boolean hasSipAddress;
|
||||||
|
|
||||||
public LinphoneContact() {
|
public LinphoneContact() {
|
||||||
|
@ -60,6 +61,7 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
thumbnailUri = null;
|
thumbnailUri = null;
|
||||||
photoUri = null;
|
photoUri = null;
|
||||||
changesToCommit = new ArrayList<ContentProviderOperation>();
|
changesToCommit = new ArrayList<ContentProviderOperation>();
|
||||||
|
changesToCommit2 = new ArrayList<ContentProviderOperation>();
|
||||||
hasSipAddress = false;
|
hasSipAddress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,10 +140,9 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
public void setPhoto(byte[] photo) {
|
public void setPhoto(byte[] photo) {
|
||||||
if (photo != null) {
|
if (photo != null) {
|
||||||
if (isAndroidContact()) {
|
if (isAndroidContact()) {
|
||||||
String rawContactId = findRawContactID(getAndroidId());
|
if (androidRawId != null) {
|
||||||
if (rawContactId != null) {
|
|
||||||
changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||||
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
|
.withValue(ContactsContract.Data.RAW_CONTACT_ID, androidRawId)
|
||||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
|
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
|
||||||
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photo)
|
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photo)
|
||||||
.withValue(ContactsContract.Data.IS_PRIMARY, 1)
|
.withValue(ContactsContract.Data.IS_PRIMARY, 1)
|
||||||
|
@ -200,6 +201,15 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
changesToCommit.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
|
changesToCommit.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
|
||||||
.withSelection(select, args)
|
.withSelection(select, args)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
|
if (androidTagId != null && noa.isSIPAddress()) {
|
||||||
|
select = ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.DATA1 + "=?";
|
||||||
|
args = new String[] { androidTagId, noa.getOldValue() };
|
||||||
|
|
||||||
|
changesToCommit.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
|
||||||
|
.withSelection(select, args)
|
||||||
|
.build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLinphoneFriend()) {
|
if (isLinphoneFriend()) {
|
||||||
|
@ -238,19 +248,37 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM);
|
values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM);
|
||||||
values.put(ContactsContract.CommonDataKinds.Phone.LABEL, ContactsManager.getInstance().getString(R.string.addressbook_label));
|
values.put(ContactsContract.CommonDataKinds.Phone.LABEL, ContactsManager.getInstance().getString(R.string.addressbook_label));
|
||||||
}
|
}
|
||||||
|
if (androidRawId != null) {
|
||||||
String rawContactId = findRawContactID(getAndroidId());
|
|
||||||
if (rawContactId != null) {
|
|
||||||
changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||||
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
|
.withValue(ContactsContract.Data.RAW_CONTACT_ID, androidRawId)
|
||||||
.withValues(values)
|
.withValues(values)
|
||||||
.build());
|
.build());
|
||||||
} else {
|
} else {
|
||||||
changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||||
.withValues(values)
|
.withValues(values)
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (noa.isSIPAddress() && LinphoneManager.getInstance().getContext().getResources().getBoolean(R.bool.use_linphone_tag)) {
|
||||||
|
if (androidTagId != null) {
|
||||||
|
changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||||
|
.withValue(ContactsContract.Data.RAW_CONTACT_ID, androidTagId)
|
||||||
|
.withValue(ContactsContract.Data.MIMETYPE, ContactsManager.getInstance().getString(R.string.sync_mimetype))
|
||||||
|
.withValue(ContactsContract.Data.DATA1, noa.getValue())
|
||||||
|
.withValue(ContactsContract.Data.DATA2, ContactsManager.getInstance().getString(R.string.app_name))
|
||||||
|
.withValue(ContactsContract.Data.DATA3, noa.getValue())
|
||||||
|
.build());
|
||||||
|
} else {
|
||||||
|
changesToCommit2.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||||
|
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||||
|
.withValue(ContactsContract.Data.MIMETYPE, ContactsManager.getInstance().getString(R.string.sync_mimetype))
|
||||||
|
.withValue(ContactsContract.Data.DATA1, noa.getValue())
|
||||||
|
.withValue(ContactsContract.Data.DATA2, ContactsManager.getInstance().getString(R.string.app_name))
|
||||||
|
.withValue(ContactsContract.Data.DATA3, noa.getValue())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
String select;
|
String select;
|
||||||
|
@ -265,13 +293,28 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
|
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
|
||||||
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, noa.getValue());
|
values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, noa.getValue());
|
||||||
}
|
}
|
||||||
|
changesToCommit.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
|
||||||
|
.withSelection(select, args)
|
||||||
|
.withValues(values)
|
||||||
|
.build());
|
||||||
|
|
||||||
String rawContactId = findRawContactID(getAndroidId());
|
if (noa.isSIPAddress() && LinphoneManager.getInstance().getContext().getResources().getBoolean(R.bool.use_linphone_tag)) {
|
||||||
if (rawContactId != null) {
|
if (androidTagId != null) {
|
||||||
changesToCommit.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
|
changesToCommit.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
|
||||||
.withSelection(select, args)
|
.withSelection(ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.DATA1 + "=? ", new String[] { androidTagId, noa.getOldValue() })
|
||||||
.withValues(values)
|
.withValue(ContactsContract.Data.DATA1, noa.getValue())
|
||||||
.build());
|
.withValue(ContactsContract.Data.DATA2, ContactsManager.getInstance().getString(R.string.app_name))
|
||||||
|
.withValue(ContactsContract.Data.DATA3, noa.getValue())
|
||||||
|
.build());
|
||||||
|
} else {
|
||||||
|
changesToCommit2.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||||
|
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||||
|
.withValue(ContactsContract.Data.MIMETYPE, ContactsManager.getInstance().getString(R.string.sync_mimetype))
|
||||||
|
.withValue(ContactsContract.Data.DATA1, noa.getValue())
|
||||||
|
.withValue(ContactsContract.Data.DATA2, ContactsManager.getInstance().getString(R.string.app_name))
|
||||||
|
.withValue(ContactsContract.Data.DATA3, noa.getValue())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,16 +351,19 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
return androidId;
|
return androidId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
if (isAndroidContact() && ContactsManager.getInstance().hasContactsAccess() && changesToCommit.size() > 0) {
|
if (isAndroidContact() && ContactsManager.getInstance().hasContactsAccess() && changesToCommit.size() > 0) {
|
||||||
try {
|
try {
|
||||||
ContactsManager.getInstance().getContentResolver().applyBatch(ContactsContract.AUTHORITY, changesToCommit);
|
ContactsManager.getInstance().getContentResolver().applyBatch(ContactsContract.AUTHORITY, changesToCommit);
|
||||||
|
createLinphoneTagIfNeeded();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(e);
|
Log.e(e);
|
||||||
} finally {
|
} finally {
|
||||||
changesToCommit = new ArrayList<ContentProviderOperation>();
|
changesToCommit = new ArrayList<ContentProviderOperation>();
|
||||||
|
changesToCommit2 = new ArrayList<ContentProviderOperation>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLinphoneFriend()) {
|
if (isLinphoneFriend()) {
|
||||||
boolean hasAddr = false;
|
boolean hasAddr = false;
|
||||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||||
|
@ -386,17 +432,22 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
hasSipAddress = false;
|
hasSipAddress = false;
|
||||||
|
|
||||||
if (isAndroidContact()) {
|
if (isAndroidContact()) {
|
||||||
String id = getAndroidId();
|
getContactNames();
|
||||||
getContactNames(id);
|
setThumbnailUri(getContactPictureUri());
|
||||||
setThumbnailUri(getContactPictureUri(id));
|
setPhotoUri(getContactPhotoUri());
|
||||||
setPhotoUri(getContactPhotoUri(id));
|
androidRawId = findRawContactID();
|
||||||
for (LinphoneNumberOrAddress noa : getAddressesAndNumbersForAndroidContact(id)) {
|
|
||||||
|
if (LinphoneManager.getInstance().getContext().getResources().getBoolean(R.bool.use_linphone_tag)) {
|
||||||
|
androidTagId = findLinphoneRawContactId();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (LinphoneNumberOrAddress noa : getAddressesAndNumbersForAndroidContact()) {
|
||||||
addNumberOrAddress(noa);
|
addNumberOrAddress(noa);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (friend == null) {
|
if (friend == null) {
|
||||||
friend = LinphoneCoreFactory.instance().createLinphoneFriend();
|
friend = LinphoneCoreFactory.instance().createLinphoneFriend();
|
||||||
friend.setRefKey(id);
|
friend.setRefKey(getAndroidId());
|
||||||
// Disable subscribes for now
|
// Disable subscribes for now
|
||||||
friend.enableSubscribes(false);
|
friend.enableSubscribes(false);
|
||||||
friend.setIncSubscribePolicy(SubscribePolicy.SPDeny);
|
friend.setIncSubscribePolicy(SubscribePolicy.SPDeny);
|
||||||
|
@ -470,21 +521,21 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
return firstLetter.compareTo(contactfirstLetter);
|
return firstLetter.compareTo(contactfirstLetter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Uri getContactPictureUri(String id) {
|
private Uri getContactPictureUri() {
|
||||||
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(id));
|
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(getAndroidId()));
|
||||||
return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
|
return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Uri getContactPhotoUri(String id) {
|
private Uri getContactPhotoUri() {
|
||||||
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(id));
|
Uri person = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(getAndroidId()));
|
||||||
return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.DISPLAY_PHOTO);
|
return Uri.withAppendedPath(person, ContactsContract.Contacts.Photo.DISPLAY_PHOTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getContactNames(String id) {
|
private void getContactNames() {
|
||||||
ContentResolver resolver = ContactsManager.getInstance().getContentResolver();
|
ContentResolver resolver = ContactsManager.getInstance().getContentResolver();
|
||||||
String[] proj = new String[]{ ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, ContactsContract.Contacts.DISPLAY_NAME };
|
String[] proj = new String[]{ ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, ContactsContract.Contacts.DISPLAY_NAME };
|
||||||
String select = ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?";
|
String select = ContactsContract.Data.CONTACT_ID + "=? AND " + ContactsContract.Data.MIMETYPE + "=?";
|
||||||
String[] args = new String[]{ id, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE };
|
String[] args = new String[]{ getAndroidId(), ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE };
|
||||||
Cursor c = resolver.query(ContactsContract.Data.CONTENT_URI, proj, select, args, null);
|
Cursor c = resolver.query(ContactsContract.Data.CONTENT_URI, proj, select, args, null);
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
if (c.moveToFirst()) {
|
if (c.moveToFirst()) {
|
||||||
|
@ -496,13 +547,13 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String findRawContactID(String id) {
|
private String findRawContactID() {
|
||||||
ContentResolver resolver = ContactsManager.getInstance().getContentResolver();
|
ContentResolver resolver = ContactsManager.getInstance().getContentResolver();
|
||||||
String result = null;
|
String result = null;
|
||||||
String[] projection = { ContactsContract.RawContacts._ID };
|
String[] projection = { ContactsContract.RawContacts._ID };
|
||||||
|
|
||||||
String selection = ContactsContract.RawContacts.CONTACT_ID + "=?";
|
String selection = ContactsContract.RawContacts.CONTACT_ID + "=?";
|
||||||
Cursor c = resolver.query(ContactsContract.RawContacts.CONTENT_URI, projection, selection, new String[]{ id }, null);
|
Cursor c = resolver.query(ContactsContract.RawContacts.CONTENT_URI, projection, selection, new String[]{ getAndroidId() }, null);
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
if (c.moveToFirst()) {
|
if (c.moveToFirst()) {
|
||||||
result = c.getString(c.getColumnIndex(ContactsContract.RawContacts._ID));
|
result = c.getString(c.getColumnIndex(ContactsContract.RawContacts._ID));
|
||||||
|
@ -512,13 +563,13 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<LinphoneNumberOrAddress> getAddressesAndNumbersForAndroidContact(String id) {
|
private List<LinphoneNumberOrAddress> getAddressesAndNumbersForAndroidContact() {
|
||||||
List<LinphoneNumberOrAddress> result = new ArrayList<LinphoneNumberOrAddress>();
|
List<LinphoneNumberOrAddress> result = new ArrayList<LinphoneNumberOrAddress>();
|
||||||
ContentResolver resolver = ContactsManager.getInstance().getContentResolver();
|
ContentResolver resolver = ContactsManager.getInstance().getContentResolver();
|
||||||
|
|
||||||
String select = ContactsContract.Data.CONTACT_ID + " =? AND (" + ContactsContract.Data.MIMETYPE + "=? OR " + ContactsContract.Data.MIMETYPE + "=?)";
|
String select = ContactsContract.Data.CONTACT_ID + " =? AND (" + ContactsContract.Data.MIMETYPE + "=? OR " + ContactsContract.Data.MIMETYPE + "=?)";
|
||||||
String[] projection = new String[] { ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, ContactsContract.Data.MIMETYPE }; // PHONE_NUMBER == SIP_ADDRESS == "data1"...
|
String[] projection = new String[] { ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, ContactsContract.Data.MIMETYPE }; // PHONE_NUMBER == SIP_ADDRESS == "data1"...
|
||||||
Cursor c = resolver.query(ContactsContract.Data.CONTENT_URI, projection, select, new String[]{ id, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE }, null);
|
Cursor c = resolver.query(ContactsContract.Data.CONTENT_URI, projection, select, new String[]{ getAndroidId(), ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE }, null);
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
while (c.moveToNext()) {
|
while (c.moveToNext()) {
|
||||||
String mime = c.getString(c.getColumnIndex(ContactsContract.Data.MIMETYPE));
|
String mime = c.getString(c.getColumnIndex(ContactsContract.Data.MIMETYPE));
|
||||||
|
@ -551,12 +602,14 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
|
|
||||||
private static LinphoneContact createAndroidContact() {
|
private static LinphoneContact createAndroidContact() {
|
||||||
LinphoneContact contact = new LinphoneContact();
|
LinphoneContact contact = new LinphoneContact();
|
||||||
|
|
||||||
contact.changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
|
contact.changesToCommit.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
|
||||||
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
|
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
|
||||||
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
|
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
|
||||||
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
|
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
|
||||||
.build());
|
.build());
|
||||||
contact.setAndroidId("0");
|
contact.setAndroidId("0");
|
||||||
|
|
||||||
return contact;
|
return contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,4 +622,63 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
contact.friend = friend;
|
contact.friend = friend;
|
||||||
return contact;
|
return contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String findLinphoneRawContactId() {
|
||||||
|
ContentResolver resolver = ContactsManager.getInstance().getContentResolver();
|
||||||
|
String result = null;
|
||||||
|
String[] projection = { ContactsContract.RawContacts._ID };
|
||||||
|
|
||||||
|
String selection = ContactsContract.RawContacts.CONTACT_ID + "=? AND " + ContactsContract.RawContacts.ACCOUNT_TYPE + "=?";
|
||||||
|
Cursor c = resolver.query(ContactsContract.RawContacts.CONTENT_URI, projection, selection, new String[] { getAndroidId(), ContactsManager.getInstance().getString(R.string.sync_account_type) }, null);
|
||||||
|
if (c != null) {
|
||||||
|
if (c.moveToFirst()) {
|
||||||
|
result = c.getString(c.getColumnIndex(ContactsContract.RawContacts._ID));
|
||||||
|
}
|
||||||
|
c.close();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createLinphoneTagIfNeeded() {
|
||||||
|
if (LinphoneManager.getInstance().getContext().getResources().getBoolean(R.bool.use_linphone_tag)) {
|
||||||
|
if (androidTagId == null && findLinphoneRawContactId() == null) {
|
||||||
|
createLinphoneContactTag();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createLinphoneContactTag() {
|
||||||
|
ArrayList<ContentProviderOperation> batch = new ArrayList<ContentProviderOperation>();
|
||||||
|
|
||||||
|
batch.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
|
||||||
|
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, ContactsManager.getInstance().getString(R.string.sync_account_type))
|
||||||
|
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, ContactsManager.getInstance().getString(R.string.sync_account_name))
|
||||||
|
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
batch.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
||||||
|
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||||
|
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
|
||||||
|
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, getFullName())
|
||||||
|
.build());
|
||||||
|
|
||||||
|
batch.add(ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI)
|
||||||
|
.withValue(ContactsContract.AggregationExceptions.TYPE, ContactsContract.AggregationExceptions.TYPE_KEEP_TOGETHER)
|
||||||
|
.withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, androidRawId)
|
||||||
|
.withValueBackReference(ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, 0)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
if (changesToCommit2.size() > 0) {
|
||||||
|
for(ContentProviderOperation cpo : changesToCommit2) {
|
||||||
|
batch.add(cpo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
ContactsManager.getInstance().getContentResolver().applyBatch(ContactsContract.AUTHORITY, batch);
|
||||||
|
androidTagId = findLinphoneRawContactId();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,9 @@ package org.linphone.compatibility;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.linphone.Contact;
|
|
||||||
import org.linphone.LinphoneContact;
|
import org.linphone.LinphoneContact;
|
||||||
import org.linphone.LinphoneUtils;
|
|
||||||
import org.linphone.R;
|
import org.linphone.R;
|
||||||
import org.linphone.core.LinphoneAddress;
|
import org.linphone.core.LinphoneAddress;
|
||||||
import org.linphone.mediastream.Log;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.ContentProviderOperation;
|
import android.content.ContentProviderOperation;
|
||||||
|
@ -195,89 +192,4 @@ public class ApiNinePlus {
|
||||||
cursor.close();
|
cursor.close();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Linphone Contacts Tag
|
|
||||||
public static void addLinphoneContactTag(Context context, ArrayList<ContentProviderOperation> ops, String newAddress, String rawContactId){
|
|
||||||
if(rawContactId != null) {
|
|
||||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactId)
|
|
||||||
.withValue(ContactsContract.Data.MIMETYPE, context.getString(R.string.sync_mimetype))
|
|
||||||
.withValue(ContactsContract.Data.DATA1, newAddress)
|
|
||||||
.withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name))
|
|
||||||
.withValue(ContactsContract.Data.DATA3, newAddress)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static void updateLinphoneContactTag(Context context, ArrayList<ContentProviderOperation> ops, String newAddress, String oldAddress, String rawContactId){
|
|
||||||
if(rawContactId != null) {
|
|
||||||
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withSelection(ContactsContract.Data.RAW_CONTACT_ID + "=? AND " + ContactsContract.Data.DATA1 + "=? ", new String[]{rawContactId, oldAddress})
|
|
||||||
.withValue(ContactsContract.Data.DATA1, newAddress)
|
|
||||||
.withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name))
|
|
||||||
.withValue(ContactsContract.Data.DATA3, newAddress)
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void deleteLinphoneContactTag(ArrayList<ContentProviderOperation> ops , String oldAddress, String rawContactId){
|
|
||||||
if(rawContactId != null) {
|
|
||||||
String select = ContactsContract.Data.RAW_CONTACT_ID + "=? AND "
|
|
||||||
+ ContactsContract.Data.DATA1 + "= ?";
|
|
||||||
String[] args = new String[]{rawContactId, oldAddress};
|
|
||||||
|
|
||||||
ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withSelection(select, args)
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void createLinphoneContactTag(Context context, ContentResolver contentResolver, Contact contact, String rawContactId){
|
|
||||||
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
|
|
||||||
|
|
||||||
if (contact != null) {
|
|
||||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
|
|
||||||
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT)
|
|
||||||
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, context.getString(R.string.sync_account_type))
|
|
||||||
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, context.getString(R.string.sync_account_name))
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
|
|
||||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
|
||||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, contact.getName())
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
|
|
||||||
List<String> numbersOrAddresses = contact.getNumbersOrAddresses();
|
|
||||||
for (String numberOrAddress : numbersOrAddresses) {
|
|
||||||
if (LinphoneUtils.isSipAddress(numberOrAddress)) {
|
|
||||||
if (numberOrAddress.startsWith("sip:")){
|
|
||||||
numberOrAddress = numberOrAddress.substring(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
|
||||||
.withValue(ContactsContract.Data.MIMETYPE, context.getString(R.string.sync_mimetype))
|
|
||||||
.withValue(ContactsContract.Data.DATA1, numberOrAddress)
|
|
||||||
.withValue(ContactsContract.Data.DATA2, context.getString(R.string.app_name))
|
|
||||||
.withValue(ContactsContract.Data.DATA3, numberOrAddress)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ops.add(ContentProviderOperation.newUpdate(ContactsContract.AggregationExceptions.CONTENT_URI)
|
|
||||||
.withValue(ContactsContract.AggregationExceptions.TYPE, ContactsContract.AggregationExceptions.TYPE_KEEP_TOGETHER)
|
|
||||||
.withValue(ContactsContract.AggregationExceptions.RAW_CONTACT_ID1, rawContactId)
|
|
||||||
.withValueBackReference(ContactsContract.AggregationExceptions.RAW_CONTACT_ID2, 0).build());
|
|
||||||
|
|
||||||
try {
|
|
||||||
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.linphone.Contact;
|
|
||||||
import org.linphone.LinphoneContact;
|
import org.linphone.LinphoneContact;
|
||||||
import org.linphone.core.LinphoneAddress;
|
import org.linphone.core.LinphoneAddress;
|
||||||
import org.linphone.mediastream.Version;
|
import org.linphone.mediastream.Version;
|
||||||
|
@ -301,32 +300,6 @@ public class Compatibility {
|
||||||
ApiFivePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID);
|
ApiFivePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Linphone Contacts Tag
|
|
||||||
public static void addLinphoneContactTag(Context context, ArrayList<ContentProviderOperation> ops, String newSipAddress, String rawContactId) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
ApiNinePlus.addLinphoneContactTag(context, ops, newSipAddress, rawContactId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void updateLinphoneContactTag(Context context, ArrayList<ContentProviderOperation> ops, String newSipAddress, String oldSipAddress, String rawContactId) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
ApiNinePlus.updateLinphoneContactTag(context, ops, newSipAddress, oldSipAddress, rawContactId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void deleteLinphoneContactTag(ArrayList<ContentProviderOperation> ops, String oldSipAddress, String rawContactId) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
ApiNinePlus.deleteLinphoneContactTag(ops, oldSipAddress, rawContactId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void createLinphoneContactTag(Context context, ContentResolver contentResolver, Contact contact, String rawContactId) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
ApiNinePlus.createLinphoneContactTag(context, contentResolver, contact, rawContactId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//End of Linphone Contact Tag
|
|
||||||
|
|
||||||
public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) {
|
public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) {
|
||||||
if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
||||||
ApiSixteenPlus.removeGlobalLayoutListener(viewTreeObserver, keyboardListener);
|
ApiSixteenPlus.removeGlobalLayoutListener(viewTreeObserver, keyboardListener);
|
||||||
|
|
Loading…
Reference in a new issue