8

Hier ist die logcat:Illegal: Ungültige Spalte

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) 

Die Zeile, die mit ihm verbunden ist, ist:

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); 
} 
... 

Was könnte das Problem sein? Die Datenbank ist einfach erstellt. Gibt es noch einen anderen Code, den Sie sehen müssen?

UPDATE:
Ich bin sehr sicher, dass diese Spalte vorhanden ist. Ich fragte die Datenbank mit diesem:

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]); 
} 

Und in 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 

So ist die Spalte vorhanden ist.

+0

Welches ist Linie: 105? Aufgabe = getContentResolver(). Abfrage (uri, PROJECTION, null, null, null); – fiction

+0

Ja. Du hast Recht. –

+0

Info - 'Ungültige Spalte Fälligkeitsdatum'. Sind Sie 100% sicher, dass es eine solche Säule gibt? – fiction

Antwort

7

Ich fand eine seltsame Lösung zu diesem Problem. In String[] PROJECTION. Sie tun müssen:

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 
}; 
+1

Können Sie erklären, warum das funktioniert? – HEATH3N

0

Haben Sie diese Spalte in der Projektionskarte, bezogen auf die Tabelle mit dieser Spalte Content-Provider hinzufügen? Ich hoffe das hilft.

17

Die Spalte existiert zweifellos in Ihrer Datenbank, aber wenn Sie die Spalte nicht zu einer Sache namens Projektion Karte hinzugefügt haben, erhalten Sie die "ungültige Spalte" Fehler, den Sie sehen. Sie können die Projektionskarte über eine Query Builder-Objekt, wie folgt hinzufügen:

// 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, ...) 

Um zu verstehen, was passiert, schauen Sie in der Quelle für die SQLiteQueryBuilder Klasse, und Sie werden die folgenden sehen:

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]); 
      } 
     } 
[...] 

Im Grunde prüft es die Spalten, die Sie in Ihrer Projektion angefordert haben, mit einer Liste von "erlaubten" Spalten. Wenn die Karte nicht die Spalte aus Ihrer Projektion enthält, wird eine IllegalArgumentException ausgelöst, genau wie Sie gesehen haben. (Ich stelle mir vor, diese Überprüfung gegen die Karte ist eine Sicherheitsfunktion, um SQL-Angriffe von Personen zu verhindern, die Ihren Inhaltsanbieter missbrauchen.)

Beachten Sie auch, dass Sie in Ihrer Abfrage "strikte" Projektionskarten festlegen Erbauer:

qb.setStrictProjectionMap(true); 

Dann in diesem Fall ist es Ihnen die genauen Spaltennamen ... wissen, erwartet Wenn Sie es nicht gesetzt ist, überprüft es für den „AS“ Spalte alias - ich denke, das erklärt die " seltsame Reparatur "Sie entdeckt.

Hoffe, das hilft.

+0

tns @DMH gute Arbeit! – FlipNovid