diff --git a/api/current.xml b/api/current.xml
index 2b31a64541228..bafbb6894a6cc 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -55658,6 +55658,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -57300,7 +57396,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
@@ -57315,7 +57411,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
@@ -57330,7 +57426,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
@@ -57345,7 +57441,7 @@
synchronized="false"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
@@ -57756,6 +57852,19 @@
+
+
+
+
+
+
+
+
+ * Returned column types are
+ *
+ * - {@link #FIELD_TYPE_NULL}
+ * - {@link #FIELD_TYPE_INTEGER}
+ * - {@link #FIELD_TYPE_FLOAT}
+ * - {@link #FIELD_TYPE_STRING}
+ * - {@link #FIELD_TYPE_BLOB}
+ *
+ *
+ *
+ * @param columnIndex the zero-based index of the target column.
+ * @return column value type
+ */
+ int getType(int columnIndex);
+
/**
* Returns true if the value in the indicated column is null.
*
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index c756825a79855..39889b983e6cd 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -217,14 +217,11 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
* @param row the row to read from, row - getStartPosition() being the actual row in the window
* @param col the column to read from
* @return {@code true} if given field is {@code NULL}
+ * @deprecated use {@link #getType(int, int)} instead
*/
+ @Deprecated
public boolean isNull(int row, int col) {
- acquireReference();
- try {
- return isNull_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
+ return getType(row, col) == Cursor.FIELD_TYPE_NULL;
}
private native boolean isNull_native(int row, int col);
@@ -247,20 +244,43 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
private native byte[] getBlob_native(int row, int col);
+ /**
+ * Returns data type of the given column's value.
+ *
+ * Returned column types are
+ *
+ * - {@link Cursor#FIELD_TYPE_NULL}
+ * - {@link Cursor#FIELD_TYPE_INTEGER}
+ * - {@link Cursor#FIELD_TYPE_FLOAT}
+ * - {@link Cursor#FIELD_TYPE_STRING}
+ * - {@link Cursor#FIELD_TYPE_BLOB}
+ *
+ *
+ *
+ * @param row the row to read from, row - getStartPosition() being the actual row in the window
+ * @param col the column to read from
+ * @return the value type
+ */
+ public int getType(int row, int col) {
+ acquireReference();
+ try {
+ return getType_native(row - mStartPos, col);
+ } finally {
+ releaseReference();
+ }
+ }
+
/**
* Checks if a field contains either a blob or is null.
*
* @param row the row to read from, row - getStartPosition() being the actual row in the window
* @param col the column to read from
* @return {@code true} if given field is {@code NULL} or a blob
+ * @deprecated use {@link #getType(int, int)} instead
*/
+ @Deprecated
public boolean isBlob(int row, int col) {
- acquireReference();
- try {
- return isBlob_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
+ return getType(row, col) == Cursor.FIELD_TYPE_BLOB;
}
/**
@@ -269,14 +289,11 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
* @param row the row to read from, row - getStartPosition() being the actual row in the window
* @param col the column to read from
* @return {@code true} if given field is a long
+ * @deprecated use {@link #getType(int, int)} instead
*/
+ @Deprecated
public boolean isLong(int row, int col) {
- acquireReference();
- try {
- return isInteger_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
+ return getType(row, col) == Cursor.FIELD_TYPE_INTEGER;
}
/**
@@ -285,14 +302,11 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
* @param row the row to read from, row - getStartPosition() being the actual row in the window
* @param col the column to read from
* @return {@code true} if given field is a float
+ * @deprecated use {@link #getType(int, int)} instead
*/
+ @Deprecated
public boolean isFloat(int row, int col) {
- acquireReference();
- try {
- return isFloat_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
+ return getType(row, col) == Cursor.FIELD_TYPE_FLOAT;
}
/**
@@ -301,20 +315,18 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
* @param row the row to read from, row - getStartPosition() being the actual row in the window
* @param col the column to read from
* @return {@code true} if given field is {@code NULL} or a String
+ * @deprecated use {@link #getType(int, int)} instead
*/
+ @Deprecated
public boolean isString(int row, int col) {
- acquireReference();
- try {
- return isString_native(row - mStartPos, col);
- } finally {
- releaseReference();
- }
+ return getType(row, col) == Cursor.FIELD_TYPE_STRING;
}
private native boolean isBlob_native(int row, int col);
private native boolean isString_native(int row, int col);
private native boolean isInteger_native(int row, int col);
private native boolean isFloat_native(int row, int col);
+ private native int getType_native(int row, int col);
/**
* Returns a String for the given field.
diff --git a/core/java/android/database/CursorWrapper.java b/core/java/android/database/CursorWrapper.java
index 633b2b3015772..2ac94707b607f 100644
--- a/core/java/android/database/CursorWrapper.java
+++ b/core/java/android/database/CursorWrapper.java
@@ -130,6 +130,10 @@ public class CursorWrapper implements Cursor {
return mCursor.isLast();
}
+ public int getType(int columnIndex) {
+ return mCursor.getType(columnIndex);
+ }
+
public boolean isNull(int columnIndex) {
return mCursor.isNull(columnIndex);
}
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 9bfbb74eeb274..af93eee4c7715 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -192,6 +192,37 @@ public class DatabaseUtils {
}
}
+ /**
+ * Returns data type of the given object's value.
+ *
+ * Returned values are
+ *
+ * - {@link Cursor#FIELD_TYPE_NULL}
+ * - {@link Cursor#FIELD_TYPE_INTEGER}
+ * - {@link Cursor#FIELD_TYPE_FLOAT}
+ * - {@link Cursor#FIELD_TYPE_STRING}
+ * - {@link Cursor#FIELD_TYPE_BLOB}
+ *
+ *
+ *
+ * @param obj the object whose value type is to be returned
+ * @return object value type
+ * @hide
+ */
+ public static int getTypeOfObject(Object obj) {
+ if (obj == null) {
+ return Cursor.FIELD_TYPE_NULL;
+ } else if (obj instanceof byte[]) {
+ return Cursor.FIELD_TYPE_BLOB;
+ } else if (obj instanceof Float || obj instanceof Double) {
+ return Cursor.FIELD_TYPE_FLOAT;
+ } else if (obj instanceof Long || obj instanceof Integer) {
+ return Cursor.FIELD_TYPE_INTEGER;
+ } else {
+ return Cursor.FIELD_TYPE_STRING;
+ }
+ }
+
/**
* Appends an SQL string to the given StringBuilder, including the opening
* and closing single quotes. Any single quotes internal to sqlString will
diff --git a/core/java/android/database/MatrixCursor.java b/core/java/android/database/MatrixCursor.java
index d5c3a32d884d2..5c1b9689370ad 100644
--- a/core/java/android/database/MatrixCursor.java
+++ b/core/java/android/database/MatrixCursor.java
@@ -271,6 +271,11 @@ public class MatrixCursor extends AbstractCursor {
return Double.parseDouble(value.toString());
}
+ @Override
+ public int getType(int column) {
+ return DatabaseUtils.getTypeOfObject(get(column));
+ }
+
@Override
public boolean isNull(int column) {
return get(column) == null;
diff --git a/core/java/android/database/MergeCursor.java b/core/java/android/database/MergeCursor.java
index cb6d7ac2ee200..2c25db765a2ba 100644
--- a/core/java/android/database/MergeCursor.java
+++ b/core/java/android/database/MergeCursor.java
@@ -128,6 +128,11 @@ public class MergeCursor extends AbstractCursor
return mCursor.getDouble(column);
}
+ @Override
+ public int getType(int column) {
+ return mCursor.getType(column);
+ }
+
@Override
public boolean isNull(int column)
{
diff --git a/core/java/com/android/internal/database/SortCursor.java b/core/java/com/android/internal/database/SortCursor.java
index 12248a227abff..00255128972c1 100644
--- a/core/java/com/android/internal/database/SortCursor.java
+++ b/core/java/com/android/internal/database/SortCursor.java
@@ -217,6 +217,11 @@ public class SortCursor extends AbstractCursor
return mCursor.getDouble(column);
}
+ @Override
+ public int getType(int column) {
+ return mCursor.getType(column);
+ }
+
@Override
public boolean isNull(int column)
{
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index fba6f0f668fae..55f5252761964 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -652,6 +652,22 @@ static void freeLastRow(JNIEnv * env, jobject object) {
window->freeLastRow();
}
+static jint getType_native(JNIEnv* env, jobject object, jint row, jint column)
+{
+ int32_t err;
+ CursorWindow * window = GET_WINDOW(env, object);
+ LOG_WINDOW("returning column type affinity for %d,%d from %p", row, column, window);
+
+ field_slot_t field;
+ err = window->read_field_slot(row, column, &field);
+ if (err != 0) {
+ throwExceptionWithRowCol(env, row, column);
+ return NULL;
+ }
+
+ return field.type;
+}
+
static JNINativeMethod sMethods[] =
{
/* name, signature, funcPtr */
@@ -679,6 +695,7 @@ static JNINativeMethod sMethods[] =
{"isString_native", "(II)Z", (void *)isString_native},
{"isFloat_native", "(II)Z", (void *)isFloat_native},
{"isInteger_native", "(II)Z", (void *)isInteger_native},
+ {"getType_native", "(II)I", (void *)getType_native},
};
int register_android_database_CursorWindow(JNIEnv * env)
diff --git a/include/binder/CursorWindow.h b/include/binder/CursorWindow.h
index bda0d31fb9c79..4fbff2ac9476e 100644
--- a/include/binder/CursorWindow.h
+++ b/include/binder/CursorWindow.h
@@ -1,16 +1,16 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
* limitations under the License.
*/
@@ -80,11 +80,11 @@ typedef struct
} data;
} __attribute__((packed)) field_slot_t;
+#define FIELD_TYPE_NULL 0
#define FIELD_TYPE_INTEGER 1
#define FIELD_TYPE_FLOAT 2
#define FIELD_TYPE_STRING 3
#define FIELD_TYPE_BLOB 4
-#define FIELD_TYPE_NULL 5
/**
* This class stores a set of rows from a database in a buffer. The begining of the
@@ -170,7 +170,7 @@ public:
row_slot_t * allocRowSlot();
row_slot_t * getRowSlot(int row);
-
+
/**
* return NULL if Failed to find rowSlot or
* Invalid rowSlot
diff --git a/test-runner/src/android/test/mock/MockCursor.java b/test-runner/src/android/test/mock/MockCursor.java
index c817532d2f180..baa150a0e0e6b 100644
--- a/test-runner/src/android/test/mock/MockCursor.java
+++ b/test-runner/src/android/test/mock/MockCursor.java
@@ -191,4 +191,8 @@ public class MockCursor implements Cursor {
public void unregisterDataSetObserver(DataSetObserver observer) {
throw new UnsupportedOperationException("unimplemented mock method");
}
+
+ public int getType(int columnIndex) {
+ throw new UnsupportedOperationException("unimplemented mock method");
+ }
}
\ No newline at end of file