赞
踩
<uses-permission android:name="android.intent.action.BOOT_COMPLETED" />
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/makeCall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="make call" />
</LinearLayout>
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
makeCall.setOnClickListener {
try {
val intent = Intent(Intent.ACTION_CALL)
intent.data = Uri.parse("tel:10086")
startActivity(intent)
} catch (e: SecurityException) {
e.printStackTrace()
}
}
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
makeCall.setOnClickListener {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.CALL_PHONE
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CALL_PHONE), 1)
} else {
call()
}
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
1 -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
call()
} else {
Toast.makeText(
this, "You denied the permission", Toast.LENGTH_SHORT
).show()
}
}
}
}
/**
* 拨打电话的逻辑
*/
private fun call() {
try {
val intent = Intent(Intent.ACTION_CALL)
intent.data = Uri.parse("tel:10086")
startActivity(intent)
} catch (e: SecurityException) {
e.printStackTrace()
}
}
}
content://com.example.app.provider/table1
content://com.example.app.provider/table2
val uri = Uri.parse("content://com.example.app.provider/table1")
val cursor = contentResolver.query (
uri,
projection,
selection,
selectionArgs,
sortOrder
)
while(cursor.moveToNext()) {
val column1 = cursor.getString(cursor.getColumnIndex("column1"))
val column2 = cursor.getString(cursor.getColumnIndex("column2"))
}
cursor.close()
//将待添加的数据添加到contentValues当中
val values = contentValuesOf("column1" to "text", "column2" to 1)
//然后调用contentResolver的insert()方法,将uri和ContentValues作为参数传入即可
contentResolver.insert(uri, values)
val values = contentValuesOf("column1" to "")
contentResolver.update(uri, values, "column1 = ? and column2 = ?", arrayOf("text", " 1"))
contentResolver.delete(uri, "column2 = ?", arrayOf("1"))
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/contactsView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
class MainActivity : AppCompatActivity() {
private val contactsList = ArrayList<String>()
private lateinit var adapter: ArrayAdapter<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, contactsList)
contactsView.adapter = adapter
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.READ_CONTACTS), 1
)
} else {
readContacts()
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
1 -> {
if (grantResults.isNotEmpty()
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
) {
readContacts()
} else {
Toast.makeText(this, "你没有权限", Toast.LENGTH_SHORT).show()
}
}
}
}
/**
* 查询联系人数据
*/
@SuppressLint("Range")
private fun readContacts() {
contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null, null
)?.apply {
while (moveToNext()) {
//获取联系人姓名
val displayName = getString(
getColumnIndex
(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)
)
//获取联系人手机号码
val number = getString(
getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER
)
)
//将两个数据取出来之后进行拼接
contactsList.add("$displayName\n$number")
}
adapter.notifyDataSetChanged()
close()
}
}
}
在onCreate()方法当中,我们首先按照ListView的标准用法对其进行初始化,然后开始调用运行时权限进行逻辑处理,因为READ_CONTACTS权限属于是危险权限了,这里我们在用户进行授权之后,调用readContacts()方法读取系统联系人信息.
readContacts()方法,可以看到使用了ContentResolver的query()方法查询系统的联系人数据
不过传入的Uri参数并没有调用Uri.parse()方法去解析一个内容URI字符串,这是因为ContactsContract.CommonDataKinds.Phone类已经帮我们做好了封装,提供了一个CONTENT_URI常量,这个常量就是使用Uri.parse()方法解析出来的结果.
接着我们对query()方法返回的Cursor对象进行遍历,这里使用了?.操作符和apply函数来简化遍历的代码
在apply函数当中将联系人姓名和手机号逐个取出,联系人姓名这一列对应的常量是ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
联系人电话号码对应的常量是:ContactsContract.CommonDataKinds.Phone.NUMBER
将两个数据取出来之后进行拼接,并且在中间加上换行符号,然后将拼接的数据放到ListView的数据源里面
并且通知刷新一下ListView,最后千万不要忘记了Cursor对象的关闭
最后我们还需要在AndroidManifest.xml文件当中声明读取联系人的权限
所以总的来说在自己的程序当中访问其他程序当中的数据,还是比较简单的,只需要获得该应用程序的内容URI,然后借助ContentResolver进行增删改查就可以
class MyProvider : ContentProvider() {
override fun onCreate(): Boolean {
TODO("Not yet implemented")
}
override fun query(
uri: Uri,
projection: Array<out String>?,
selection: String?,
selectionArgs: Array<out String>?,
sortOrder: String?
): Cursor? {
TODO("Not yet implemented")
}
override fun getType(uri: Uri): String? {
TODO("Not yet implemented")
}
override fun insert(uri: Uri, values: ContentValues?): Uri? {
TODO("Not yet implemented")
}
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int {
TODO("Not yet implemented")
}
override fun update(
uri: Uri,
values: ContentValues?,
selection: String?,
selectionArgs: Array<out String>?
): Int {
TODO("Not yet implemented")
}
}
content://com.example.app.provider/table1
content://com.example.app.provider/table1/1
content://com.example.app.provider/*
content://com.example.app.provider/table1/#
class MyProvider : ContentProvider() {
/**
* 表示访问table1表中的所有数据
*/
private val table1Dir = 0
/**
* 表示访问table1表中的单条数据
*/
private val table1Item = 1
private val table2Dir = 2
private val table2Item = 3
/**
* 在MyProvider实例化的时候就创建UriMatcher实例
*/
private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
/**
* 调用addURI()方法,将期望匹配的内容URI格式传递进去
*/
init {
uriMatcher.addURI("com.example.app.provider", "table1", table1Dir)
uriMatcher.addURI("com.example.app.provider", "table1/#", table1Item)
uriMatcher.addURI("com.example.app.provider", "table2", table2Dir)
uriMatcher.addURI("com.example.app.provider", "table2/#", table2Item)
}
override fun onCreate(): Boolean {
TODO("Not yet implemented")
}
override fun query(
uri: Uri,
projection: Array<out String>?,
selection: String?,
selectionArgs: Array<out String>?,
sortOrder: String?
): Cursor? {
when(uriMatcher.match(uri)) {
table1Dir -> {
//查询table1表中的所有数据
}
table1Item -> {
//查询table1表当中的单条数据
}
table2Dir -> {
//查询table2表中的所有数据
}
table2Item -> {
//查询table2表当中的所有数据
}
}
}
override fun getType(uri: Uri): String? {
TODO("Not yet implemented")
}
override fun insert(uri: Uri, values: ContentValues?): Uri? {
TODO("Not yet implemented")
}
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int {
TODO("Not yet implemented")
}
override fun update(
uri: Uri,
values: ContentValues?,
selection: String?,
selectionArgs: Array<out String>?
): Int {
TODO("Not yet implemented")
}
}
- 必须以vnd开头
- 如果内容URI以路径结尾,则后接android.cursor.dir/;如果内容URI以id结尾,则后接android.cursor.item/
- 最后街上vnd..
van.android.cursor.dir/vnd.com.example.app.provider.table1
van.android.cursor.item/vnd.com.example.app.provider.table1
override fun getType(uri: Uri) = when (uriMatcher.match(uri)) {
table1Dir -> "van.android.cursor.dir/vnd.com.example.app.provider.table1"
table1Item -> "van.android.cursor.item/vnd.com.example.app.provider.table1"
table2Dir -> "van.android.cursor.dir/vnd.com.example.app.provider.table2"
table2Item -> "van.android.cursor.item/vnd.com.example.app.provider.table2"
else -> null
}
class DatebaseProvider : ContentProvider() {
private val bookDir = 0
private val bookItem = 1
private val categoryDir = 2
private val categoryItem = 3
private val authority = "com.zb.databasetest.provider"
private var dbHelper: MyDatabaseHelper? = null
/**
* by lazy 懒加载机制对UriMatcher进行初始化操作
*/
private val uriMather by lazy {
val matcher = UriMatcher(UriMatcher.NO_MATCH)
matcher.addURI(authority, "book", bookDir)
matcher.addURI(authority, "book/#", bookItem)
matcher.addURI(authority, "category", categoryDir)
//代码块的最后一行代码,赋值给uriMather
matcher
}
/**
* 删除数据
*
* @param uri Uri
* @param selection String?
* @param selectionArgs Array<String>?
*/
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?) =
dbHelper?.let {
//删除数据
val db = it.writableDatabase
val deletedRows = when (uriMather.match(uri)) {
bookDir -> db.delete("Book", selection, selectionArgs)
bookItem -> {
val bookId = uri.pathSegments[1]
db.delete("Book", "id = ?", arrayOf(bookId))
}
categoryDir -> db.delete("Category", selection, selectionArgs)
categoryItem -> {
val categoryId = uri.pathSegments[1]
db.delete("Category", "id = ?", arrayOf(categoryId))
}
else -> 0
}
deletedRows
} ?: 0
override fun getType(uri: Uri) = when (uriMather.match(uri)) {
bookDir -> "vnd.android.cursor.dir/vnd.com.zb.databasetest.provider.book"
bookItem -> "vnd.android.cursor.item/vnd.com.zb.databasetest.provider.book"
categoryDir -> "vnd.android.cursor.dir/vnd.com.zb.databasetest.provider.category"
categoryItem -> "vnd.android.cursor.item/vnd.com.zb.databasetest.provider.category"
else -> null
}
/**
* 添加数据
* @param uri Uri
* @param values ContentValues?
* @return Uri?
*/
override fun insert(uri: Uri, values: ContentValues?) = dbHelper?.let {
//添加数据
val db = it.writableDatabase
val uriReturn = when (uriMather.match(uri)) {
bookDir, bookItem -> {
val newBookId = db.insert("Book", null, values)
Uri.parse("content://$authority/book/$newBookId")
}
categoryDir, categoryItem -> {
val newCategoryId = db.insert("Category", null, values)
Uri.parse("content://$authority/category/$newCategoryId")
}
else -> null
}
uriReturn
}
override fun onCreate() = context?.let {
dbHelper = MyDatabaseHelper(it, "BookStore.db", 2)
true
} ?: false
/**
* 查询数据
* @param uri Uri
* @param projection Array<String>?
* @param selection String?
* @param selectionArgs Array<String>?
* @param sortOrder String?
* @return Cursor?
*/
override fun query(
uri: Uri, projection: Array<String>?, selection: String?,
selectionArgs: Array<String>?, sortOrder: String?
) = dbHelper?.let {
//查询数据
val db = it.readableDatabase
val cursor = when (uriMather.match(uri)) {
bookDir -> db.query(
"Book", projection, selection, selectionArgs,
null, null, sortOrder
)
bookItem -> {
val bookId = uri.pathSegments[1]
db.query(
"Book", projection, "id = ?", arrayOf(bookId), null, null,
sortOrder
)
}
categoryDir -> db.query(
"Category", projection, selection, selectionArgs,
null, null, sortOrder
)
categoryItem -> {
val categoryId = uri.pathSegments[1]
db.query(
"Category",
projection,
"id = ?",
arrayOf(categoryId),
null,
null,
sortOrder
)
}
else -> null
}
cursor
}
/**
* 更新数据
*
* @param uri Uri
* @param values ContentValues?
* @param selection String?
* @param selectionArgs Array<String>?
*/
override fun update(
uri: Uri, values: ContentValues?, selection: String?,
selectionArgs: Array<String>?
) = dbHelper?.let {
//更新数据
val db = it.writableDatabase
val updateRows = when (uriMather.match(uri)) {
bookDir -> db.update("Book", values, selection, selectionArgs)
bookItem -> {
val bookId = uri.pathSegments[1]
db.update("Book", values, "id = ?", arrayOf(bookId))
}
categoryDir -> db.update("Category", values, selection, selectionArgs)
categoryItem -> {
val categoryId = uri.pathSegments[1]
db.update("Category", values, "id = ?", arrayOf(categoryId))
}
else -> 0
}
updateRows
} ?: 0
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/addData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add To Book" />
<Button
android:id="@+id/queryData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Query From Book" />
<Button
android:id="@+id/updateData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Update Book" />
<Button
android:id="@+id/deleteData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Delete From Book" />
</LinearLayout>
class MainActivity : AppCompatActivity() {
var bookId: String? = null
@SuppressLint("Range")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
addData.setOnClickListener {
//添加数据
val uri = Uri.parse("content://com.zb.databasetest.provider/book")
val values = contentValuesOf(
"name" to "A Clash of Kings",
"author" to "George Martin", "pages" to 1040, "price" to 22.5
)
val newUri = contentResolver.insert(uri, values)
bookId = newUri?.pathSegments?.get(1)
}
queryData.setOnClickListener {
//查询数据
val uri = Uri.parse("content://com.zb.database")
contentResolver.query(uri, null, null, null, null)?.apply {
while (moveToNext()) {
val name = getString(getColumnIndex("name"))
val author = getString(getColumnIndex("author"))
val pages = getInt(getColumnIndex("pages"))
val price = getDouble(getColumnIndex("price"))
Log.d("MainActivity", "book name is $name")
Log.d("MainActivity", "book author is $author")
Log.d("MainActivity", "book pages is $pages")
Log.d("MainActivity", "book price is $price")
}
close()
}
}
updateData.setOnClickListener {
//更新数据
bookId?.let {
val uri = Uri.parse("content://com.zb.database.provider/book/$it")
val values = contentValuesOf(
"name" to "A Storm of Swords",
"pages" to 1216,
"price" to 24.05
)
contentResolver.update(uri, values, null, null)
}
}
deleteData.setOnClickListener {
//删除数据
bookId?.let {
val uri = Uri.parse("content://com.zb.databasetest.provider/book/$it")
contentResolver.delete(uri, null, null)
}
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。