Unblock Contact Android • Ad-Free

// 5. Reset local spam confidence for that number val pm = context.getSystemService(ProtectionManager::class.java) // Android 14+ pm.resetSpamFeedback(normalized)

Unblocking via the Contacts app must issue a ContentResolver.delete() on BlockedNumberContract.BlockedNumbers.CONTENT_URI and update the raw_contacts table. If either transaction fails (e.g., database lock), the contact appears unblocked in the UI but remains blocked by the telephony stack. 4. The Unblock Transaction: Atomicity Analysis Executing an unblock triggers the following sequence (Android 13+): unblock contact android

// 2. Delete from legacy SMS block table (if using AOSP messaging) context.contentResolver.delete( Uri.parse("content://sms/blocked"), "address = ?", arrayOf(normalized) ) Delete from system blocked provider context

fun fullyUnblockContact(context: Context, phoneNumber: String, subId: Int) val normalized = PhoneNumberUtils.normalizeNumber(phoneNumber) // 1. Delete from system blocked provider context.contentResolver.delete( BlockedNumbers.CONTENT_URI, "number = ?", arrayOf(normalized) ) "number = ?"

The SMS/MMS app maintains its own blocked table: content://sms/blocked . This table is not automatically synced with the BlockedNumberProvider on unblock. Google Messages and Samsung Messages use a periodic sync job (run every 6-12 hours). Therefore, unblocking a contact does not immediately unblock SMS delivery.

| Storage Location | URI / Path | Purpose | | :--- | :--- | :--- | | | content://com.android.blockednumber/blocked | Primary source of truth for telephony. | | Contacts DB | data/data/com.android.providers.contacts/databases/contacts.db (Table: raw_contacts ) | Marks STARRED (0) and CUSTOM_RINGTONE (null) but also flags CONTACT_STATUS for blocked. | | Call Log | content://call_log/calls | Adds CALL_BLOCK_REASON column (Value: 1 for user block). | | SMS Provider | content://sms/blocked | Isolated blocking for Messaging app. |