求助懂Android ContentProvider 请进

lusia1010 2016-05-30 01:29:57
请大神帮忙指点迷津,做了ContentProvider 的程序,报错如下。



CPAActivity.java
package mei.testcp;
import mei.testcp.FirstProviderMetaData.UserTableMetaData;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class CPActivity extends Activity {

private Button insert=null;
private Button query=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

insert=(Button)findViewById(R.id.insert);
query=(Button)findViewById(R.id.query);

insert.setOnClickListener(new InsertClickListener());
query.setOnClickListener(new QueryClickListener());
System.out.println(getContentResolver().getType(FirstProviderMetaData.UserTableMetaData.CONTENT_URI));
}
//往子表中插入一条记录
class InsertClickListener implements OnClickListener{

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
ContentValues values = new ContentValues();
values.put(FirstProviderMetaData.UserTableMetaData.USER_NAME, "zhangsan");
//实际上使用的是ContentResolver的insert方法
//该insert中有2个参数,第一个为代表了ContentProvider的URL,第二个参数为要插入的值。此处的insert函数
//一执行,则自动调用ContentProvider的insert方法。
Uri uri = getContentResolver().insert(FirstProviderMetaData.UserTableMetaData.CONTENT_URI,
values);
System.out.println("uri--->" +uri.toString());
}
}


//查询也是采用的ContentResolver中的query方法。
class QueryClickListener implements OnClickListener{

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Cursor c = getContentResolver().query(FirstProviderMetaData.UserTableMetaData.CONTENT_URI,
null, null, null, null);
while(c.moveToNext())
System.out.println(c.getString(c.getColumnIndex(UserTableMetaData.USER_NAME)));
}
}

}

FirstContentProvider.java
package mei.testcp;

import java.util.HashMap;

import mei.testcp.FirstProviderMetaData.UserTableMetaData;
import mei.sqlite3.db.DatabaseHelper;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

public class FirstContentProvider extends ContentProvider{

//定义一个UriMatcher类对象,用来匹配URL:形成映射,规则是否合法
public static final UriMatcher uriMatcher;
//组时的ID
public static final int INCOMING_USER_COLLECTION = 1;
//单个时的ID
public static final int INCOMING_USER_SIGNAL = 2;
//定义一个DatabaseHelper对象
private DatabaseHelper dh;

static{
//UriMatcher.NO_MATCH表示不匹配任何路径的返回码
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(FirstProviderMetaData.AUTHORTY, "users", INCOMING_USER_COLLECTION);
//后面加了#表示为单个:users下面的某一个users
uriMatcher.addURI(FirstProviderMetaData.AUTHORTY, "users/#", INCOMING_USER_SIGNAL);
}
//新建一个HashMap,后面执行插入操作时有用
public static HashMap<String, String> userProjectionMap;
static
{
userProjectionMap = new HashMap<String, String>();
//给数据库表中的列取别名
userProjectionMap.put(UserTableMetaData._ID, UserTableMetaData._ID);
userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME);
}

//得到ContentProvider的数据类型,返回的参数URL所代表的数据类型
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
System.out.println("getType");
switch(uriMatcher.match(uri)){
//matcher满足URL的前2项(即协议+路径)为第1种情况时,switch语句的值为URL的第3项,此处为INCOMING_USER_COLLECTION
case INCOMING_USER_COLLECTION:
return UserTableMetaData.CONTENT_TYPE;
case INCOMING_USER_SIGNAL:
return UserTableMetaData.CONTENT_TYPE_ITEM;
default:
throw new IllegalArgumentException("Unknown URI" + uri);
}
}
//该函数的返回值是一个URL
//这个URL表示的是刚刚使用这个函数的所插入的数据
//content://mei.testcp.FirstContentProvider/users/
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
System.out.println("insert");
SQLiteDatabase db = dh.getWritableDatabase();
long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values);
if(rowId > 0){
//发出通知给监听器,说明数据已经改变
//ContentUris为工具类
Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);
getContext().getContentResolver().notifyChange(insertedUserUri, null);

return insertedUserUri;
}
throw new SQLException("Failed to insert row into" + uri);
}

//回调函数,在ContentProvider创建的时候调用
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
System.out.println("onCreate");
dh = new DatabaseHelper(getContext(), FirstProviderMetaData.DATABASE_NAME);
return true;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
System.out.println("delete");
return 0;
}

