本文主要是介绍Android——内容提供者,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Android 基础中最重要的就四大组件,四大组件是Android学习的开始。
activity ——算作Android界面
service——服务
Broadcast Receiver——广播
Content Provider——内容提供者
这四大组件开始对我来说内容提供者是最难理解的,但是慢慢接触之后感觉也不是很难。相对于基础来说吧。
这两天我又看了这一章的内容,就在这做个笔记吧
内容提供者。就按字面意思来理解 Android手机的内容,提供出来的工具
在做黑马教程(手机卫士)的时候就要提取出联系人,短信等数据的时候就要到了内容提供者
它是不同应用程序直接进行数据交换的标准API,当一个应用程序需要把自己的数据暴露出来给其他应用使用的时候,该应用程序
就可以通过提供contentProvider来实现:其他应用程序就可以通过ContentResolver来操作ContentProvider暴露出来的数据(抄的疯狂Android)
这里就可以知道,Android的内容提供者是有两部分组成的,这样想。内容当做事一个苹果树,A是苹果树的拥有者,如果B想要就需要拿钱去买。
但是A想卖,B才能买。买卖交换就要有市场。
简单点说就是其他应用拿数据,需要一个桥梁这就出现了内容提供者
Uri就是这个桥梁
想利用好内容提供者就要知道Uri。
假设你想去百度获取信息,该怎么办。首先得去百度网站才能吧。那也就是去到百度的界面,去百度的网站
同理,B应用要拿到A应用的网站就要去A的网站。只是在这里应该是打引号的网站,先这样理解吧
从其他地方扒了一点过来
Uri代表了要操作的数据,Uri主要包含了两部分信息
①需要操作的ContentProvider
②对ContentProvider中的什么数据进行操作
组成部分
①scheme:ContentProvider的scheme已经由Android所规定为content://
②主机名(Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。建议为公司域名,保持唯一性
③路径(path):可以用来表示我们要操作的数据,路径的构建应根据业务而定:
要操作person表中id为10的记录,可以构建这样的路径:/person/10
要操作person表中id为10的记录的name字段, person/10/name
要操作person表中的所有记录,可以构建这样的路径:/person
要操作xxx表中的记录,可以构建这样的路径:/xxx
当然要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下:
要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://com.jbridge.provider.personprovider/person")
下面就直接写代码把。方法直接就在代码直接说
1
import android.content.ContentProvider;
2
import android.content.ContentValues;
3
import android.database.Cursor;
4
import android.net.Uri;
5
import android.support.annotation.NonNull;
6
import android.support.annotation.Nullable;
7
import android.util.Log;
8
9
/**
10
* Created by YacaToy on 2017/6/24.
11
*/
12
//ContentProvider的创建和其他四大组件差不多,都要继承然后在清单文件中配置好
13
public class FirstProvider extends ContentProvider {
14
private String Tag = "ContentProvider";
15
//第一次创建该ContentProvider时调用该方法
16
17
public boolean onCreate() {
18
Log.w(Tag, "onCreate: 第一次创建用该方法");
19
return false;
20
}
21
22
23
24
public Cursor query( Uri uri, String[] projection, String selection,
25
String[] selectionArgs, String sortOrder) {
26
Log.w(Tag , "query: 调用");
27
Log.w(Tag , "selection: 参数是"+selection);
28
return null;
29
}
30
31
//该返回的返回值代表ContentProvider所提供的MIME类型
32
33
34
public String getType( Uri uri) {
35
return null;
36
}
37
38
//实现插入的方法,该方法应该返回新插入的纪录的Uri
39
40
41
public Uri insert( Uri uri, ContentValues values) {
42
Log.w(Tag , "insert: 调用");
43
Log.w(Tag , "values: 参数是"+values);
44
return null;
45
}
46
47
//实现删除方法,该方法应该返回被删除的纪录条数
48
49
public int delete( Uri uri, String selection, String[] selectionArgs) {
50
Log.w(Tag , "delete: 调用");
51
Log.w(Tag , "selection: 参数是"+selection);
52
return 0;
53
}
54
55
//实现更新方法,该方法应该返回被更新的纪录条数
56
57
public int update( Uri uri, ContentValues values, String selection, String[] selectionArgs) {
58
Log.w(Tag , "update: 不调用");
59
Log.w(Tag , "selection: 参数是"+selection+"values"+values);
60
return 0;
61
}
62
}
清单文件
1
<provider
2
android:authorities="org.crazyit.providers.firstprovider" <!--这么一长串的东西只是一个标识-->
3
android:name=".content.FirstProvider"
4
></provider>
这个程序我就用了四个button,就没有添代码了
1
2
contentResolver = getContentResolver();
3
4
class MyOnClickListener implements View.OnClickListener {
5
6
7
public void onClick(View v) {
8
switch (v.getId()){
9
case R.id.query: //查询
10
Cursor cursor = contentResolver.query(uri,null,"query_where",null,null);
11
Toast.makeText(getApplicationContext(),cursor+"",Toast.LENGTH_SHORT).show();
12
break;
13
case R.id.insert: //插入
14
ContentValues values = new ContentValues();
15
values.put("name","Yaca");
16
Uri nuwUri = contentResolver.insert(uri,values);
17
Toast.makeText(getApplicationContext(),values+"",Toast.LENGTH_SHORT).show();
18
break;
19
case R.id.update: //更新
20
ContentValues valuess = new ContentValues();
21
valuess.put("name","Yaca");
22
contentResolver.update(uri,valuess,"update_where",null);
23
24
break;
25
case R.id.delete: //删除
26
/**
27
代码
28
**/
29
break;
30
31
}
32
}
33
}
然后我点击了 插入 出现了
参数是name=Yaca
大致就是这么一个节奏
1
//实现插入的方法,该方法应该返回新插入的纪录的Uri
2
@Nullable
3
@Override
4
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
5
Log.w(Tag , "insert: 调用");
6
Log.w(Tag , "values: 参数是"+values);
7
return null;
8
}
1
case R.id.insert: //插入
2
ContentValues values = new ContentValues();
3
values.put("name","Yaca");
4
Uri nuwUri = contentResolver.insert(uri,values);
5
Toast.makeText(getApplicationContext(),values+"",Toast.LENGTH_SHORT).show();
6
break;
把这两个代码放在一起看,就懂了。 数据的操作无法就是增删改查。contentProvider定义 增删改查的方法。contentResolver提供参数
创建ContentProvider的说明
通过上面的介绍可以看出,ContentProvide不像Activity存在复杂的生命周期,ContentProvider只有一个onCreate()生命周期方法——当其他应用通过ContentResolver第一次方法该ContentProvider时
onCreate()方法将会被调用,onCreate只会被调用一次:ContentProvider提供的query(),insert(),update(),delete()方法则由其他应用用过ContentResolve调用这些方法时传入
前面介绍的示例由于并未真正对数据进行操作,因此ContentProvider实际能处理的Uri,以及确定每个方法中Uri参数所操作的额数据,Android系统提供了 UriMatcher工具类
void addURI(String authority,String path,int code):该方法用于向UriMatcher对象注册Uri,其中authorty和path组合成一个Uri,而code则代表Uri对应标识码
int match(Uri uri) : 根据前面注册的Uri来判断指定Uri对应的标识码,如果找不到匹配的标识码,该方法将会返回 -1
例如,我们先通过如下代码来创建UriMatcher对象
1
UriMatcher mather = new UriMathcer(UriMathcer.NO_MATCh);
2
mathcer.addURI("org.crazyit.providers.firstprovider","words",1);
3
mathcer.addURI("org.crazyit.providers.firstprovider","word/#",2);
上面创建的UriMatcher对象注册了两个Uri,其中 org.crazyit.providers.firstprovider/words对应的识别码为1;
org.crazyit.providers.firstprovider/word#对应的标识码为2;#为通配符
这就意味着如下匹配结果:
1
mathcer.match(Uri.parse("content:// org.crazyit.providers.firstprovider/words "));
2
//返回标识码为1
3
mathcer.match(Uri.parse("content:// org.crazyit.providers.firstprovider/word/2 "));
4
//返回标识码为2
5
mathcer.match(Uri.parse("content:// org.crazyit.providers.firstprovider/word/10 "));
6
//返回标识码为2
至于到底需要为UriMatcher对象注册多少个uri,则取决于系统的业务逻辑
对于 "content:// org.crazyit.providers.firstprovider/words "这个Uri,它的资源部分为words,这种资源通常代表了访问所以数据项;对应 "content:// org.crazyit.providers.firstprovider/word/2"这个Uri。它的资源部分通常代表访问数据项,其中最后一个数值往往代表了该数据的ID
除此之外,Android还提供了ContentUris工具类,它是一个操作Uri字符串的工具类
提供了如下两个工具方法
withAPPendedld(Uri,id)用于为路径加上ID部分
1
Uri uri = Uri.parse("content:// org.crazyit.providers.firstprovider/words ");
2
Uri resultUri = ContentUris.withAppendedId(Uri,2);
3
//生成后的Uri为:"content:// org.crazyit.providers.firstprovider/word/2"
Parseld(uri):用于从指定Uri种解析出所包含的ID值
1
Uri uri = Uri.parse("content:// org.crazyit.providers.firstprovider/word/2 ");
2
long wordId = ContentUris.parseId(uri); //获取的结果为2
接下来我就写一个例子:还是老路子,学生信息管理
在A应用上创建一个数据库,然后在B应用上调用A应用的数据
开始创建A应用:代码如下
数据库类的代码
1
import android.content.Context;
2
import android.database.DatabaseErrorHandler;
3
import android.database.sqlite.SQLiteDatabase;
4
import android.database.sqlite.SQLiteOpenHelper;
5
import android.util.Log;
6
7
/**
8
* Created by YacaToy on 2017/6/23.
9
*/
10
11
public class MySQLieOpenHeler extends SQLiteOpenHelper {
12
private String Tag = "MySQLieOpenHeler";
13
public MySQLieOpenHeler(Context context) {
14
super(context, "student.db", null, 1);
15
}
16
17
18
public void onCreate(SQLiteDatabase db) {
19
Log.w(Tag,"创建了SQL");
20
db.execSQL("create table student (_id integer primary key autoincrement , " +
21
"name varchar(50),phone varchar(20));");
22
}
23
24
25
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
26
27
}
28
}
然后就是创建一下A应用的ContentProvider基础类
1
import android.content.ContentProvider;
2
import android.content.ContentValues;
3
import android.database.Cursor;
4
import android.database.sqlite.SQLiteDatabase;
5
import android.net.Uri;
6
import android.support.annotation.NonNull;
7
import android.support.annotation.Nullable;
8
9
/**
10
* Created by YacaToy on 2017/6/24.
11
*/
12
13
public class MyContent extends ContentProvider {
14
private MySQLieOpenHeler dbOpenHelper;
15
public boolean onCreate() {
16
return false;
17
}
18
19
//查询
20
21
22
public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
23
//这里一定要记得 new MySQLieOpenHeler(this.getContext()); 否则就是爆空指针异常
24
if(dbOpenHelper == null){
25
dbOpenHelper = new MySQLieOpenHeler(this.getContext());
26
}
27
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
28
return db.query("student",projection,selection,selectionArgs,null,null,sortOrder);
29
}
30
31
32
33
public String getType( Uri uri) {
34
//这个暂时我也不怎么会用,也就是返回出一个类型,根据类型数据来操作内容,以后我学好点的时候再来单独写一个博客吧。不好意思
35
return null;
36
}
37
38
//添加
39
40
41
public Uri insert( Uri uri, ContentValues values) {
42
if(dbOpenHelper == null){
43
dbOpenHelper = new MySQLieOpenHeler(this.getContext());
44
}
45
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
46
db.insert("student",null,values);
47
db.close();
48
return null;
49
}
50
51
//删除
52
53
public int delete( Uri uri, String selection, String[] selectionArgs) {
54
if(dbOpenHelper == null){
55
dbOpenHelper = new MySQLieOpenHeler(this.getContext());
56
}
57
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
58
db.delete("student",selection,selectionArgs);
59
db.close();
60
return 0;
61
}
62
63
//更新
64
65
public int update( Uri uri, ContentValues values, String selection, String[] selectionArgs) {
66
if(dbOpenHelper == null){
67
dbOpenHelper = new MySQLieOpenHeler(this.getContext());
68
}
69
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
70
db.update("student",values,selection,selectionArgs);
71
return 0;
72
}
73
}
74
基本就是把,ContentResolver要调用的参数直接给数据操作。db了。这样也就相当于一个桥梁。直接把参数给它就成
一定要记得配置清单文件
1
<provider
2
android:authorities="com.yacatot.data.student"
3
android:name=".MyContent"
4
android:exported="true"
5
></provider>
最后一开始创建的时候就配置好,等下忘记了
好了。A应有提供功能就写完了。该是B应用了
布局文件我就写了四个按钮,没有做其他处理。有点儿懒
直接说吧。看代码
1
2
import android.content.ContentResolver;
3
import android.content.ContentValues;
4
import android.database.Cursor;
5
import android.net.Uri;
6
import android.support.v7.app.AppCompatActivity;
7
import android.os.Bundle;
8
import android.util.Log;
9
import android.view.View;
10
import android.widget.Button;
11
12
import java.util.ArrayList;
13
import java.util.List;
14
15
public class MainActivity extends AppCompatActivity {
16
private String TAG= "MainActivity";
17
ContentResolver contentResolver;
18
Uri uri = Uri.parse("content://com.yacatot.data.student/"); //地址
19
20
protected void onCreate(Bundle savedInstanceState) {
21
super.onCreate(savedInstanceState);
22
setContentView(R.layout.activity_main);
23
contentResolver = getContentResolver();
24
//添加
25
Button insert = (Button) findViewById(R.id.bt_insert);
26
insert.setOnClickListener(new View.OnClickListener() {
27
28
public void onClick(View v) {
29
ContentValues values = new ContentValues();
30
values.put("name","zhangsan");
31
values.put("phone","123456");
32
contentResolver.insert(uri,values);
33
34
}
35
});
36
//删除
37
Button delete = (Button) findViewById(R.id.bt_delete);
38
delete.setOnClickListener(new View.OnClickListener() {
39
40
public void onClick(View v) {
41
42
contentResolver.delete(uri,"name = ?", new String[] {"zhangsan"} );
43
44
}
45
});
46
47
//更新
48
Button update = (Button) findViewById(R.id.bt_update);
49
update.setOnClickListener(new View.OnClickListener() {
50
51
public void onClick(View v) {
52
ContentValues values = new ContentValues();
53
values.put("name","lisi");
54
contentResolver.update(uri,values,"name = ?" , new String[] {"zhangsan"});
55
56
}
57
});
58
59
//查询
60
Button inquire = (Button) findViewById(R.id.bt_inquire);
61
inquire.setOnClickListener(new View.OnClickListener() {
62
63
public void onClick(View v) {
64
65
Cursor query = contentResolver.query(uri, null, null, null, null);
66
List<StudentInfo> list = new ArrayList<StudentInfo>();
67
while (query.moveToNext()){
68
StudentInfo info = new StudentInfo();
69
String name = query.getString(1);
70
info.setName(name);
71
String phone = query.getString(2);
72
info.setPhone(phone);
73
list.add(info);
74
}
75
Log.w(TAG,list.get(0).getName());
76
Log.w(TAG,list.get(0).getPhone());
77
}
78
});
79
}
80
}
81
这里说一下。查询。在A应有中
1
//查询
2
3
4
public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
5
//这里一定要记得 new MySQLieOpenHeler(this.getContext()); 否则就是爆空指针异常
6
if(dbOpenHelper == null){
7
dbOpenHelper = new MySQLieOpenHeler(this.getContext());
8
}
9
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
10
return db.query("student",projection,selection,selectionArgs,null,null,sortOrder);
11
}
12
//这里返回的是Cursor类型,记得。Content只是一个桥梁,他不做好人好事。
13
内容提供者的基础就介绍完了。有什么问题一起讨论。新手之间多多学习
这篇关于Android——内容提供者的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!