0

错误说:column _id does not exists但是该列在数据库中(设置为主键),并且该列位于外部 SD 文件夹中。我试图在活动的初始加载时返回数据库中包含的值,但似乎游标没有返回任何内容。

public class ComponentsDbAdapter {

  public static final String COLUMN_ID = "_id";
  public static final String COLUMN_SUBSTRUCTURE = "substructure";
  public static final String COLUMN_TYPE = "type";
  public static final String COLUMN_ORDERNUM = "ordernum";
  public static final String COLUMN_INSTALLATION = "installation";
  private static final String TAG = "ComponentsDbAdapter";
  private DatabaseHelper mDbHelper;
  private SQLiteDatabase mDb;
  private static final String DATABASE_PATH = Environment.getExternalStorageDirectory().getAbsoluteFile()+ "/DATABASE_BACKUP/IMPORTED/";
  private static final String DATABASE_NAME = "android.db";
  private static final String TABLE_NAME = "TAB_WORKSCPE";
  private static final int DATABASE_VERSION = 1; 
  private final Context mCtx;


  public ComponentsDbAdapter open() throws SQLException {
    mDbHelper = new DatabaseHelper(mCtx);
    mDb = mDbHelper.getWritableDatabase();
    return this;
  }

  private static class DatabaseHelper extends SQLiteOpenHelper {
    DatabaseHelper(Context context) {
        super(context, DATABASE_PATH+DATABASE_NAME, null, DATABASE_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.query(TABLE_NAME, new String[] {COLUMN_ID, COLUMN_SUBSTRUCTURE, COLUMN_TYPE, COLUMN_ORDERNUM, COLUMN_INSTALLATION}, null, null, null, null, null); 
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }
  }

  public ComponentsDbAdapter(Context ctx) {
    this.mCtx = ctx;
  }

  public void close() {
    if (mDbHelper != null) {
        mDbHelper.close();
    }
 }

  public Cursor fetchComponentsByName(String inputText) throws SQLException {
    Log.w(TAG, inputText);
    Cursor mCursor = null;
    if (inputText == null  ||  inputText.length () == 0)  {
        mCursor = mDb.query(TABLE_NAME, new String[] {COLUMN_ID, COLUMN_SUBSTRUCTURE, COLUMN_TYPE, COLUMN_ORDERNUM, COLUMN_INSTALLATION}, null, null, null, null, null); 
} else {
    mCursor = mDb.query(true, TABLE_NAME, new String[] {COLUMN_ID, COLUMN_SUBSTRUCTURE, COLUMN_TYPE, COLUMN_ORDERNUM, COLUMN_INSTALLATION}, COLUMN_TYPE + " like '%" + inputText + "%'", null, null, null, null, null);
}
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor; 
}

public Cursor fetchAllComponents() {
    Cursor mCursor = mDb.query(TABLE_NAME, new String[] {COLUMN_ID, COLUMN_SUBSTRUCTURE, COLUMN_TYPE, COLUMN_ORDERNUM, COLUMN_INSTALLATION}, null, null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;
  }
}





public class AndroidListViewCursorAdaptorActivity extends Activity {

private ComponentsDbAdapter dbHelper;
private SimpleCursorAdapter dataAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    dbHelper = new ComponentsDbAdapter(this);
    dbHelper.open();

