安卓开发入门教程-ContentProvider
2020-11-04 本文已影响0人
蓝不蓝编程
什么是ContentProvider
ContentProvider时安卓提供的跨应用共享数据的一种方式,它允许一个应用安全的访问另外一个应用提供的数据.
调用系统提供的ContentProvider-访问通讯录
效果图:
实现方案
- 在AndroidManifest.xml中添加权限
<uses-permission android:name="android.permission.READ_CONTACTS" />
- 在app模块build.gradle文件中添加依赖
//用于简化动态权限申请
implementation 'com.qw:soulpermission:1.3.0'
- 访问通讯录代码
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//对按钮添加点击事件
button.setOnClickListener {
readContactsWithPermission()
}
}
/**
* 先申请读取系统通讯录权限,再进行读取。
*/
private fun readContactsWithPermission() {
SoulPermission.getInstance()
.checkAndRequestPermission(
Manifest.permission.READ_CONTACTS,
object : CheckRequestPermissionListener {
override fun onPermissionOk(permission: Permission) {
readContacts()
}
override fun onPermissionDenied(permission: Permission) {
toast("请授予权限")
}
})
}
/**
* 读取系统通讯录并展示总数和其中一个联系人的姓名与电话。
*/
private fun readContacts() {
val contacts: ArrayList<String> = getContactsInfo()
contacts.forEach {
Log.d("MainActivity", "联系人信息:$it")
}
}
/**
* 读取系统通讯录信息
*/
private fun getContactsInfo(): ArrayList<String> {
val dataList = ArrayList<String>()
val cursor = contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null
)
if (cursor != null) {
while (cursor.moveToNext()) {
val displayName =
cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
val phone =
cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
dataList.add("$displayName:$phone")
}
cursor.close()
}
return dataList
}
private fun toast(text: String) =
Toast.makeText(this, text, Toast.LENGTH_LONG).show()
}
自定义ContentProvider
效果图
1. 创建ContentProvider
1). 在工程目录中单击右键,选择“New>Other>Content Provider”
2). 在窗口中设置Class Name(类名)和URI Authorities(一个全局唯一的路径,一般以自己的包名开头)
3). 创建后的ContentProvider过于冗长,此处略去.
4). 查看AndroidManifest.xml文件,里面应该已经增加了如下provider配置.
<manifest ...>
<application ...>
<provider
android:name=".MyContentProvider"
android:authorities="com.add007.providerdemo"
android:enabled="true"
android:exported="true"></provider>
...
</application>
</manifest>
2. 添加数据库操作类
/**
* 数据库辅助操作类
*/
class DbHelper
(context: Context?, databaseName: String, version: Int) : SQLiteOpenHelper(
context, databaseName, null, version
) {
//创建用户表的sql语句,表名:user_table,包含主键_id,用户名字段:user_name。
private var createUserTableSql =
("CREATE TABLE user_table(_id INTEGER PRIMARY KEY, user_name text)")
/**
* 创建数据库表
*/
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(createUserTableSql)
}
/**
* 数据库升级
*/
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
val sql = "DROP TABLE IF EXISTS user_table"
db.execSQL(sql)
onCreate(db)
}
/**
* 插入数据
*/
fun insert(tableName: String, cv: ContentValues) = writableDatabase.insert(tableName, null, cv)
/**
* 删除指定数据
*/
fun delete(tableName: String, id: Int): Int {
val where = "_id = ?"
val whereValue = arrayOf(id.toString())
return writableDatabase.delete(tableName, where, whereValue)
}
/**
* 删除所有数据
*/
fun deleteAll(tableName: String) = writableDatabase.delete(tableName, null, null)
/**
* 更新数据
*/
fun update(
tableName: String, values: ContentValues, whereClause: String?, whereArgs: Array<String>?
) = writableDatabase.update(tableName, values, whereClause, whereArgs)
/**
* 查询数据,返回一个指定数据集合的游标
*/
fun query(tableName: String): Cursor {
return readableDatabase.query(tableName, null, null, null, null, null, null)
}
}
3. 修改ContentProvider类
class MyContentProvider : ContentProvider() {
private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
private val authority = "cn.cxy.contentproviderdemo.provider"
private val allUsers = 1 //返回多个记录的匹配码
private val singleUser = 2 //返回单个记录的匹配码
private lateinit var dbHelper: DbHelper
private val userTable = "user_table"
/**
* 配置本应用支持的路径后缀
*/
init {
uriMatcher.addURI(authority, "user", allUsers);
uriMatcher.addURI(authority, "user/#", singleUser);
}
/**
* 创建存储数据的数据库
*/
override fun onCreate(): Boolean {
dbHelper = DbHelper(context, "userTable", 1)
return true
}
override fun getType(uri: Uri) = when (uriMatcher.match(uri)) {
singleUser -> "vnd.android.cursor.item/vnd.cn.cxy.contentproviderdemo.provider.user"
allUsers -> "vnd.android.cursor.dir/vnd.cn.cxy.contentproviderdemo.provider.user"
else -> null
}
/**
* 插入数据
*/
override fun insert(uri: Uri, values: ContentValues?): Uri? {
var resultUri: Uri? = null
when (uriMatcher.match(uri)) {
singleUser, allUsers -> {
var userId = dbHelper.insert(userTable, values!!)
resultUri = Uri.parse("content://$authority/user/${userId}")
}
}
return resultUri
}
/**
* 更新数据
*/
override fun update(
uri: Uri, values: ContentValues?, selection: String?,
selectionArgs: Array<String>?
) = dbHelper.update("user_table", values!!, null, null)
/**
* 删除数据
*/
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
when (uriMatcher.match(uri)) {
singleUser, allUsers -> {
dbHelper.deleteAll(userTable)
}
}
return 0
}
/**
* 查询数据
*/
override fun query(
uri: Uri, projection: Array<String>?, selection: String?,
selectionArgs: Array<String>?, sortOrder: String?
) = dbHelper.query("user_table")
}
4. activity中调用
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
addDataBtn.setOnClickListener { addUser() }
updateDataBtn.setOnClickListener { updateUser() }
delDataBtn.setOnClickListener { delUser() }
queryDataBtn.setOnClickListener { queryUser() }
}
/**
* 新增数据
*/
private fun addUser() {
GlobalScope.launch(Dispatchers.IO) {
val uri: Uri = Uri.parse("content://cn.cxy.contentproviderdemo.provider/user")
val values = ContentValues().apply { put("user_name", "张三") }
contentResolver.insert(uri, values)
}
}
/**
* 更新数据
*/
private fun updateUser() {
GlobalScope.launch(Dispatchers.IO) {
val uri: Uri = Uri.parse("content://cn.cxy.contentproviderdemo.provider/user")
val values = ContentValues().apply { put("user_name", "李四") }
contentResolver.update(uri, values, null, null)
}
}
/**
* 删除数据
*/
private fun delUser() {
GlobalScope.launch(Dispatchers.IO) {
val uri: Uri = Uri.parse("content://cn.cxy.contentproviderdemo.provider/user")
contentResolver.delete(uri, null, null)
}
}
/**
* 查询数据
*/
private fun queryUser() {
GlobalScope.launch(Dispatchers.IO) {
val uri = Uri.parse("content://cn.cxy.contentproviderdemo.provider/user")
val cursor = contentResolver.query(uri, null, null, null, null)
if (cursor != null) {
var count = 0
while (cursor.moveToNext()) {
val id = cursor.getInt(cursor.getColumnIndexOrThrow("_id"))
val name = cursor.getString(cursor.getColumnIndexOrThrow("user_name"))
Log.d("MainActivity", "用户:${id}_$name")
count++
}
cursor.close()
if (count == 0) {
Log.d("MainActivity", "数据库是空的!")
}
}
}
}
}