Cursor.getType () für API Level <11

Ich frage den CallLog-Inhaltsanbieter ab und muss die Spaltentypen erkennen.

In Honeycomb und neuer (API Level 11+) können Sie einen Spalten- Cursor.getType(int columnIndex) indem Sie die Methode Cursor.getType(int columnIndex) die einen der folgenden Typen zurückgibt:

  • Richtige Ausrichtung Spalte in Android Tisch Layout
  • Java-Abhängigkeits-Injektion: Dagger 1 vs Dolch 2, was besser ist?
  • Gradle-Synchronisierung fehlgeschlagen: Fehler beim Erstellen von Build Tools Revision 24.0.0 rc1
  • Android: Wie man mehrere Selektoren in einer einzigen XML-Datei schreibt
  • Erkennung der physischen Menütaste in Android drücken
  • Android Recyclerview vs ListView mit Viewholder
    • FELD_TYPE_NULL (0)
    • FELD_TYPE_INTEGER (1)
    • FELD_TYPE_FLOAT (2)
    • FELD_TYPE_STRING (3)
    • FELD_TYPE_BLOB (4)

    Wie kann ich das auf Pre-Honeycomb <11 Geräte erreichen?

    Ich habe folgendes ausprobiert:

     for ( int i = 0; i < cursor.getColumnCount(); i++ ) { int columnType = -1; try { cursor.getInt( i ); columnType = Cursor.FIELD_TYPE_INTEGER; } catch ( Exception ignore ) { try { cursor.getString( i ); columnType = Cursor.FIELD_TYPE_STRING; } catch ( Exception ignore1 ) { try { cursor.getFloat( i ); columnType = Cursor.FIELD_TYPE_FLOAT; } catch ( Exception ignore2 ) { try { cursor.getBlob( i ); columnType = Cursor.FIELD_TYPE_BLOB; } catch ( Exception ignore3 ) { columnType = Cursor.FIELD_TYPE_NULL; } } } } } 

    Allerdings wird keine Ausnahme ausgelöst. Die Daten werden immer in der ersten Art gegossen, die Sie überprüfen, in diesem Fall getInt (). Das heißt, ich bekomme die richtigen Werte, wenn der Spaltentyp Integer ist, aber ein 0 für alle anderen Typen.

    Warum schaue ich nicht in die Dokumentation, um zu überprüfen, welche Art gespeichert ist? Die Spalten unterscheiden sich je nach Gerätehersteller und nicht alle von ihnen sind dokumentiert, siehe diese Frage: Wie behandeln Sie herstellerabhängige Unterschiede in ContentProvider?

    Irgendwelche Ideen?

  • Android sort arraylist von Eigenschaften
  • Android Speech Recognition API funktioniert nicht in Android 7 Nougat
  • Wann man handler.post () & wann zum neuen Thread ()
  • Was ist mit curl clone.bundle Fehler auf AOSP Repo Sync zu tun
  • Getting "Fragment hat keine Ansicht" nach der Aufnahme von anderen Fragment ohne UI
  • Kleine Caps auf TextViews, EditTexts und Buttons in Android
  • 4 Solutions collect form web for “Cursor.getType () für API Level <11”

    Sie können diesen Code verwenden, wenn der Cursor in einer gültigen Zeile positioniert ist:

     CursorWrapper cw = (CursorWrapper)cursor; Class<?> cursorWrapper = CursorWrapper.class; Field mCursor = cursorWrapper.getDeclaredField("mCursor"); mCursor.setAccessible(true); AbstractWindowedCursor abstractWindowedCursor = (AbstractWindowedCursor)mCursor.get(cw); CursorWindow cursorWindow = abstractWindowedCursor.getWindow(); int pos = abstractWindowedCursor.getPosition(); for ( int i = 0; i < cursor.getColumnCount(); i++ ) { String type = null; if (cursorWindow.isNull(pos, i)) { type = "Cursor.FIELD_TYPE_NULL"; } else if (cursorWindow.isLong(pos, i)) { type = "Cursor.FIELD_TYPE_INTEGER"; } else if (cursorWindow.isFloat(pos, i)) { type = "Cursor.FIELD_TYPE_FLOAT"; } else if (cursorWindow.isString(pos, i)) { type = "Cursor.FIELD_TYPE_STRING"; } else if (cursorWindow.isBlob(pos, i)) { type = "Cursor.FIELD_TYPE_BLOB"; } } 

    Beachten Sie, dass Cursor.FIELD_TYPE_ * Konstante Werte ab HONEYCOMB definiert sind.

    Erweiterung auf Juans Antwort, hier ist mein Ersatz für die API 11 Methode Cursor.getType (int i) – für einen Cursor, der von einer SQL-Abfrage wiederholt wird

     public class DbCompat { protected static final int FIELD_TYPE_BLOB = 4; protected static final int FIELD_TYPE_FLOAT = 2; protected static final int FIELD_TYPE_INTEGER = 1; protected static final int FIELD_TYPE_NULL = 0; protected static final int FIELD_TYPE_STRING = 3; static int getType(Cursor cursor, int i) throws Exception { SQLiteCursor sqLiteCursor = (SQLiteCursor) cursor; CursorWindow cursorWindow = sqLiteCursor.getWindow(); int pos = cursor.getPosition(); int type = -1; if (cursorWindow.isNull(pos, i)) { type = FIELD_TYPE_NULL; } else if (cursorWindow.isLong(pos, i)) { type = FIELD_TYPE_INTEGER; } else if (cursorWindow.isFloat(pos, i)) { type = FIELD_TYPE_FLOAT; } else if (cursorWindow.isString(pos, i)) { type = FIELD_TYPE_STRING; } else if (cursorWindow.isBlob(pos, i)) { type = FIELD_TYPE_BLOB; } return type; } } 

    Cist: https://gist.github.com/kassim/c340cbfc5243db3a4826

    Es gibt etwas, das funktionieren kann: http://developer.android.com/reference/android/database/DatabaseUtils.html cursorRowToContentValues

    Kopiert die Zeile in ein ContentValues-Objekt. Dann kannst du ContentValues.get () aufrufen, die dir ein Objekt gibt. Sie können dann die Klasse dieses Objekts anschauen.

    bearbeiten

    Entsprechend dem Quellcode von DatabaseUtils sind das Objekt entweder Blobs oder Strings.

    Bearbeiten 2

    Wenn jedoch Ihr Cursor ein WindowCursor ist, hat es Methoden, die Objekttypen zu kennen. (IsBlob, isString, isLong …)

    Ich habe in der Vergangenheit das gleiche Problem gesehen. Ich habe es mit einer ziemlich schönen Lösung angepackt. Match dies mit Ihren Bedürfnissen. In meinem Fall habe ich eine Menge von verschiedenen Objekten, die alle mit einem Server in der Cloud synchronisiert sind. Sie haben alle gemeinsame Eigenschaften, so dass sie alle von einem gemeinsamen BaseObject erben. Dieses Objekt hat eine Methode, die einen Cursor als Parameter annimmt und ein neues Objekt desselben Typs zurückgibt, so dass jedes Objekt, das von ihm erbt, diese Methode mit den erweiterten Eigenschaften überschreibt.

    * Beachten Sie, dass die Vererbung von Objekten für diesen Ansatz nicht notwendig ist. Es ist nur eine schlauerere Art, es zu tun. Solange du die gleiche Methode in allen Objekten hast, musst du Form DB nehmen, das wird funktionieren, wie du am Ende sehen kannst.

    Lassen Sie mich das verdeutlichen:

    Unser baseObject.

     public class BaseObject{ protected int number; protected String text; public <T extends BaseObject> T setObject(Cursor c) { number = c.getInt(cur.getColumnIndexOrThrow(COLUMN_NAME_FOR_NUMBER)); text = c.getString(cur.getColumnIndexOrThrow(COLUMN_NAME_FOR_TEXT)); return (T) this; } } 

    Ein neues Objekt, das von der ersten erbt.

     public class Contact extends BaseObject{ private String name; @Override public <T extends BaseObject> T setObject(Cursor c) { super.setObject(c); name = c.getString(cur.getColumnIndexOrThrow(COLUMN_NAME_FOR_NAME)); return (T) this; } } 

    Schließlich ist es in Ihrer Datenbank so einfach, die gewünschten Daten zu verlangen, indem Sie eine generische Methode "getAllObjects" anrufen und den Klassentyp, den Sie mit den anderen Parametern der Abfrage abfragen möchten, übergeben:

     public synchronized <T extends BaseObject> ArrayList<T> getObjectsForClass(final Class<T> classType, String selection, String[] selectionArgs, String sort, String limit) { ArrayList<T> objects = null; if (db == null || !db.isOpen()) { db = getWritableDatabase(); } objects = new ArrayList<T>(); Cursor c = null; T object; try { object = classType.newInstance(); String table = object.getTable(); StringBuilder tableSb = new StringBuilder(); tableSb.append(table).append(" INNER JOIN ").append(Constants.DB_BASE_OBJECT_TABLE) .append(" ON ").append(table).append(".").append(BaseObject.DB_OBJECT_ID_KEY).append(" = ") .append(Constants.DB_BASE_OBJECT_TABLE).append(".") .append(BaseObject.DB_ID_KEY); c = db.query(tableSb.toString(), null, selection, selectionArgs, null, null, sort, limit); if (c.getCount() > 0) { c.moveToFirst(); while (!c.isAfterLast()) { object = classType.newInstance(); object.setObject(c); objects.add(object); c.moveToNext(); } } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } c.close(); return objects; } 

    Und da gehst du hin Eine generische Methode, um ein beliebiges Objekt aus der Datenbank zu erhalten und es erfolgreich in ein Objekt oder ein Array von Objekten zur Laufzeit zu verwandeln.

    Notizen:

    • Jedes Objekt sollte eine Methode getTable () haben, um die richtige Tabelle abfragen zu können
    • In diesem Ansatz gibt es auch eine OODB Verbindung, wie Sie sehen können. Sie können den gleichen Ansatz verwenden, ohne dass, indem Sie nur alle Elemente abfragen (SELECT * FROM …)

    Ich hoffe es hilft. Antwort mit Fragen oder Zweifeln.

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.