2016-05-11安卓四大组件 内容提供者contentprovider +数据库+解析者
2016-05-11 11:10
288 查看
MainActivity:
MyContentProvider:
数据库:
MySqliteOpenHelper:
内容解析者:
MainActivity:
User:
package com.guyulei.contentprovider; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
MyContentProvider:
package com.guyulei.contentprovider; import com.guyulei.sqlite.MySqliteOpenHelper; 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; import android.text.TextUtils; import android.util.Log; public class MyContentProvider extends ContentProvider { /* * 创建自己的类MyContentProvider 继承ContentProvider * ContentProvider封装自己的数据库 并提供给外部 作为中介 * 比如 :手机应用中心 xx宝 读取系统短信 通讯录等等 */ /*内容提供者的注册 * android:authorities 主机 * android:exported="true" 对外可以访问 * <provider android:name="com.guyulei.contentprovider.MyContentProvider" android:authorities="com.guyulei.user.provider" android:exported="true"> </provider> */ private static final String TAG = "guyulei"; private MySqliteOpenHelper mySqliteOpenHelper; private SQLiteDatabase database; /* * 生命uri地址解析器 UriMatcher (匹配器)将表名 解析出来 * 默认 不匹配 * 解析过程 是个匹配的过程 思想很重要 将我们所有需要解析的表放到静态代码块内 */ private static final UriMatcher urimatcher = new UriMatcher(UriMatcher.NO_MATCH); private static final String AUTHORITY = "com.guyulei.user.provider"; private static final String G_USER = "g_user"; private static final int G_CODE = 1; private static final String Z_USER = "z_user"; private static final int Z_CODE = 2; //静态代码块 //g_user......G_CODE.....匹配成功返回1 //z_user......Z_CODE.....匹配成功返回2 static{ //给urimatcher 增加我们需要的匹配 其自己识别到底是哪个表 urimatcher.addURI(AUTHORITY, G_USER, G_CODE); urimatcher.addURI(AUTHORITY, Z_USER, Z_CODE); } @Override //第一次创建组件时调用 主线程中调用 四大组件 必须注册 public boolean onCreate() { //数据库类的对象 mySqliteOpenHelper = new MySqliteOpenHelper(getContext()); database = mySqliteOpenHelper.getWritableDatabase(); /* * 对于返回值true 和 false 目前没有影响都可以 * 建议使用true */ return true; } /* * 插入数据 * Uri uri:内容提供者要访问的地址 * values:要插入的数据 */ @Override public Uri insert(Uri uri, ContentValues values) { Log.d(TAG, "uri="+uri+".....ThreamName="+Thread.currentThread().getName()); /* * uri是提供者和解析者之间的桥梁 * 作为两者的返回值 * 问题解决:解析者向提供者 提供uri 里面包含 表名 * 需要解析出来 */ //插入成功返回id /* * 到底插哪个表 uri匹配器进行匹配解析 */ String tableName = getTableName(uri); if(TextUtils.isEmpty(tableName)){ return null; } long i = database.insert(tableName, null, values); Log.d(TAG, "插入"+tableName+"成功后的id为:"+i); //安卓自带工具类 追加id 到uri后面的函数 Uri withAppendedId = ContentUris.withAppendedId(uri, i); //将新的组合的 Uri返回 return withAppendedId; } public String getTableName(Uri uri) { int match = urimatcher.match(uri); //对match进行分析 思想啊思想 String tableName = ""; switch(match){ case G_CODE: tableName = G_USER; break; case Z_CODE: tableName = Z_USER; break; case UriMatcher.NO_MATCH: Log.d(TAG, "您的uri传错啦 "+uri); break; default: break; } return tableName; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { String tableName = getTableName(uri); //返回游标 接收解析者 传来的参数 进行查询 Cursor cursor = database.query(tableName, projection, selection, selectionArgs, null, null, sortOrder); //注意返回值 return cursor; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } }
数据库:
MySqliteOpenHelper:
package com.guyulei.sqlite; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class MySqliteOpenHelper extends SQLiteOpenHelper { private static final String TAG = "guyulei"; //自带构造函数参数太多 将其私有 自己再创建一个 private MySqliteOpenHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub } //重写构造方法需要注意:形参的个数可以少 下面传的时候 不能少 可以固定 //如:this(context,"user.db",null,1); //如果一个类 不能和其他类联系 需要用时 可以 通过自定义的构造函数 public MySqliteOpenHelper(Context context){ this(context,"user.db",null,1); } @Override public void onCreate(SQLiteDatabase db) { String g_sql = "create table g_user(c_id integer primary key,c_name varchar(20),c_age integer);"; String z_sql = "create table z_user(c_id integer primary key,c_name varchar(20),c_age integer);"; db.execSQL(g_sql); db.execSQL(z_sql); Log.d(TAG, "数据库表创建成功了!"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } }
内容解析者:
MainActivity:
package com.guyulei.contentresolver; import java.util.ArrayList; import java.util.List; import com.guyulei.user.User; 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.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; public class MainActivity extends Activity { private ListView lv_query; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv_query = (ListView) findViewById(R.id.lv_query); } /* * 解析者 向 提供者的g_user 表中插入数据 * 先拿到解析者对象 * * 内容提供者的书写规范 * content://com.guyulei.provider/user/01 * schema 主机名authority path ID * content:// 双斜杠 不能错 * content://com.guyulei.contentprovider.MyContentProvider 错误 * content://com.guyulei.user.provider 正确 是主机authority 不是上面的name 注意 */ public void insertuser(View view) { //拿到解析者对象 系统提供的函数 ContentResolver contentResolver = getContentResolver(); //插入数据 Uri url = Uri.parse("content://com.guyulei.user.provider/g_user"); ContentValues values = new ContentValues(); values.put("c_name", "guyulei"); values.put("c_age", 22); /* * 解析者向提供者插入数据 提供者给解析者 返回一个Uri insert * 提供者本身自己也返回 Uri 类型 * public Uri insert(Uri uri, ContentValues values) * 插入成功之后返回一个int * long i = database.insert("g_user", null, values); * 整个过程是:解析者向提供者 传递一个数据插入到表里 提供者拿到这个数据后 由提供者自己去进行数据库插入 * 插入返回的int i 是返回给了提供者 * 现在将int i 整合在 提供者的自身的返回值URI里 再将这个新的URI 回传给解析者 */ Uri insert = contentResolver.insert(url, values); //同样使用工具类 将id解析出来 long id = ContentUris.parseId(insert); Toast.makeText(this, "插入完毕后的id为:"+id, Toast.LENGTH_LONG).show(); } /* * 向z_user表中插入数据 */ public void insertz_user(View view) { //拿到解析者 ContentResolver contentResolver = getContentResolver(); //解析者向提供者 提交需要插入 数据 /* * 新的问题: * 当表很多的时候, 因为解析者不直接指定插哪个表 那么 提供者将不知道 往哪个表里插入 * 此时需要path 指定往哪个表里插入 * content://com.guyulei.provider/user/01 * schema 主机名authority path ID */ Uri url = Uri.parse("content://com.guyulei.user.provider/z_user"); ContentValues values = new ContentValues(); values.put("c_name", "zhouhongwei"); values.put("c_age", 25); Uri insert = contentResolver.insert(url, values ); long id = ContentUris.parseId(insert); Toast.makeText(this, "插入完毕后的id为:"+id, Toast.LENGTH_LONG).show(); } public void queryz_user(View view) { List<User> users = new ArrayList<User>(); //拿到解析者 ContentResolver contentResolver = getContentResolver(); //解析者设置查询数据条件 查询出来的数据在listview 内显示 Uri uri = Uri.parse("content://com.guyulei.user.provider/z_user"); String[] projection = new String[]{"c_name","c_age"}; Cursor cursor = contentResolver.query(uri, projection , null, null, "c_age desc"); while(cursor.moveToNext()){ User user = new User(); user.name = cursor.getString(0); user.age = Integer.parseInt(cursor.getString(1)); users.add(user); } cursor.close(); lv_query.setAdapter(new ArrayAdapter<User>(this, android.R.layout.simple_list_item_1,users)); } }
User:
package com.guyulei.user; public class User { public String name; public int age; public User() { super(); // TODO Auto-generated constructor stub } public User(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User [name=" + name + ", age=" + age + "]"; } }