android中数据库一般是不能直接被其他程序创建的,一般是通过内容提供者 ,内容提供者是android开发中常见的数据操作方式,例如;android手机的联系人信息获取 我们是可以直接操作android提供的内容提供者的, android需要做的就是在联系人中定义一个内容提供者;
内容提供者关键步骤:
1,创建(A程序)数据库; 继承SQLiteOpenHelper创建数据库和表
2,创建(A程序)的内容提供者; 继承Contentprovider自定义内容提供者
3,创建(B程序)操作A程序的数据(增删该查) ; 使用上下文获取内容提供者
一: A程序;
1,定义A程序的数据库
package com.example.DemoDB;
/**
* 数据库的创建
*/
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class HelperDemo extends SQLiteOpenHelper{
public HelperDemo(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
//创建表
String sql="create table user(_id integer primary key autoincrement,userphone txet,username text)";
//使用execSQL只用sql语句
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
2,创建显示操作数据的xml文件
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/textView1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_marginTop="130dp" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/textView1" android:layout_marginLeft="18dp" android:layout_marginTop="44dp" android:onClick="optionuser" android:text="添加" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/button1" android:layout_marginLeft="46dp" android:layout_toRightOf="@+id/button1" android:onClick="optionuser" android:text="删除" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button1" android:layout_below="@+id/button1" android:layout_marginTop="22dp" android:onClick="optionuser" android:text="修改" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button3" android:layout_alignBottom="@+id/button3" android:layout_alignLeft="@+id/button2" android:onClick="optionuser" android:text="查询" /> </RelativeLayout>
3,创建A程序的数据库和操作数据库方法,将操作的结果显示出来
package com.example.DemoDB;
import com.example.sharedpreferrences.R;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
/**
*
* @author Administrator 数据库的操作
*/
public class DemoDB extends Activity {
private TextView v1;
private Button t1;
private Button t2;
private Button t3;
private Button t4;
private HelperDemo demo;
private SQLiteDatabase database;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_db);
//创建数据库 user_contacts数据库的名字
demo = new HelperDemo(this, "user_contacts", null, 1);
//增删改查按钮和显示数据按钮
v1 = (TextView) this.findViewById(R.id.textView1);
t1 = (Button) this.findViewById(R.id.button1);
t2 = (Button) this.findViewById(R.id.button2);
t3 = (Button) this.findViewById(R.id.button3);
t4 = (Button) this.findViewById(R.id.button4);
}
// 数据库的操作
public void optionuser(View v) {
switch (v.getId()) {
case R.id.button1:// 添加数据
database = demo.getWritableDatabase();
if (database == null) {
Toast.makeText(this, "不能添加数据", Toast.LENGTH_SHORT).show();
} else {
// 第一个方式
String sql = "insert into user values(null,'12345','长沙')";
database.execSQL(sql);
// 第二种方式
// 参数一:表名
// 参数二:null
// 参数三:使用ContentValues赋值
// ContentValues values = new ContentValues();
// values.put("userphone", "123");
// values.put("username", "value");
//
// database.insert("user", null, values);
selectuser();
}
break;
case R.id.button2:// 删除
database = demo.getWritableDatabase();
if (database == null) {
Toast.makeText(this, "不能删除数据数据", Toast.LENGTH_SHORT).show();
} else {
// //第一种方式
// String sql ="delete from user where _id=?";
// String[] str= {"1"};
// database.execSQL(sql, str);
// 第二种方式
// 参数一:表名
// 参数二:条件
// 参数三:条件的值
String whereClause = "_id=?";
String[] whereArgs = { "2" };
database.delete("user", whereClause, whereArgs);
}
selectuser();
break;
case R.id.button3:// 修改
database = demo.getWritableDatabase();
if (database == null) {
Toast.makeText(this, "不能修改数据", Toast.LENGTH_SHORT).show();
} else {
// 第一种方式
// String sql="update user set username='武汉' where _id=6";
// database.execSQL(sql);
// 参数一:表名
// 参数二:更新的值
// 参数三:?的字段名
// 参数四:?字段名的值
ContentValues values = new ContentValues();
values.put("username", "北京");
String whereClause = "_id=?";
String[] whereArgs = { "5" };
database.update("user", values, whereClause, whereArgs);
}
selectuser();
break;
case R.id.button4:// 查询
selectuser();
break;
}
}
// 查询
public void selectuser() {
SQLiteDatabase database2 = demo.getReadableDatabase();
// // 第一种方式
// String sql = "select * from user order by _id desc";
// Cursor c = database2.rawQuery(sql, null);
// StringBuffer buffer = new StringBuffer();
// while (c.moveToNext()) {
// int id = c.getInt(c.getColumnIndex("_id"));
// String phone = c.getString(c.getColumnIndex("userphone"));
// String name = c.getString(c.getColumnIndex("username"));
// buffer.append(id + "\t姓名:\t" + name + "<><>电话:\t" + phone + "\r\n");
// }
// v1.setText(buffer);
//第二种方式
//参数一:表名
//查询数据会返回一个游标对象,遍历游标对象就得到值
Cursor c=database2.query("user", null, null, null, null, null, null);
StringBuffer buffer = new StringBuffer();
while (c.moveToNext()) {
int id = c.getInt(c.getColumnIndex("_id"));
String phone = c.getString(c.getColumnIndex("userphone"));
String name = c.getString(c.getColumnIndex("username"));
buffer.append(id + "\t姓名:\t" + name + "<><>电话:\t" + phone + "\r\n");
}
v1.setText(buffer);
}
}
4,定义A程序的内容提供者
package com.example.DemoDB;
/**
* 内容提供者
*/
import android.content.ContentProvider;
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;
/**
*
* @author Administrator 使用内容提供者共享数据 第一步:继承ContentProvider 第二步; <provider
* android:name="com.example.DemoDB.MyContent"
* android:authorities="com.example.DemoDB.MyContent.provider"
* android:exported="true"></provider>
*/
public class MyContent extends ContentProvider {
// 定义字符串用来匹配的关键
static String authority = "com.MyContent.provider";
// 定义一个URI匹配器,NO_MATCH表示默认不匹配任何路径
static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
// 使用静态块来添加可匹配路径,为了保证在执行那个程序之前,匹配器中有可匹配路径
static {
// 参数一:内容提供者
// 参数二:名字
// 参数三:匹配的地址
matcher.addURI(authority, "insretdate", 1);//插入
matcher.addURI(authority, "selectdate", 2);//查询
matcher.addURI(authority, "daletedate", 3);//删除
matcher.addURI(authority, "updatedate", 4);//修改
}
private HelperDemo demo;
@Override
public boolean onCreate() {
// 创建数据库
demo = new HelperDemo(this.getContext(), "user_contacts", null, 1);
return true;
}
@Override
public String getType(Uri uri) {
// 获得类型
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// 匹配内容提供者的数据
int code = matcher.match(uri);
if (code != 2) {
throw new IllegalArgumentException("参数异常:" + uri);
}
//判断是否可读
SQLiteDatabase querydatabase=demo.getReadableDatabase();
if(querydatabase==null){
throw new RuntimeException("数据不存在");
}
Cursor cursor=querydatabase.query("user", projection, selection, selectionArgs, null, null, sortOrder);
return cursor;
}
@Override
// 插入数据
public Uri insert(Uri uri, ContentValues values) {
// 匹配uri
int code = matcher.match(uri);
if (code != 1) {
throw new IllegalArgumentException("插入数据时参数异常:" + uri);
}
SQLiteDatabase db = demo.getWritableDatabase();
if (db == null) {
throw new RuntimeException("无法插入数据,数据库对象为只读!");
}
// 返回的是插入的数据的id 插入到数据库可以使用insertOrThrow 和insert插入
long id = db.insertOrThrow("user", "_id", values);
// 返回的Uri代表被插入的数据
uri = ContentUris.withAppendedId(uri, id);
return uri;
}
@Override
// 删除数据
public int delete(Uri uri, String selection, String[] selectionArgs) {
//匹配编码
int code=matcher.match(uri);
if(code!=3){
throw new IllegalArgumentException("删除参数异常:"+uri);
}
//判断是否可写
SQLiteDatabase sd= demo.getWritableDatabase();
if(sd==null){
throw new RuntimeException("删除 运行时异常");
}
//删除数据
int len=sd.delete("user", selection, selectionArgs);
return len;
}
@Override
// 更新数据
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int code=matcher.match(uri);
if(code!=4){
throw new IllegalArgumentException("更新参数异常:"+uri);
}
SQLiteDatabase sd=demo.getWritableDatabase();
if(sd==null){
throw new RuntimeException("更新运行时异常");
}
//更新数据
int len=sd.update("user", values, selection, selectionArgs);
return len;
}
}
分析:
a, MyContent类执行时,先初始化static的相关属性,
// 定义字符串用来匹配的关键
static String authority = "com.MyContent.provider";
// 定义一个URI匹配器,NO_MATCH表示默认不匹配任何路径
static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
// 使用静态块来添加可匹配路径,为了保证在执行那个程序之前,匹配器中有可匹配路径
static {
// 参数一:内容提供者
// 参数二:名字
// 参数三:匹配的地址
matcher.addURI(authority, "insretdate", 1);//插入
matcher.addURI(authority, "selectdate", 2);//查询
matcher.addURI(authority, "daletedate", 3);//删除
matcher.addURI(authority, "updatedate", 4);//修改
}
b, B程序操作A程序的内容提供者是通过 addURI()方法中的名字 找到内容提供者,通过匹配地址找到插 入语句
5,清单中注册
<provider
android:name="com.example.DemoDB.MyContent"
android:authorities="com.MyContent.provider"
android:exported="true"></provider>
</application>
二 :B程序
操作A程序中的内容提供者的步骤:
上下文获取内容提供者
1,xml文件 按不同的按钮输入框输入的结果不同,请仔细查看B程序中按钮的操作
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_marginBottom="141dp" android:onClick="show" android:text="更新" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button1" android:layout_alignBottom="@+id/button1" android:layout_toRightOf="@+id/textView1" android:onClick="show" android:text="查询" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignRight="@+id/button1" android:layout_below="@+id/button2" android:layout_marginTop="36dp" android:onClick="show" android:text="删除" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button3" android:layout_alignBottom="@+id/button3" android:layout_alignRight="@+id/editText2" android:onClick="show" android:text="添加" /> <EditText android:id="@+id/editText2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button1" android:layout_centerVertical="true" android:ems="10" /> <EditText android:id="@+id/editText1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/editText2" android:layout_alignLeft="@+id/editText2" android:layout_marginBottom="14dp" android:ems="10" > <requestFocus /> </EditText> </RelativeLayout>
2,B程序操作A程序的内容提供者
package com.example.date.provider;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
/**
*
* @author Administrator
*操作数据保存程序的内容提供者,实现增删改查操作
*/
public class MainActivity extends Activity {
private EditText editText1;
private EditText editText2;
private ContentResolver resolver;
private TextView t1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t1=(TextView)this.findViewById(R.id.textView1);
editText1 = (EditText) this.findViewById(R.id.editText1);
editText2 = (EditText) this.findViewById(R.id.editText2);
//获得内容提供者
resolver= this.getContentResolver();
}
//实现按钮的监听器方法
public void show(View v) {
switch (v.getId()) {
case R.id.button1://更新数据
//获取输入框的值
String str=editText1.getText().toString().trim();
//内容提供者的地址
Uri uri= Uri.parse("content://com.MyContent.provider/updatedate");
ContentValues values= new ContentValues();
values.put("username", "天津");
String where="_id=?";
String[] selectionArgs={str};
//更新语句
resolver.update(uri, values, where, selectionArgs);
break;
case R.id.button2:
//查询
Uri uriselect= Uri.parse("content://com.MyContent.provider/selectdate");
Cursor c= resolver.query(uriselect, null, null, null, null);
StringBuffer buffer = new StringBuffer();
while (c.moveToNext()) {
int id = c.getInt(c.getColumnIndex("_id"));
String phone = c.getString(c.getColumnIndex("userphone"));
String name = c.getString(c.getColumnIndex("username"));
buffer.append(id + "\t姓名:\t" + name + "<><>电话:\t" + phone + "\r\n");
}
t1.setText(buffer);
break;
case R.id.button3:
//删除
Uri uridelete=Uri.parse("content://com.MyContent.provider/daletedate");
String str1=editText1.getText().toString().trim();
String wheredelete = "username=?";
String[] selectionArgsdelete = {str1};
resolver.delete(uridelete, wheredelete, selectionArgsdelete);
break;
case R.id.button4:
//增加
Uri uriinsret= Uri.parse("content://com.MyContent.provider/insretdate");
//获取输入框中的姓名和电话
String name=editText1.getText().toString().trim();
String phone=editText2.getText().toString().trim();
//使用键值对存放数据
ContentValues valuesinsert = new ContentValues();
valuesinsert.put("username", name);
valuesinsert.put("userphone", phone);
//插入语句
resolver.insert(uriinsret, valuesinsert);
break;
}
}
}