搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
木道寻08
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
vscode 文件无法修改一直亮光标解决办法_vscode光标移动但无法编辑
2
无法解析的外部符号 "class google::protobuf::internal::ExplicitlyConstructed fixed_address_empty_string
3
如何正确使用迁移学习_迁移学习 尺寸
4
unable to connect to 192.168.1.110:5555 解决办法(不用RootAndroid设备)_already connected to 192.168.1.110:5555
5
Java反序列化漏洞利用及修复 示例代码_java 反序列化漏洞利用
6
Android Studio 模块打aar 引入aar详细步骤_androidstudio引入aar包
7
算法数据结构——玩转递归算法(Recursion)使用套路及具体应用实例讲解_数据结构递归模型
8
Charles修改参数_charlos修改参数,可以无视入参吗
9
AI Agent: AI的下一个风口 具身智能的定义与特点_具身智能agent
10
Xcode检测不到iPhone设备_xcode无法识别ios17系统以上的手机
当前位置:
article
> 正文
ContentProvider_
作者:木道寻08 | 2024-08-17 14:52:05
赞
踩
一、什么是ContentProvider?
ContentProvider是一个抽象类,可以理解为一个特殊的存储数据的类型,它提供了一套标准的接口来获取和操作数据。可以把数据封装到ContentProvider 中,从而是这些数据可以被其他的应用程序所共享。搭建起了所有应用程序之间数据交换的桥梁!
二、ContentProvider的创建过程
1.创建一个类继承ContentProvider
继承它需要实现其所有的抽象方法
a.onCreate() :初始化该ContentProvider
b.query(Uri,String[],String,Sring[],String) :通过Uri进行查询,返回Uri
c.intert(Uri,ContentValues):将数据插入到Uri所指定的位置
d.update(Uri,ContentValues,String,String []):更新uri指定位置的数据
e.delete(Uri,String,String[]):删除uri指定位置的数据
f.getType(Uri):返回数据的类型
2.声明CONTENT_URI,实现UriMatcher
每个ContentProvider都会对外提供一个公共的Uri,当有数据共享的时候,就需要使用ContentProvider为这些数据定义一个Uri,
UriMatcher是一个用来匹配Uri的工具类
public static final String AUTHORITY="com.example.provider.students";
private static final UriMatcher Urimatcher;
Urimatcher=new UriMatcher(UriMatcher.NO_MATCH);
//添加需要匹配的Uri,匹配则返回相应的匹配码
Urimatcher.addURI(Students.AUTHORITY, "student", STUDENT);
Urimatcher.addURI(Students.AUTHORITY, "student/#", STUDENT_ID);
3.在AndroidManifest.xml中注册
<provider
android:name=".StudentContentProvider"
android:authorities="com.example.provider.students"
/>
三、ContentProvider的使用实例
1.常量类,声明需要使用的常量
点击(
此处
)折叠或打开
package
com
.
example
.
provider
;
import
android
.
net
.
Uri
;
import
android
.
provider
.
BaseColumns
;
/**
*
* @author zt
*常量类,声明要使用的常量
*内部类Student实现了BaseColumns接口,该接口也是一个常量接口
该常量接口中已经定义了_id和_count常量,分别用来表示记录的id和已经记录的数量
*/
public
final
class
Students
{
//定义常量
public
static
final
String
AUTHORITY
=
"com.example.provider.students"
;
private
Students
(
)
{
}
//内部类
public
static
final
class
Student
implements
BaseColumns
{
private
Student
(
)
{
}
//构造方法
public
static
final
Uri
CONTENT_URI
=
Uri
.
parse
(
"content://"
+
AUTHORITY
+
"/student"
)
;
public
static
final
String
CONTENT_TYPE
=
"vnd.android.cursor.dir/vnd.example.provider.students"
;
public
static
final
String
CONTENT_ITEM_TYPE
=
"vnd.android.cursor.item/vnd.example.provider.students"
;
//数据库中的表字段
public
static
final
String
NMAE
=
"name"
;
//姓名
public
static
final
String
GENDER
=
"gender"
;
//性别
public
static
final
String
AGE
=
"age"
;
//年龄
}
}
2.利用数据库帮助类SQLiteOpenHelper来创建数据库
点击(
此处
)折叠或打开
package
com
.
example
.
provider
;
import
com
.
example
.
provider
.
Students
.
Student
;
import
android
.
content
.
Context
;
import
android
.
database
.
sqlite
.
SQLiteDatabase
;
import
android
.
database
.
sqlite
.
SQLiteOpenHelper
;
public
class
DbHelper
extends
SQLiteOpenHelper
{
//数据库的名称
private
static
final
String
DATABASE_NAME
=
"student.db"
;
private
static
final
int
DATABASE_VERSION
=
1
;
public
static
final
String
TABLE_NAME
=
"student"
;
public
DbHelper
(
Context
context
)
{
super
(
context
,
DATABASE_NAME
,
null
,
DATABASE_VERSION
)
;
}
/**
* 创建table
*/
@
Override
public
void
onCreate
(
SQLiteDatabase db
)
{
//创建学生信息表,包括四个字段
//包括id、姓名、性别、年龄
String
sql
=
"create table "
+
TABLE_NAME
+
" ("
+
Student
.
_ID
+
" integer primary key,"
+
Student
.
NMAE
+
" text,"
+
Student
.
GENDER
+
" text,"
+
Student
.
AGE
+
" integer "
+
");"
;
db
.
execSQL
(
sql
)
;
}
/**
* 更新表
*/
@
Override
public
void
onUpgrade
(
SQLiteDatabase db
,
int
oldVersion
,
int
newVersion
)
{
String
sql
=
"drop table if exits student"
;
db
.
execSQL
(
sql
)
;
}
}
3.创建StudentContentProvider类继承ContentProvider
点击(
此处
)折叠或打开
package
com
.
example
.
provider
;
import
java
.
util
.
HashMap
;
import
com
.
example
.
provider
.
Students
.
Student
;
import
android
.
content
.
ContentProvider
;
import
android
.
content
.
ContentResolver
;
import
android
.
content
.
ContentUris
;
import
android
.
content
.
ContentValues
;
import
android
.
content
.
UriMatcher
;
import
android
.
database
.
Cursor
;
import
android
.
database
.
sqlite
.
SQLiteDatabase
;
import
android
.
net
.
Uri
;
import
android
.
text
.
TextUtils
;
public
class
StudentContentProvider
extends
ContentProvider
{
//声明数据库帮助类对象
private
DbHelper dbHelper
;
//定义ContentResolver 对象
private
ContentResolver
resolver
;
//定义Uri工具类
private
static
final
UriMatcher Urimatcher
;
//匹配码
private
static
final
int
STUDENT
=
1
;
private
static
final
int
STUDENT_ID
=
2
;
//需要查询 的列集合
private
static
HashMap
<
String
,
String
>
stu
;
//
static
{
Urimatcher
=
new
UriMatcher
(
UriMatcher
.
NO_MATCH
)
;
//添加需要匹配的Uri,匹配则返回相应的匹配码
Urimatcher
.
addURI
(
Students
.
AUTHORITY
,
"student"
,
STUDENT
)
;
Urimatcher
.
addURI
(
Students
.
AUTHORITY
,
"student/#"
,
STUDENT_ID
)
;
//实例化集合
stu
=
new
HashMap
<
String
,
String
>
(
)
;
//添加查询列map
stu
.
put
(
Student
.
_ID
,
Student
.
_ID
)
;
stu
.
put
(
Student
.
NMAE
,
Student
.
NMAE
)
;
stu
.
put
(
Student
.
GENDER
,
Student
.
GENDER
)
;
stu
.
put
(
Student
.
AGE
,
Student
.
AGE
)
;
}
/**
* 初始化
*/
@
Override
public
boolean
onCreate
(
)
{
//创建DbHelper对象
dbHelper
=
new
DbHelper
(
getContext
(
)
)
;
return
true
;
}
/**
* 查询数据
*/
@
Override
public
Cursor
query
(
Uri
uri
,
String
[
]
projection
,
String
selection
,
String
[
]
selectionArgs
,
String
sortOrder
)
{
SQLiteDatabase db
=
dbHelper
.
getReadableDatabase
(
)
;
Cursor
cursor
;
switch
(
Urimatcher
.
match
(
uri
)
)
{
case
STUDENT
:
cursor
=
db
.
query
(
DbHelper
.
TABLE_NAME
,
projection
,
selection
,
selectionArgs
,
null
,
null
,
sortOrder
)
;
break
;
case
STUDENT_ID
:
String
stuId
=
uri
.
getPathSegments
(
)
.
get
(
1
)
;
String
where
=
"Student._ID="
+
stuId
;
if
(
selection!=null
&
&
""
.
equals
(
selection
.
trim
(
)
)
)
//trim()函数的功能是去掉首尾空格
{
where
+
=
" and "
+
selection
;
}
cursor
=
db
.
query
(
DbHelper
.
TABLE_NAME
,
projection
,
where
,
selectionArgs
,
null
,
null
,
sortOrder
)
;
break
;
default
:
//如果传进来的Uri不是我们需要的类型
throw
new
IllegalArgumentException
(
"this is Unknown Uri:"
+
uri
)
;
}
return
cursor
;
}
/**
* 获得类型
*/
@
Override
public
String
getType
(
Uri
uri
)
{
return
null
;
}
/**
* 插入数据
*/
@
Override
public
Uri
insert
(
Uri
uri
,
ContentValues
values
)
{
//获得可写入的数据库
SQLiteDatabase db
=
dbHelper
.
getWritableDatabase
(
)
;
ContentResolver
resolver
=
this
.
getContext
(
)
.
getContentResolver
(
)
;
//插入数据,返回行号ID
long
rowid
=
db
.
insert
(
DbHelper
.
TABLE_NAME
,
Student
.
NMAE
,
values
)
;
//如果插入成功,返回Uri
if
(
rowid
>
0
)
{
Uri
stuUri
=
ContentUris
.
withAppendedId
(
uri
,
rowid
)
;
resolver
.
notifyChange
(
stuUri
,
null
)
;
//数据发送变化时候,发出通知给注册了相应uri的
return
stuUri
;
}
return
null
;
}
/**
* 删除数据
*/
@
Override
public
int
delete
(
Uri
uri
,
String
selection
,
String
[
]
selectionArgs
)
{
SQLiteDatabase db
=
dbHelper
.
getWritableDatabase
(
)
;
resolver
=
this
.
getContext
(
)
.
getContentResolver
(
)
;
int
count
;
//根据返回的匹配码进行相应的删除动作
switch
(
Urimatcher
.
match
(
uri
)
)
{
case
STUDENT
:
count
=
db
.
delete
(
DbHelper
.
TABLE_NAME
,
selection
,
selectionArgs
)
;
break
;
case
STUDENT_ID
:
//只删除对于的id
//getPathSegments()方法得到一个String的List
String
stuId
=
uri
.
getPathSegments
(
)
.
get
(
1
)
;
count
=
db
.
delete
(
DbHelper
.
TABLE_NAME
,
Student
.
_ID
+
"="
+
stuId
+
(
!
TextUtils
.
isEmpty
(
selection
)
?
" and ("
+
selection
+
')'
:
""
)
,
selectionArgs
)
;
break
;
default
:
//如果传进来的Uri不是我们需要的类型
throw
new
IllegalArgumentException
(
"this is Unknown Uri:"
+
uri
)
;
}
resolver
.
notifyChange
(
uri
,
null
)
;
return
count
;
}
/**
* 更新数据
*/
@
Override
public
int
update
(
Uri
uri
,
ContentValues
values
,
String
selection
,
String
[
]
selectionArgs
)
{
SQLiteDatabase db
=
dbHelper
.
getWritableDatabase
(
)
;
//创建一个可读的数据库
resolver
=
this
.
getContext
(
)
.
getContentResolver
(
)
;
int
count
;
switch
(
Urimatcher
.
match
(
uri
)
)
{
case
STUDENT
:
count
=
db
.
update
(
DbHelper
.
TABLE_NAME
,
values
,
selection
,
selectionArgs
)
;
break
;
case
STUDENT_ID
:
String
stuId
=
uri
.
getPathSegments
(
)
.
get
(
1
)
;
//获得id
count
=
db
.
update
(
DbHelper
.
TABLE_NAME
,
values
,
Student
.
_ID
+
"="
+
stuId
+
(
!
TextUtils
.
isEmpty
(
selection
)
?
" and ("
+
selection
+
')'
:
""
)
,
selectionArgs
)
;
break
;
default
:
//如果传进来的Uri不是我们需要的类型
throw
new
IllegalArgumentException
(
"this is Unknown Uri:"
+
uri
)
;
}
resolver
.
notifyChange
(
uri
,
null
)
;
return
count
;
}
}
4.创建一个Activity 来测试,查询、删减、插入、更新数据
点击(
此处
)折叠或打开
package
com
.
example
.
provider
;
import
com
.
example
.
provider
.
Students
.
Student
;
import
android
.
app
.
Activity
;
import
android
.
content
.
ContentResolver
;
import
android
.
content
.
ContentUris
;
import
android
.
content
.
ContentValues
;
import
android
.
database
.
Cursor
;
import
android
.
net
.
Uri
;
import
android
.
os
.
Bundle
;
import
android
.
util
.
Log
;
public
class
MyContentProvider
extends
Activity
{
private
static
final
String
TAG
=
"MyContentProvider"
;
private
ContentResolver
resolver
;
@
Override
protected
void
onCreate
(
Bundle savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
)
;
setContentView
(
R
.
layout
.
activity_main
)
;
insert
(
)
;
//插入数据
// delete(1);//删除第一行
update
(
4
)
;
query
(
)
;
//查询
}
//插入数据
public
void
insert
(
)
{
Uri
uri
=
Student
.
CONTENT_URI
;
//获得ContentResolver对象
resolver
=
this
.
getContentResolver
(
)
;
ContentValues
values
=
new
ContentValues
(
)
;
//添加学生信息
values
.
put
(
Student
.
NMAE
,
"Jack"
)
;
values
.
put
(
Student
.
GENDER
,
"男"
)
;
values
.
put
(
Student
.
AGE
,
20
)
;
//将信息插入
resolver
.
insert
(
uri
,
values
)
;
Log
.
i
(
TAG
,
uri
.
toString
(
)
)
;
}
//删除数据
//删除第id行
public
void
delete
(
Integer
id
)
{
//指定uri
Uri
uri
=
ContentUris
.
withAppendedId
(
Student
.
CONTENT_URI
,
id
)
;
resolver
=
this
.
getContentResolver
(
)
;
resolver
.
delete
(
uri
,
null
,
null
)
;
}
//更新
public
void
update
(
Integer
id
)
{
Uri
uri
=
ContentUris
.
withAppendedId
(
Student
.
CONTENT_URI
,
id
)
;
resolver
=
this
.
getContentResolver
(
)
;
ContentValues
values
=
new
ContentValues
(
)
;
values
.
put
(
Student
.
NMAE
,
"xiaofang"
)
;
values
.
put
(
Student
.
GENDER
,
"女"
)
;
values
.
put
(
Student
.
AGE
,
25
)
;
resolver
.
update
(
uri
,
values
,
null
,
null
)
;
}
//查询
public
void
query
(
)
{
Uri
uri
=
Student
.
CONTENT_URI
;
String
[
]
PROJECTION
=
new
String
[
]
{
Student
.
_ID
,
Student
.
NMAE
,
Student
.
GENDER
,
Student
.
AGE
}
;
resolver
=
this
.
getContentResolver
(
)
;
Cursor
cursor
=
resolver
.
query
(
uri
,
PROJECTION
,
null
,
null
,
null
)
;
//判断游标是否为空
if
(
cursor
.
moveToFirst
(
)
)
{
for
(
int
i
=
0
;
i
<
cursor
.
getCount
(
)
;
i
+
+
)
{
cursor
.
moveToPosition
(
i
)
;
int
id
=
cursor
.
getInt
(
0
)
;
//获得id
String
name
=
cursor
.
getString
(
1
)
;
//取得姓名
String
gender
=
cursor
.
getString
(
2
)
;
//取得性别
int
age
=
cursor
.
getInt
(
3
)
;
//取得年龄
//输出日记
Log
.
i
(
TAG
,
"id:"
+
id
+
" name:"
+
name
+
" gender:"
+
gender
+
" age:"
+
age
)
;
}
}
}
}
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/木道寻08/article/detail/993178
推荐阅读
article
Android
OpenGLES
+
Camera1
相机
预览(
2
)_
opengles
安卓...
本文详细介绍了如何在
Android
中使用
OpenGLES
结合
Camera1
进行
相机
预览,并实现滤镜功能。文章通过Base...
赞
踩
article
Android
CPU
深度
睡眠
,什么是
CPU
更
深度
睡眠
...
问题描述:在X201等机型中,电源管理软件中,在系统设置中有一项
CPU
更
深度
睡眠
,更
深度
睡眠
是什么?如下图所示:解决方案...
赞
踩
article
Flutter
与
Android
开发:构建
跨平台
移动应用的新选择_
flutter
android
...
移动应用开发领域一直在不断发展,各种新的技术和工具层出不穷。其中,
Flutter
作为一种由Google推出的开源UI工具...
赞
踩
article
Android
RecyclerView
实现
卡片
堆叠
视图_
android
recyclerview卡...
最近需求里面要实现一个
卡片
堆叠
的视图,通过
卡片
上下移动来切换阅读的条目,github和csdn找了不少都不能完全符合需求...
赞
踩
article
由于生成
一个
完整
的
应用程序
(
app
)
的
代码涉及到多个层面
,
如
用户界面
(
UI
)
、
后端逻辑
、
数据存储等
,
...
kotlinimport kotlinx.android.synthetic.main.activity_main.* ...
赞
踩
article
Android
Studio
gradle
下载
速度慢解决方法_
android
studio
文件
下载
太...
Android
Studio
安装Gradle时
下载
速度慢?本文提供手动
下载
和安装步骤:从官方指定地址
下载
Gradle,使...
赞
踩
article
【
Android
】手动
下载
gradle
插件包,解决
gradle
插件包
下载
不全问题。_
android
...
拉取别人的项目时,因为网络问题
gradle
插件包一直
下载
不全,一直build。_
android
gradle
plugi...
赞
踩
article
Android
studio
Logcat 功能介绍_
android
studio
logcat
用法...
Android
Studio Jellyfish版本下
logcat
功能,不同的tag会有不同的颜色,不同level等级的...
赞
踩
article
Android
Studio
中LogCat的使用_
androidstduio
logcat
...
、自定义权限(APP Permission...
赞
踩
article
android
studio
查
看
logcat日志_
android
studio
如何
看
日志...
Android Studio中
如何
查
看
Logcat调试信息|浏览:3023|更新:2015-09-12 12:33|标签...
赞
踩
article
Android
中
Text
Span
分析_
textspan
...
1.为什么需要
Span
?在文本展示时,如果不需要设置样式,包括颜色,大小,对齐方式等属性时,可以利用 View 的属性...
赞
踩
article
Android
Base64
.
encode
与
java
.
util
.
Base64
.getEncode...
标准中定义的算法简单点说就是:1. 先计算MD5加密的二进制数组(128位)。2. 再对这个二进制进行
base64
编码(...
赞
踩
article
3 款适合您
手机
或平板电脑的最佳
Android
和
iOS
修复
工具_
ipad
修复
软件
...
文章介绍了
Android
和
iOS
设备常见的性能问题,如运行缓慢、挂起、连接问题等,并推荐了几款
修复
工具,如奇客
软件
的An...
赞
踩
article
Android
App
开发
教学
: 利用
MediaPipe
实现即时
脸部
侦测
功能...
在
Android
开发
中,实现即时
脸部
侦测
功能是一个具有挑战性且引人注目的任务。幸运的是,Google的
MediaPipe
...
赞
踩
article
【
Android
腾讯
地图
】
腾讯
地图
开发记录 ① (
地图
基础显示 |
创建
应用
和
申请
key
| 配...
一、
创建
应用
和
申请
key
1、
创建
应用
2、
申请
key
二、
配置
应用
1、
配置
远程
依赖
库基础
配置
完整
配置
2、
配置
腾讯
地图
Ke...
赞
踩
article
Android
Tcp客户端收发
数据
Handler
版本_
tcp
handler
...
Problem安卓中使用TCP等网络模块时,需要新开线程来将网络的连接、收发等处理放到子线程中执行。前一篇使用Async...
赞
踩
article
UE5.1
+
Android
环境
搭建_
ue5
接入安卓...
一定一定一定要参照官方文档,因UE不同版本对应的
环境
搭建并不完全一致。_
ue5
接入安卓
ue5
接入安卓 ...
赞
踩
相关标签
android
数码相机
Android CPU 深度睡眠
flutter
ios
ui
编辑器
android studio
gradle
常用工具
测试工具
adb
andrdoid java base64结果不同
智能手机
电脑
windows
powerpoint
pdf