Q:

How to correctly write big CRUD sqlite android app

I'm writing an app that manipulates with database consists of 3 tables. I created this database from json file using models (Worker model, specialty model) with getters and setters. Now I want to get specific info from this database. I'v already made it but my code is pretty silly. What I need is to change the architecture of my app but I don't know how exactly it should looks like.
This is the examples of my methods, and they are pretty week
This is how I add info into database. I like it, I think it's correct:
public void addWorker(Worker worker){

    List<Specialty> specialty;

    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();

    //fixind names
    String f_name = fixName(worker.getF_name());
    String l_name = fixName(worker.getL_name());
    String birthday = fixDate(worker.getBirthday());

    values.put(KEY_F_NAME, f_name);
    values.put(KEY_L_NAME, l_name);
    values.put(KEY_BIRTHDAY, birthday);
    values.put(KEY_AVATR_URL, worker.getAvart_url());
    specialty = worker.getSpecialty();
    long worker_id = db.insert(TABLE_WORKERS,null,values);

    //add unique specialty
    for (Specialty spec: specialty){
        createRelations(worker_id, spec.getSpecialty_id());
        if (getCount(spec.getSpecialty_id()) == 0){
            addSpecialty(spec);
        }

    }
}

And this is how I take info from database:
    public String[] getFullInfo(String worker_name){
        String selectQuery = "HUGE QUERY HERE "where workers.f_name =?";
        Log.e(LOG_TAG, selectQuery);
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor c = db.rawQuery(selectQuery, new String [] {worker_name});

    String[] details = new String[5];

    c.moveToFirst();
    while (c.isAfterLast() == false){
        details[0] = c.getString(c.getColumnIndex(KEY_F_NAME));
        details[1] = c.getString(c.getColumnIndex(KEY_L_NAME));
        details[2] = c.getString(c.getColumnIndex(KEY_BIRTHDAY));
        details[3] = c.getString(c.getColumnIndex("age"));
        details[4] = c.getString(c.getColumnIndex(KEY_SPEC_NAME));
        c.moveToNext();
    }
    return details;

}

This is my another query and it has different return type:
public List<Map<String ,String>> getWorkerListBySpec(String spec_name){

    String selectQuery = "HUGE QUERY HERE
            "where specialty.spec_name=?";
    Log.e(LOG_TAG, selectQuery);

    SQLiteDatabase db = this.getReadableDatabase();
    Cursor c = db.rawQuery(selectQuery, new String [] {spec_name});

    //making list of workers
    List<Map<String ,String>> data = new ArrayList<Map<String,String>>();
    c.moveToFirst();
    while (c.isAfterLast() == false){

            Map<String,String> datum = new HashMap<String,String>(2);
            datum.put(KEY_F_NAME,  c.getString(c.getColumnIndex(KEY_F_NAME)));
            datum.put(KEY_L_NAME, c.getString(c.getColumnIndex(KEY_L_NAME)));
            datum.put(KEY_BIRTHDAY, c.getString(c.getColumnIndex(KEY_BIRTHDAY)));
            data.add(datum);
        c.moveToNext();
    }
    return data;

}

and the third one, which also have different return type:
public List<String> getAllSpecs_Names(){
    List<String> spec_names = new ArrayList<String>();
    String selectQuery = "select * from " + TABLE_SPECIALTY;
    Log.e(LOG_TAG, selectQuery);

    SQLiteDatabase db = this.getReadableDatabase();
    Cursor c = db.rawQuery(selectQuery, null);

    if (c.moveToFirst()){
        do{
            spec_names.add(c.getString(c.getColumnIndex(KEY_SPEC_NAME)));
        }while (c.moveToNext());

    }

    return spec_names;
}

I know, that this is all wrong.
Please tell me how I should make all my queries. 
It will be good if you give me the link to check how the app should look like

A:

instead of returning a List or Map, you should better return a own CursorWrapper 
so you could could look like this:
 public WorkerCursor getWorkerListBySpec(String spec_name){
    String selectQuery = "HUGE QUERY HERE
            "where specialty.spec_name=?";
    Log.e(LOG_TAG, selectQuery);

    SQLiteDatabase db = this.getReadableDatabase();
    Cursor c = db.rawQuery(selectQuery, new String [] {spec_name});
    return new WorkerCursor(cursor);
}

public static class WorkerCursor extends CursorWrapper {

        /**
         * Creates a cursor wrapper.
         *
         * @param cursor The underlying cursor to wrap.
         */
        public WorkerCursor(Cursor cursor) {
            super(cursor);
        }

        public Worker getWorker() {
            return getWorkerAtCursor();
        }

        public Worker getWorker(int position) {
            if (moveToPosition(position)) {
                return getWorkerCursor();
            } else {
                return null;
            }
        }

        private Worker getWorkerAtCursor() {
            if (isBeforeFirst() || isAfterLast()) {
                return null;
            }
            worker worker = new Worker();
            worker.name = c.getString(c.getColumnIndex(KEY_F_NAME));
            ....
            return worker;
}
}

and the same for your List, just with a other CursorWrapper 
and don't forget to close the CursorWrapper, when it's no more needed, like in onDestroy of Activity and so 

