尝试使用下面显示的自定义ContentProvider查询我的数据库时,我收到以下错误.
@H_403_25@解决方法
我已经确认该表存在正确的名称,但仍然无效.
我能够使用原始查询,但我希望我们使用ContentProvider模式进行练习.
谢谢,如果您需要更多信息,请与我们联系.
sqliteOpenHelper
public class DatabaseHelper extends sqliteOpenHelper { private static final String TAG = DatabaseHelper.class.getSimpleName(); private static final String DB_PATH = "/data/data/ashton.android.personal.worktc/databases/"; private static final String DB_NAME = "worktc.db"; private static final int DB_VERSION = 1; private sqliteDatabase myDatabase; private final Context context; public DatabaseHelper(Context context) { super(context,DB_NAME,null,DB_VERSION); this.context = context; } /** * Creates a empty database on the system and rewrites it with your own database. * */ public void createDataBase() throws IOException { boolean dbExist = this.checkDataBase(); if (dbExist) { //do nothing - database already exist } else { Log.e(TAG,"Database does not exist when trying to create it."); //By calling this method and empty database will be created into the default system path //of your application so we are gonna be able to overwrite that database with our database. this.getReadableDatabase(); this.close(); try { this.copyDataBase(); Log.e(TAG,"createDatabase database created"); } catch (IOException e) { throw new Error("Error copying database"); } } } /** * Check if the database already exist to avoid re-copying the file each time you open the application. * @return true if it exists,false if it doesn't */ private boolean checkDataBase(){ File dbFile = new File(DB_PATH + DB_NAME); return dbFile.exists(); } /** * Copies your database from your local assets-folder to the just created empty database in the * system folder,from where it can be accessed and handled. * This is done by transfering bytestream. * */ private void copyDataBase() throws IOException{ //Open your local db as the input stream InputStream myInput = this.context.getAssets().open(DB_NAME); //Open the empty db as the output stream OutputStream myOutput = new FileOutputStream(DB_PATH + DB_NAME); //transfer bytes from the inputfile to the outputfile byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer))>0){ myOutput.write(buffer,length); } //Close the streams myOutput.flush(); myOutput.close(); myInput.close(); } public boolean openDataBase() throws sqlException { //Open the database String myPath = DB_PATH + DB_NAME; this.myDatabase = sqliteDatabase.openDatabase(myPath,sqliteDatabase.CREATE_IF_NECESSARY); return this.myDatabase != null; } @Override public synchronized void close() { if(this.myDatabase != null) this.myDatabase.close(); super.close(); } @Override public void onCreate(sqliteDatabase db) { // TODO Auto-generated method stub } @Override public void onUpgrade(sqliteDatabase db,int oldVersion,int newVersion) { // TODO Auto-generated method stub } }
内容提供商
public class WorkTCContentProvider extends ContentProvider { private static final String TAG = WorkTCContentProvider.class.getSimpleName(); public static final String AUTHORITY = "ashton.android.personal.worktc.database"; private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { sURIMatcher.addURI( AUTHORITY,ProfessionTable.TABLE_NAME,ProfessionTable.PROFESSIONS); sURIMatcher.addURI( AUTHORITY,ProfessionTable.TABLE_NAME + "/#",ProfessionTable.PROFESSIONS_ID); } private DatabaseHelper database; @Override public int delete(Uri uri,String selection,String[] selectionArgs) { // TODO Auto-generated method stub return 0; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } @Override public Uri insert(Uri uri,ContentValues values) { // TODO Auto-generated method stub return null; } @Override public boolean onCreate() { Log.d(TAG,"before database creation"); this.database = new DatabaseHelper(getContext()); try { this.database.createDataBase(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.database.openDataBase(); this.database.close(); Log.d(TAG,"after database creation"); // this.database.getWritableDatabase().execsql( "pragma foreign_keys = on;" ); return false; } @Override public Cursor query(Uri uri,String[] projection,String[] selectionArgs,String sortOrder) { sqliteQueryBuilder queryBuilder = new sqliteQueryBuilder(); switch (sURIMatcher.match(uri)) { case ProfessionTable.PROFESSIONS: /* * Dont do anything,just do the normal query. */ break; case ProfessionTable.PROFESSIONS_ID: queryBuilder.appendWhere(ProfessionTable._ID + "=" + uri.getLastPathSegment()); break; default: throw new IllegalArgumentException("Unknown URI: " + uri); } sqliteDatabase db = this.database.getReadableDatabase(); Cursor cursor = queryBuilder.query( db,projection,selection,selectionArgs,sortOrder); cursor.setNotificationUri(WorkTCApp.getContext().getContentResolver(),uri); return cursor; } @Override public int update(Uri uri,ContentValues values,String[] selectionArgs) { // TODO Auto-generated method stub return 0; } }
ProfessionTable
public final class ProfessionTable implements BaseColumns { public static final String TABLE_NAME = "Professions"; public static final Uri URI = Uri.parse("content://" + WorkTCContentProvider.AUTHORITY + "/" + TABLE_NAME); public static final int PROFESSIONS = 10; public static final int PROFESSIONS_ID = 11; public static final String NAME = "name"; public static final String ICON = "icon"; private ProfessionTable() {} }
09-08 11:16:18.285: E/AndroidRuntime(11651): FATAL EXCEPTION: main 09-08 11:16:18.285: E/AndroidRuntime(11651): java.lang.RuntimeException: Unable to start activity ComponentInfo{ashton.android.personal.worktc/ashton.android.personal.worktc.controllers.WorkActivity}: java.lang.IllegalStateException: Invalid tables 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.app.ActivityThread.access$1500(ActivityThread.java:117) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.os.Handler.dispatchMessage(Handler.java:99) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.os.Looper.loop(Looper.java:130) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.app.ActivityThread.main(ActivityThread.java:3687) 09-08 11:16:18.285: E/AndroidRuntime(11651): at java.lang.reflect.Method.invokeNative(Native Method) 09-08 11:16:18.285: E/AndroidRuntime(11651): at java.lang.reflect.Method.invoke(Method.java:507) 09-08 11:16:18.285: E/AndroidRuntime(11651): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842) 09-08 11:16:18.285: E/AndroidRuntime(11651): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) 09-08 11:16:18.285: E/AndroidRuntime(11651): at dalvik.system.NativeStart.main(Native Method) 09-08 11:16:18.285: E/AndroidRuntime(11651): Caused by: java.lang.IllegalStateException: Invalid tables 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.database.sqlite.sqliteDatabase.findEditTable(sqliteDatabase.java:1127) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.database.sqlite.sqliteQueryBuilder.query(sqliteQueryBuilder.java:330) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.database.sqlite.sqliteQueryBuilder.query(sqliteQueryBuilder.java:280) 09-08 11:16:18.285: E/AndroidRuntime(11651): at ashton.android.personal.worktc.database.worktcContentProvider.query(worktcContentProvider.java:104) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.content.ContentProvider$Transport.query(ContentProvider.java:187) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.content.ContentResolver.query(ContentResolver.java:267) 09-08 11:16:18.285: E/AndroidRuntime(11651): at ashton.android.personal.worktc.views.WorkView.onFinishInflate(WorkView.java:96) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.view.LayoutInflater.rInflate(LayoutInflater.java:631) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.view.LayoutInflater.inflate(LayoutInflater.java:408) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.view.LayoutInflater.inflate(LayoutInflater.java:276) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.view.View.inflate(View.java:8884) 09-08 11:16:18.285: E/AndroidRuntime(11651): at ashton.android.personal.worktc.controllers.WorkActivity.onCreate(WorkActivity.java:30) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 09-08 11:16:18.285: E/AndroidRuntime(11651): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615) 09-08 11:16:18.285: E/AndroidRuntime(11651): ... 11 more