9

ログキャットは次のとおりです。

01-15 16:06:03.622: ERROR/AndroidRuntime(22300): Uncaught handler: thread main exiting due to uncaught exception
01-15 16:06:03.657: ERROR/AndroidRuntime(22300): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mohit.geo2do/com.mohit.geo2do.activities.TaskEdit}: java.lang.IllegalArgumentException: Invalid column due_date
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.os.Looper.loop(Looper.java:123)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.ActivityThread.main(ActivityThread.java:4363)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at java.lang.reflect.Method.invokeNative(Native Method)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at java.lang.reflect.Method.invoke(Method.java:521)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at dalvik.system.NativeStart.main(Native Method)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300): Caused by: java.lang.IllegalArgumentException: Invalid column due_date
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.database.sqlite.SQLiteQueryBuilder.computeProjection(SQLiteQueryBuilder.java:508)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.database.sqlite.SQLiteQueryBuilder.buildQuery(SQLiteQueryBuilder.java:356)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:309)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:266)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at com.mohit.geo2do.provider.TasksProvider.query(TasksProvider.java:174)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.content.ContentProvider$Transport.query(ContentProvider.java:130)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.content.ContentResolver.query(ContentResolver.java:202)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at com.mohit.geo2do.activities.TaskEdit.onCreate(TaskEdit.java:105)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-15 16:06:03.657: ERROR/AndroidRuntime(22300):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)

それに関連付けられている行は次のとおりです。

private Cursor task;
private Uri uri;
private String[] PROJECTION { 
    Tasks._ID, Tasks.TITLE, Tasks.COMPLETED, Tasks.DUE_DATE, Tasks.IMPORTANCE, Tasks.NOTES
};
...
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.edit_task);
    ...
    uri = getIntent().getData();
    task = getContentResolver().query(uri, PROJECTION, null, null, null);
} 
...

何が問題なのですか?データベースは問題なく作成されます。あなたが見る必要がある他のコードはありますか?

更新:
このコラムが存在すると確信しています。これでデータベースにクエリを実行しました:

Cursor c = db.rawQuery("SELECT * FROM tasks LIMIT 1", null);
for (int i = 0; i < c.getColumnNames().length; i++) {
    Log.v(TAG, c.getColumnNames()[i]);
}

そしてLogCatで:

01-15 16:52:07.857: VERBOSE/TasksProvider(24325): Creating database...
01-15 16:52:07.862: VERBOSE/TasksProvider(24325): _id
01-15 16:52:07.862: VERBOSE/TasksProvider(24325): title
01-15 16:52:07.862: VERBOSE/TasksProvider(24325): completed
01-15 16:52:07.862: VERBOSE/TasksProvider(24325): due_date
01-15 16:52:07.862: VERBOSE/TasksProvider(24325): notes
01-15 16:52:07.862: VERBOSE/TasksProvider(24325): importance

したがって、列は存在します。

4

3 に答える 3

18

列は間違いなくデータベースに存在しますが、射影マップと呼ばれるものに列を追加していない場合、表示されている「無効な列」エラーが発生します。次のように、クエリ ビルダー オブジェクトを介して投影図を追加できます。

// The projection map is a hashmap of strings
HashMap<String, String> MyProjectionMap;
MyProjectionMap = new HashMap<String, String>();

// Add column mappings to the projection map
MyProjectionMap.put(Tasks._ID, Tasks._ID);
MyProjectionMap.put(Tasks.TITLE, Tasks.TITLE);
[...]

SQLiteQueryBuilder qb;
qb.setTables("tasks");
qb.setProjectionMap(MyProjectionMap)

// Then do your query
Cursor c = qb.query(db, projection, ...)

何が起こるかを理解するために、SQLiteQueryBuilder クラスのソースを調べると、次のように表示されます。

private String[] computeProjection(String[] projectionIn) {
    if (projectionIn != null && projectionIn.length > 0) {
       if (mProjectionMap != null) {
          [...]
          for (int i = 0; i < length; i++) {
             String userColumn = projectionIn[i];
             String column = mProjectionMap.get(userColumn);
             [...]
             if (!mStrictProjectionMap && ( userColumn.contains(" AS ") || userColumn.contains(" as "))) {
                /* A column alias already exist */
                projection[i] = userColumn;
                continue;
             }
             throw new IllegalArgumentException("Invalid column " + projectionIn[i]);
          }
      }
[...]

基本的には、プロジェクションで要求した列を「許可された」列のリストと照合してチェックします。マップにプロジェクションの列が含まれていない場合は、見たように IllegalArgumentException がスローされることがわかります。(マップに対するこのチェックは、コンテンツ プロバイダーを悪用する人々による SQL ベースの攻撃を防ぐためのセキュリティ機能だと思いますが、それは単なる推測です。)

また、クエリ ビルダーで「厳密な」射影マップを設定する場合は、次の点にも注意してください。

qb.setStrictProjectionMap(true);

その場合、正確な列名を知っていることが期待されます...設定しない場合、「AS」列エイリアスをチェックします-それはあなたが発見した「奇妙な修正」を説明していると思います。

お役に立てれば。

于 2011-07-21T20:29:31.960 に答える
9

これに対する奇妙な修正を見つけました。でString[] PROJECTION。あなたがしなければなりません:

private String[] PROJECTION { 
    Tasks._ID, 
    Tasks.TITLE, 
    Tasks.COMPLETED,
    Tasks.DUE_DATE + " as " + Tasks.DUE_DATE, 
    Tasks.IMPORTANCE + " as " + Tasks.DUE_DATE, 
    Tasks.NOTES + " as " + Tasks.NOTES
};
于 2011-01-15T22:19:41.100 に答える
0

この列のあるテーブルを基準にして、コンテンツプロバイダーの投影マップにこの列を追加しましたか?これがお役に立てば幸いです。

于 2011-02-10T15:20:37.920 に答える