Cursor.getType() for API Level <11

前端 未结 4 1045
北荒
北荒 2020-12-10 01:00

I\'m querying the CallLog content provider and need to detect the column types.

In Honeycomb and newer (API Level 11+) you can get a columns preferred data type by c

4条回答
  •  佛祖请我去吃肉
    2020-12-10 01:51

    I faced the same problem in the past. I tackled it with a pretty nice solution. Match this with your needs. In my case I have an amount of different objects which are all synced to a server in the cloud. They all have common properties, so that they all inherit from a common BaseObject. This object has a method that takes a cursor as a parameter and returns a new object of the same type, so that each object that inherits from it, overrides this method with the extended properties of it.

    *Note that the inheritance of objects is not necessary for this approach. It's just a smarter way of doing it. As long as you have the same method in all the objects you need to take form DB this will work as you'll be able to see in the end.

    Let me illustrate that:

    Our baseObject.

    public class BaseObject{
    
        protected int number;
        protected String text;
    
        public  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;
        }
    }
    

    A new object that inherits from the first.

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

    Finally in your database it's as easy as to ask for the data you want by calling a generic method "getAllObjects" and passing the class type you want to query along with the other parameters of the query:

    public synchronized  ArrayList getObjectsForClass(final Class classType,
            String selection, String[] selectionArgs, String sort, String limit) {
    
        ArrayList objects = null;
    
        if (db == null || !db.isOpen()) {
            db = getWritableDatabase();
        }
    
        objects = new ArrayList();
    
        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;
    }
    

    And there you go. One generic method to get any object from the your database and to successfully turn it into an object or an array of objects in runtime.

    Notes:

    • Every object should have a method getTable() in order to be able to query the right table
    • In this approach there's also a OODB connection as you may see. You can use the same approach without that, by just querying all items (SELECT * FROM...)

    Hope it helps. Answer back with issues or doubts.

提交回复
热议问题