    //Generate ListView from SQLite Database
    displayListView();
}

private void displayListView() {
    Cursor cursor = dbHelper.fetchAllComponents();

    // The desired columns to be bound
    String[] columns = new String[] {
        ComponentsDbAdapter.COLUMN_SUBSTRUCTURE,
        ComponentsDbAdapter.COLUMN_TYPE,
        ComponentsDbAdapter.COLUMN_ORDERNUM,
        ComponentsDbAdapter.COLUMN_INSTALLATION
    };

    // the XML defined views which the data will be bound to
    int[] to = new int[] {
        R.id.inst,
        R.id.subdt,
        R.id.type,
        R.id.ordernum,
    };

    // create the adapter using the cursor pointing to the desired data
    //as well as the layout information
    dataAdapter = new SimpleCursorAdapter(
        this, 
        R.layout.country_info,
        cursor,
        columns,
        to,
        0);

    ListView listView = (ListView) findViewById(R.id.listView1);
    // Assign adapter to ListView
    listView.setAdapter(dataAdapter);


    listView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> listView, View view,
            int position, long id) {
            // Get the cursor, positioned to the corresponding row in the result set
            Cursor cursor = (Cursor) listView.getItemAtPosition(position);

            // Get the state's capital from this row in the database.
            String compSubdt = cursor.getString(cursor.getColumnIndexOrThrow("subdt"));
            Toast.makeText(getApplicationContext(), compSubdt, Toast.LENGTH_SHORT).show();
        }
    });

    EditText myFilter = (EditText) findViewById(R.id.myFilter);
    myFilter.addTextChangedListener(new TextWatcher() {

        public void afterTextChanged(Editable s) {
        }

        public void beforeTextChanged(CharSequence s, int start,int count, int after) {
        }

        public void onTextChanged(CharSequence s, int start,int before, int count) {
            dataAdapter.getFilter().filter(s.toString());
        }
    });

    dataAdapter.setFilterQueryProvider(new FilterQueryProvider() {
        public Cursor runQuery(CharSequence constraint) {
            return dbHelper.fetchComponentsByName(constraint.toString());
        }
    });
 }
 }
4

3 回答 3

0

从您的代码中看,您尚未创建表,因此不会找到任何列。

您可以在onCreate方法中通过创建查询来创建表来执行此操作。在您的代码中,您似乎在进行选择而不是创建。

private static final String TABLE_CREATE = "create table "
    + TABLE_NAME
    + "("
    + COLUMN_ID + " integer primary key autoincrement, "
    + COLUMN_TYPE + " text not null default '', "
    + COLUMN_ORDERNUM + " integer not null default 0, "
    + COLUMN_INSTALLATION + " integer not null default 0, "
    + COLUMN_SUBSTRUCTURE + " text not null default ''"
    + ");";

@Override
public void onCreate(SQLiteDatabase database) {
    database.execSQL(TABLE_CREATE);
}

要将其存储在外部存储上,您需要覆盖getDatabasePath(...)。类似的解决方案在这里https://stackoverflow.com/a/8385537/935779

@Override
public File getDatabasePath(String name) {
    // reference where you would like the file to be here.
    File result = new File(getExternalFilesDir(null), name);
    return result;
}

我相信你会想用你的Application班级覆盖它,因为它是ContextWrapper.

该方法getDatabaseFile(...)openOrCreateDatabase(...)内部使用来确定位置。

或者,您可以在那里覆盖openOrCreateDatabase(...)并设置文件位置。

于 2013-03-29T16:06:11.380 回答
0

我认为您不能更改甚至指定数据库的位置,只能更改名称。离开路径,不要尝试将其放在外部存储中 - 让 Android 确定路径。

于 2013-03-29T21:58:54.747 回答
0

好的,这花了我将近一周的时间和很大的压力,但这是解决方案。我开始阅读很多教程并让它在这个中工作:

http://www.mysamplecode.com/2012/11/android-database-content-provider.html

我从虚拟设备中提取了数据库并手动添加了更多数据。然后将数据库复制到我的设备文件夹上的所需文件夹(只是为了确保数据库一致性/列完全相同)。然后将 MyDatabaseHelper 类更改如下:

public class MyDatabaseHelper extends SQLiteOpenHelper {

    private static final String DATABASE_PATH = Environment.getExternalStorageDirectory().getAbsoluteFile()+ "/MYFOLDER/";
    private static final String DATABASE_NAME = "TheWorld.db";
    private static final int DATABASE_VERSION = 1;

    MyDatabaseHelper(Context context) {
        super(context, DATABASE_PATH+DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        CountriesDb.onCreate(db);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        CountriesDb.onUpgrade(db, oldVersion, newVersion);
    }
}

不要忘记为您的清单添加权限:

<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

完毕!如果您通读上面的帖子,答案是基于柯克斯的建议,因此阅读他推荐的链接会有所帮助。我还有更多的测试要做,以防我之前的数据库结构错误。

于 2013-04-03T08:15:01.877 回答