android四大组件分别是Activity,Service,ContentProvider,BrodcastReceiver.这次介绍的是ContentProvider。
ContentProvider,从字面意思就是内容提供者,通俗的讲就是给别的应用提供数据,比如android手机自带的通讯录,联系人,这些应用通过这个组件类来给其他的应用相关数据。
Content providers are one of the primary building blocks of Android applications, providing content to applications. They encapsulate data and provide it to applications through the single ContentResolver interface. A content provider is only required if you need to share data between multiple applications. For example, the contacts data is used by multiple applications and must be stored in a content provider. If you don’t need to share data amongst multiple applications you can use a database directly via SQLiteDatabase.这个是官网的介绍。
下面来说下使用方法:
1,如何获取内容提供者的数据
在activity中,只要通过ContentResolver接口来获取数据,直接调用getContentResolver()方法就可以实例化一个ContentResolver。再是通过接口中相关的方法来对数据进行增,删,查,改。
ContentResolver contentResolver = getContentResolver();
onCreate() 初始化内容提供者
query(Uri, String[], String, String[], String) 查询相关的数据
insert(Uri, ContentValues) 插入数据
update(Uri, ContentValues, String, String[]) 修改数据
delete(Uri, String, String[]) 删除数据
getType(Uri) which returns the MIME type of data in the content provider
实例代码:用联系人的做为例子
a:准备好uri
//联系人的uri raw_contacts表的uri
private Uri contactUri = Uri.parse("content://com.android.contacts/raw_contacts");
private String[] contactClumns = new String[]{"_id", "display_name"};
private Uri dataUri = Uri.parse("content://com.android.contacts/data");
private String[] dataClumns = new String[]{"data1"};
b:开始通过内容ContentResolver 来对数据进行操作
ContentResolver contentResolver = getContentResolver();
//查询数据
Cursor contactCursor = contentResolver.query(contactUri, contactClumns, null, null, null);
//删除 getContentResolver().delete(dataUri,"raw_contact_id="+map.get("id"),null); getContentResolver().delete(contactUri,"_id="+map.get("id"),null);
//修改
contentResolver.update(dataUri, values, "raw_contact_id=" + id + " and mimetype_id=1", null);
//增加
contentResolver.insert(dataUri, values);
这是介绍了如何使用通过操作内容提供者的数据。
注:别忘了在清单文件中加上相应的权限
接下来介绍下如何自定义一个内容提供者,给其他应用提供数据。
先写一个数据库的帮助类
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, "user.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
String tb_user = "create table tb_user(" +
"id integer primary key autoincrement," +
"username text," +
"password text," +
"money text)";
String tb_order = "create table tb_order(" +
"id integer primary key autoincrement," +
"user_id integer," +
"productname text," +
"price text)";
db.execSQL(tb_user);
db.execSQL(tb_order);
db.execSQL("insert into tb_user(username,password,money) values('smile','123456','666666')");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion>oldVersion){
db.execSQL("drop table if exists tb_order");
db.execSQL("drop table if exists tb_user");
onCreate(db);
}
}
}
- 然后再写一个类继承ContentProvider,这个类就是你定义的内容提供者。
- 在类中先定义好Uri也就是一个唯一标识。
- 再定义数据表的唯一标识。
- 再定义并初始化UriMatcher,将相应的uri加入到UriMatcher中,后面匹配uri的时候可以用的到。
- 最后重写里面操作数据的几个方法。
实例代码:
public class UserContentProvider extends ContentProvider {
//定义该providercontent组件的唯一标识,包名加数据库名字,也可以自己规定
private static final String AUTHORITY = "com.edu.contentprovider.user";
//为该数据库中可以被提供出去的表定义标识
private static final int CODE_USER = 1;
private static final int CODE_ORDER = 2;
//定义urimatch
private static UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//content://com.edu.contentprovider.user/user
uriMatcher.addURI(AUTHORITY, "user", CODE_USER);
//content://com.edu.contentprovider.user/order
uriMatcher.addURI(AUTHORITY, "order", CODE_ORDER);
}
private DBHelper dbHelper;
@Override
public boolean onCreate() {
//初始化sqlisteopenhelper的子类
dbHelper = new DBHelper(getContext());
return false;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
int code = uriMatcher.match(uri);
if (code == CODE_ORDER) {
return db.query("tb_order", projection, selection, selectionArgs, null, null, sortOrder);
} else if (code == CODE_USER) {
return db.query("tb_user", projection, selection, selectionArgs, null, null, sortOrder);
}
return null;
}
@Nullable
@Override
public String getType(Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
int code = uriMatcher.match(uri);
if (code == CODE_ORDER) {
} else if (code == CODE_USER) {
long id = db.insert("tb_user", null, values);
return ContentUris.withAppendedId(uri, id);
}
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
int code = uriMatcher.match(uri);
if (code == CODE_ORDER) {
} else if (code == CODE_USER) {
return db.delete("tb_user", selection, selectionArgs);
}
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
int code = uriMatcher.match(uri);
if (code == CODE_ORDER) {
} else if (code == CODE_USER) {
return db.update("tb_user",values,selection, selectionArgs);
}
return 0;
}
}
最后在清单文件中注册相关的权限,并将自定义的内容提供者注册进去。
<permission android:name="com.edu.contentprovider.permission.WRITE_READ" />
<uses-permission android:name="com.edu.contentprovider.permission.WRITE_READ" />
注册内容提供者
<provider
android:exported="true"
android:permission="com.edu.contentprovider.permission.WRITE_READ"
android:authorities="com.edu.contentprovider.user"
android:name="com.edu.contentprovider.UserContentProvider"/>
将应用运行一下,相应的数据库就生成了,其他应用就可以通过获取内容提供者的数据了。
注:一定要记得在清单文件中注册不然内容提供者没找到同时数据库也无法创建,拿后面的调用就无法完成了。
测试代码:
public class MainActivity extends AppCompatActivity {
//访问user表的uri
Uri uri = Uri.parse("content://com.edu.contentprovider.user/user");
private String[] columns = new String[]{"id", "username", "password", "money"};
private ListView lv;
private List<String> mDatas;
private ArrayAdapter<String> arrayAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
lv = (ListView) findViewById(R.id.lv);
mDatas = new ArrayList<>();
arrayAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, mDatas);
lv.setAdapter(arrayAdapter);
loadData();
}
private void loadData() {
Cursor cursor = getContentResolver().query(uri, columns, null, null, null);
while (cursor.moveToNext()) {
cursor.getInt(cursor.getColumnIndex("id"));
String username = cursor.getString(cursor.getColumnIndex("username"));
String password = cursor.getString(cursor.getColumnIndex("password"));
String money = cursor.getString(cursor.getColumnIndex("money"));
String str = username + password + money;
mDatas.add(str);
}
arrayAdapter.notifyDataSetChanged();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
就介绍到这!