android - 为来 self 自己的应用程序的来电提供来电显示

标签 android ios android-contentprovider contacts ios-extensions

我想编写一个应用程序,通过查看我的应用程序内的一个表(例如 SQLite 数据库表)来识别来电(未知)的电话号码。

我已经在 iOS 中使用 Call Directory Extension 实现了这个,但对于 Android,我能找到的唯一选择是使用 BroadcastReceiver with a popup above the native incoming call screen显示联系信息。

ContactsContract.Directory似乎提供了创建自定义目录的可能性, native 调用应用程序可以在其中查找来电显示。不幸的是,我找不到任何关于如何实现这一点的好例子。

有谁知道是否可以使用 ContactsContract.Directory 实现来电显示,或者在 Android 中是否有类似于 Android 中的 Call Directory Extension 的东西?如果是这种情况,示例代码将非常有用。

最佳答案

我只是勉强写了一篇关于如何让它工作的教程。在这里查看:https://simplenexus.dev/2019/08/27/android-caller-id.html

如何使这个工作的基础是:

AndroidManifest.xml

<provider
android:name=".callerid.CallerIDProvider"
android:authorities="@string/callerid_authority"
android:readPermission="android.permission.READ_CONTACTS"
android:enabled="true"
android:exported="true">
<meta-data
  android:name="android.content.ContactDirectory"
  android:value="true"/></provider>

来电显示提供者.kt

private var userRepository: UserRepository? = null

private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH)

override fun onCreate(): Boolean {
    context?.let {
        val userDao = UserDatabase.getDatabase(it).userDao()
        userRepository = UserRepository(userDao)
        val authority = it.getString(R.string.callerid_authority)
        uriMatcher.addURI(authority, "directories", DIRECTORIES)
        uriMatcher.addURI(authority, "phone_lookup/*", PHONE_LOOKUP)
    }
    return true
}

override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? {
    when (uriMatcher.match(uri)) {
        DIRECTORIES -> {
            val label = context?.getString(R.string.app_name) ?: return null
            val cursor = MatrixCursor(projection)
            projection?.map { column ->
                when (column) {
                    Directory.ACCOUNT_NAME,
                    Directory.ACCOUNT_TYPE,
                    Directory.DISPLAY_NAME -> label
                    Directory.TYPE_RESOURCE_ID -> R.string.app_name
                    Directory.EXPORT_SUPPORT -> Directory.EXPORT_SUPPORT_SAME_ACCOUNT_ONLY
                    Directory.SHORTCUT_SUPPORT -> Directory.SHORTCUT_SUPPORT_NONE
                    else -> null
                }
            }?.let { cursor.addRow(it) }
            return cursor
        }
        PHONE_LOOKUP -> {
            userRepository?.let { userRepo ->
                val phoneNumber = uri.pathSegments[1]
                val cursor = MatrixCursor(projection)
                val user = runBlocking(Dispatchers.IO) { userRepo.getUser(phoneNumber) }
                user?.let { u ->
                    projection?.map { column ->
                        when (column) {
                            PhoneLookup._ID -> -1
                            PhoneLookup.DISPLAY_NAME -> u.fullName
                            PhoneLookup.LABEL -> u.phoneLabel
                            else -> null
                        }
                    }?.let { cursor.addRow(it) }
                }
                return cursor
            }
        }
    }
    return null
}

关于android - 为来 self 自己的应用程序的来电提供来电显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48870782/

相关文章:

android - 如何将 Material 设计库导入 Android Studio?

objective-c - 如何像 iTunes 排序一样对 NSString 进行排序?

ios - Twitter Fabric 登录 iOS 如何更改应用程序 key

java - Android ContentResolver.update() 产生重复项

android - 事件的最后编辑? Android 日历提供商

android - 用于在未启动的android和服务器之间同步数据的SyncService

android - 如何以编程方式检测应用程序是否在三星 "Edge"屏幕上运行?

java - Firebase Firestore 在运行时错误时崩溃

android - 增强现实框架

ios - 如何以编程方式创建 View 层次结构?