@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
System.out.println("update");
return 0;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
System.out.println("query");
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
switch(uriMatcher.match(uri)){
case INCOMING_USER_COLLECTION:
qb.setTables(UserTableMetaData.TABLE_NAME);//设置表的名称
qb.setProjectionMap(userProjectionMap);//其中userProjectionMap为上面建立好了的Hashmap
break;
case INCOMING_USER_SIGNAL:
qb.setTables(UserTableMetaData.TABLE_NAME);
qb.setProjectionMap(userProjectionMap);
qb.appendWhere(UserTableMetaData._ID + "=" +uri.getPathSegments().get(1));//设置where条件
break;
}
String orderBy;
if(TextUtils.isEmpty(sortOrder)){
orderBy = UserTableMetaData.DEFAULT_SORT_ORDER;//传入的排序参数为空的时候采用默认的排序
}
else{
orderBy = sortOrder;
}
SQLiteDatabase db = dh.getWritableDatabase();
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
}

FirstProviderMetaData.java
package mei.testcp;

import android.net.Uri;
import android.provider.BaseColumns;

public class FirstProviderMetaData {

//这里的AUTHORTY为包的全名+ContentProvider子类的全名
public static final String AUTHORTY = "mei.testcp.FirstContentProvider";
public static final String DATABASE_NAME = "FisrtContentProvider.db";
public static final int DATABASE_VERSION = 1;
public static final String USERS_TABLE_NAME = "users";
public static final class UserTableMetaData implements BaseColumns{

public static final String TABLE_NAME = "users";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORTY + "/users");
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.firstprovider.user";
public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.firstprovider.user";
public static final String USER_NAME = "name";
public static final String DEFAULT_SORT_ORDER = "_id desc";


}

}

DatabaseHelper.java
package mei.sqlite3.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper{

private static final int VERSION=1;

public DatabaseHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
}

public DatabaseHelper(Context context,String name){
this(context,name,VERSION);
}
public DatabaseHelper(Context context,String name,int version){
this(context,name,null,VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
System.out.println("create a Database");
db.execSQL("create table USERS_TABLE_NAME (_ID INTEGER PRIMARY KEY autoincrement,USER_NAME varchar(20))");

}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
System.out.println("update a Database");
}
}

Manifest.xml

<provider
android:name="mei.testcp.FirstContentProvider"
android:authorities="mei.testcp.FirstContentProvider"/>
</application>
</manifest>
...全文
225 7 打赏 收藏 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
lusia1010 2016-05-31
  • 打赏
  • 举报
回复
lusia1010 2016-05-31
  • 打赏
  • 举报
回复
lusia1010 2016-05-30
  • 打赏
  • 举报
回复
引用 4 楼 ink_s 的回复:
[quote=引用 3 楼 lusia1010 的回复:] [quote=引用 1 楼 ink_s 的回复:] create table USERS_TABLE_NAME 你建的表名是USERS_TABLE_NAME 不是users
谢谢!但是我后来定义USERS_TABLE_NAME等于users啦,为什么不行? public static final String USERS_TABLE_NAME = "users";[/quote]改成 db.execSQL("create table users (_ID INTEGER PRIMARY KEY autoincrement,name varchar(20))");[/quote] 哈哈,这个试过了还是报这个错误
ink_s 2016-05-30
  • 打赏
  • 举报
回复
引用 3 楼 lusia1010 的回复:
[quote=引用 1 楼 ink_s 的回复:] create table USERS_TABLE_NAME 你建的表名是USERS_TABLE_NAME 不是users
谢谢!但是我后来定义USERS_TABLE_NAME等于users啦,为什么不行? public static final String USERS_TABLE_NAME = "users";[/quote]改成 db.execSQL("create table users (_ID INTEGER PRIMARY KEY autoincrement,name varchar(20))");
lusia1010 2016-05-30
  • 打赏
  • 举报
回复
引用 1 楼 ink_s 的回复:
create table USERS_TABLE_NAME 你建的表名是USERS_TABLE_NAME 不是users
谢谢!但是我后来定义USERS_TABLE_NAME等于users啦,为什么不行? public static final String USERS_TABLE_NAME = "users";
ink_s 2016-05-30
  • 打赏
  • 举报
回复
db.execSQL("create table USERS_TABLE_NAME (_ID INTEGER PRIMARY KEY autoincrement,USER_NAME varchar(20))"); 这个USERS_TABLE_NAME在“”内, 成了字符串了
ink_s 2016-05-30
  • 打赏
  • 举报
回复
create table USERS_TABLE_NAME 你建的表名是USERS_TABLE_NAME 不是users

80,490

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