Pergunta

I've built a single ContentProvider as a frontend for my 3 table sqlitedb. It's my first ContentProvider and i can't find a good tutorial on how to built it. The schema is actually very simple.

CONTROLS: _id, title, text, last(time)used, phoneNumber

EVENTS: _id, text, phoneNumber, date, type

NUMBERS: _id, title, phoneNumber

There are several kind of errors, as of now my biggest concern are:

1) I have two tabs with listFragments, tab1 loads CONTROLS, tab2 loads EVENTS. Tab1 will load forever (using the LOADER to make it an asynctask), Tab2 will display the empty message in 1 second (work as intended).

2) When i try to insert something in NUMBERS table i get the below logcat (HAD TO EDIT DUE TO CHAR LIMIT) that tells me the columns don't exist. (I have tested inserting in other tables, but i think the result is the same) The ContentResolver.insert method will give -1 as a result.

3) when i built a query I usually use:

String selection = MyContentProvider.Data.C_ID + "=";
String[] args = {+ String.valueOf(id)};

as the selection and selectionArgs for the query. With this ContentProvider i have to use:

String selection = MyContentProvider.Data.C_ID + "='" + String.valueOf(id) + "'";

as the selection and null as selectionArgs or i get a syntax error.

This comes up when i invoke this method:

  public void save(){
    name= etContactName.getText().toString();
    number= etPhoneNumber.getText().toString();
    String empty="";
    if(name.equals(null) || number.equals(null) || name.equals(empty) || number.equals(empty)){
        Toast.makeText(this, "Enter both name and number", Toast.LENGTH_SHORT).show();
    }else{
        ContentResolver cr= this.getContentResolver();
        ContentValues values= new ContentValues();

        values.put(MyContentProvider.Data.N_TITLE, name);
        values.put(MyContentProvider.Data.N_NUMBER, number);

        cr.insert(MyContentProvider.Data.CONTENT_URI_NUMBERS, values);
        NavUtils.navigateUpFromSameTask(this);
    }
}

Last but not least, my entire MyContentProvider class, where, i think, lays the error:

public class MyContentProvider extends ContentProvider {

@SuppressWarnings("unused")
private static final String TAG = "SurvContentProvider";
private static final String DATABASE_NAME = "surv.db";
private static final int DATABASE_VERSION = 5;

public static class Data{
    private Data(){
    }

    //Content Types
    public static final String CONTENT_TYPE_EVENTS = 
            "vnd.android.cursor.dir/vnd.com.corsalini.survcontr.SurvContentProvider.EVENTS";
    public static final String CONTENT_TYPE_EVENTS_ID = 
            "vnd.android.cursor.item/vnd.com.corsalini.survcontr.SurvContentProvider.EVENTS";
    public static final String CONTENT_TYPE_CONTROLS = 
            "vnd.android.cursor.dir/vnd.com.corsalini.survcontr.SurvContentProvider.CONTROLS";
    public static final String CONTENT_TYPE_CONTROLS_ID = 
            "vnd.android.cursor.item/vnd.com.corsalini.survcontr.SurvContentProvider.CONTROLS";
    public static final String CONTENT_TYPE_NUMBERS = 
            "vnd.android.cursor.dir/vnd.com.corsalini.survcontr.SurvContentProvider.NUMBERS";
    public static final String CONTENT_TYPE_NUMBERS_ID = 
            "vnd.android.cursor.item/vnd.com.corsalini.survcontr.SurvContentProvider.NUMBERS";
    //Content URIs
    public static final Uri CONTENT_URI_EVENTS = Uri.parse("content://"
            + MyContentProvider.AUTHORITY + "/EVENTS");
    public static final Uri CONTENT_URI_CONTROLS = Uri.parse("content://"
            + MyContentProvider.AUTHORITY + "/CONTROLS");
    public static final Uri CONTENT_URI_NUMBERS = Uri.parse("content://"
            + MyContentProvider.AUTHORITY + "/NUMBERS");

    //Tables
    //EVENTS Table
    public static final String E_ID= "_id";
    public static final String E_TEXT= "ETEXT";
    public static final String E_NUMBER= "ENUMBER";
    public static final String E_TYPE= "ETYPE";
    public static final String E_DATE= "EDATE";
    //Type COSTANTS
    public static final int SENT_PROGRESS=0;
    public static final int SENT_COMPLETED=1;
    public static final int RECEIVED_UNREAD=2;
    public static final int RECEIVED_READ=3;
    //CONTROLS Table
    public static final String C_ID= "_id";
    public static final String C_TITLE= "CTITLE";
    public static final String C_TEXT= "CTEXT";
    public static final String C_LAST= "CLAST";
    public static final String C_NUMBER= "CNUMBER";
    //NUMBERS Table
    public static final String N_ID= "_id";
    public static final String N_TITLE= "NTITLE";
    public static final String N_NUMBER= "NNUMBER";
}


private static HashMap<String, String> eventsProjectionMap;
private static HashMap<String, String> controlsProjectionMap;
private static HashMap<String, String> numbersProjectionMap;


public static final String AUTHORITY = "com.corsalini.survcontr.SurvContentProvider";
private static final int EVENTS=1;
private static final int EVENTS_ID=10;
private static final int CONTROLS=2;
private static final int CONTROLS_ID=20;
private static final int NUMBERS=3;
private static final int NUMBERS_ID=30;

private static final String TABLE_NAME_EVENTS = "EVENTS";
private static final String TABLE_NAME_CONTROLS = "CONTROLS";
private static final String TABLE_NAME_NUMBERS = "NUMBERS";

public static final String CREATE_TABLE_EVENTS= "CREATE TABLE IF NOT EXISTS "
        + TABLE_NAME_EVENTS + " ("
        + Data.E_ID + " INTEGER  PRIMARY KEY AUTOINCREMENT NOT NULL, "
        + Data.E_TEXT + " TEXT  NULL, "
        + Data.E_NUMBER + " TEXT  NULL, "
        + Data.E_TYPE + " INTEGER  NULL, "
        + Data.E_DATE + " TEXT  NULL);";

public static final String CREATE_TABLE_CONTROLS= "CREATE TABLE IF NOT EXISTS "
        + TABLE_NAME_CONTROLS + " ("
        + Data.C_ID + " INTEGER  PRIMARY KEY AUTOINCREMENT NOT NULL, "
        + Data.C_TITLE + " TEXT  NULL, "
        + Data.C_TEXT + " TEXT  NULL, "
        + Data.C_NUMBER + " TEXT  NULL, "
        + Data.C_LAST + " TEXT  NULL);";

public static final String CREATE_TABLE_NUMBERS= "CREATE TABLE IF NOT EXISTS "
        + TABLE_NAME_NUMBERS + " ("
        + Data.N_ID + " INTEGER  PRIMARY KEY AUTOINCREMENT NOT NULL, "
        + Data.N_TITLE + " TEXT  NULL, "
        + Data.N_NUMBER + " INTEGER  NULL);";
private static final UriMatcher sUriMatcher;
static{
    //UriMatcher
    sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    sUriMatcher.addURI(AUTHORITY, "EVENTS", EVENTS);
    sUriMatcher.addURI(AUTHORITY, "EVENTS/#", EVENTS_ID);
    sUriMatcher.addURI(AUTHORITY, "CONTROLS", CONTROLS);
    sUriMatcher.addURI(AUTHORITY, "CONTROLS/#", CONTROLS_ID);
    sUriMatcher.addURI(AUTHORITY, "NUMBERS", NUMBERS);
    sUriMatcher.addURI(AUTHORITY, "NUMBERS/#", NUMBERS_ID);
    //eventsProjectionMap
    eventsProjectionMap = new HashMap<String, String>();
    eventsProjectionMap.put(Data.E_ID, Data.E_ID);
    eventsProjectionMap.put(Data.E_TEXT, Data.E_TEXT);
    eventsProjectionMap.put(Data.E_NUMBER, Data.E_NUMBER);
    eventsProjectionMap.put(Data.E_TYPE, Data.E_TYPE);
    eventsProjectionMap.put(Data.E_DATE, Data.E_DATE);
    //controlsProjectionMap
    controlsProjectionMap = new HashMap<String, String>();
    controlsProjectionMap.put(Data.C_ID, Data.C_ID);
    controlsProjectionMap.put(Data.C_TITLE, Data.C_TITLE);
    controlsProjectionMap.put(Data.C_TEXT, Data.C_TEXT);
    controlsProjectionMap.put(Data.C_LAST, Data.C_LAST);
    controlsProjectionMap.put(Data.C_NUMBER, Data.C_NUMBER);
    //numbersProjectionMap
    numbersProjectionMap = new HashMap<String, String>();
    numbersProjectionMap.put(Data.N_ID, Data.N_ID);
    numbersProjectionMap.put(Data.N_TITLE, Data.N_TITLE);
    numbersProjectionMap.put(Data.N_NUMBER, Data.N_NUMBER);
}

private DatabaseHelper dbHelper;


private static class DatabaseHelper extends SQLiteOpenHelper {
    DatabaseHelper(Context context) {

        super(context, DATABASE_NAME, null, DATABASE_VERSION);

    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLE_EVENTS);
        db.execSQL(CREATE_TABLE_CONTROLS);
        db.execSQL(CREATE_TABLE_NUMBERS);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
         db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME_EVENTS);
         db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME_CONTROLS);
         db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME_NUMBERS);

         db.execSQL(CREATE_TABLE_EVENTS);
            db.execSQL(CREATE_TABLE_CONTROLS);
            db.execSQL(CREATE_TABLE_NUMBERS);
    }
}


@Override
public int delete(Uri uri, String where, String[] whereArgs) {
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    int count=0;
    switch (sUriMatcher.match(uri)) {
    case EVENTS:
        break;
    case EVENTS_ID:
        where = where + "_id = " +      uri.getLastPathSegment();
        count = db.delete(TABLE_NAME_EVENTS, where, whereArgs);
        break;
    case CONTROLS:
        break;
    case CONTROLS_ID:
        where = where + "_id = " +      uri.getLastPathSegment();
        count = db.delete(TABLE_NAME_CONTROLS, where, whereArgs);
        break;
    case NUMBERS:
        break;
    case NUMBERS_ID:
        where = where + "_id = " +      uri.getLastPathSegment();
        count = db.delete(TABLE_NAME_NUMBERS, where, whereArgs);
        break;
    default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }

    getContext().getContentResolver().notifyChange(uri, null);
    return count;

}


@Override
public String getType(Uri uri) {

    switch (sUriMatcher.match(uri)) {
    case EVENTS:
        return Data.CONTENT_TYPE_EVENTS;
    case EVENTS_ID:
        return Data.CONTENT_TYPE_EVENTS_ID;
    case CONTROLS:
        return Data.CONTENT_TYPE_CONTROLS;
    case CONTROLS_ID:
        return Data.CONTENT_TYPE_CONTROLS_ID;
    case NUMBERS:
        return Data.CONTENT_TYPE_NUMBERS;
    case NUMBERS_ID:
        return Data.CONTENT_TYPE_NUMBERS_ID; 
    default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }

}

@Override
public Uri insert(Uri uri, ContentValues initialValues) {
    if (sUriMatcher.match(uri) != EVENTS && sUriMatcher.match(uri) != CONTROLS
            && sUriMatcher.match(uri) != NUMBERS) {
        throw new IllegalArgumentException("Unknown URI " + uri);
    }
    else 
    {
        ContentValues values;
        if (initialValues != null) {
            values = new ContentValues(initialValues);
        } else {
            values = new ContentValues();
        }

        SQLiteDatabase db = dbHelper.getWritableDatabase();
        long rowId=0;
        switch (sUriMatcher.match(uri)) {
        case EVENTS:
            rowId = db.insert(TABLE_NAME_EVENTS, Data.E_TEXT, values);
            break;
        case CONTROLS:
            rowId = db.insert(TABLE_NAME_CONTROLS, Data.C_TEXT, values);
            break;
        case NUMBERS:
            rowId = db.insert(TABLE_NAME_EVENTS, Data.N_TITLE, values);
            break;
        }
        Log.d("INSERT", "ROWID= "+rowId);

        if (rowId > 0) {
            Log.d("INSERT", "ROWID= "+rowId +" ENTRATO");   
            Uri noteUri=null;
            switch (sUriMatcher.match(uri)) {
            case EVENTS:
                noteUri = ContentUris.withAppendedId(Data.CONTENT_URI_EVENTS, rowId);
                break;
            case CONTROLS:
                noteUri = ContentUris.withAppendedId(Data.CONTENT_URI_CONTROLS, rowId);
                break;
            case NUMBERS:
                noteUri = ContentUris.withAppendedId(Data.CONTENT_URI_NUMBERS, rowId);
                break;
            }
            getContext().getContentResolver().notifyChange(noteUri, null);
            return noteUri;
        }else{

            throw new SQLException("Failed to insert row into " + uri);
        }
    }
}

@Override
public boolean onCreate() {
    dbHelper = new DatabaseHelper(getContext());
    return true;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    switch (sUriMatcher.match(uri)) {   

    case EVENTS:
        qb.setTables(TABLE_NAME_EVENTS);
        qb.setProjectionMap(eventsProjectionMap);
        break;
    case EVENTS_ID:
        qb.setTables(TABLE_NAME_EVENTS);
        qb.setProjectionMap(eventsProjectionMap);
        selection = selection + "_id =?s " + uri.getLastPathSegment();
        break;
    case CONTROLS:
        qb.setTables(TABLE_NAME_CONTROLS);
        qb.setProjectionMap(controlsProjectionMap);
        break;
    case CONTROLS_ID:
        qb.setTables(TABLE_NAME_CONTROLS);
        qb.setProjectionMap(controlsProjectionMap);
        selection = selection + "_id =?s " + uri.getLastPathSegment();
        break;
    case NUMBERS:
        qb.setTables(TABLE_NAME_NUMBERS);
        qb.setProjectionMap(numbersProjectionMap);
        break;
    case NUMBERS_ID:
        qb.setTables(TABLE_NAME_NUMBERS);
        qb.setProjectionMap(numbersProjectionMap);
        selection = selection + "_id =?s " + uri.getLastPathSegment();
        break;
    default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }
    SQLiteDatabase db = dbHelper.getReadableDatabase();
    Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
    c.setNotificationUri(getContext().getContentResolver(), uri);
    return c;
}

@Override
public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
    SQLiteDatabase db = dbHelper.getWritableDatabase();
    int count;
    switch (sUriMatcher.match(uri)) {
    case EVENTS:
        count = db.update(TABLE_NAME_EVENTS, values, where, whereArgs);
        break;
    case CONTROLS:
        count = db.update(TABLE_NAME_CONTROLS, values, where, whereArgs);
        break;
    case NUMBERS:
        count = db.update(TABLE_NAME_NUMBERS, values, where, whereArgs);
        break;
    default:
        throw new IllegalArgumentException("Unknown URI " + uri);
    }
    getContext().getContentResolver().notifyChange(uri, null);
    return count;
}

}

EDIT: FragControl:

public class FragControls extends ListFragment implements  LoaderManager.LoaderCallbacks<Cursor>{

private static final int CONTROLS_LOADER = 0x01;


SimpleCursorAdapter mAdapter;
ContentResolver resolver;
String mCurFilter;
DbOp db;
private String numberSelected = "0";


@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    resolver= getActivity().getContentResolver();
    // Give some text to display if there is no data.  In a real
    // application this would come from a resource.
    setEmptyText(this.getString(R.string.add_control)); 

    // We have a menu item to show in action bar.
    setHasOptionsMenu(true);

    // Create an empty adapter we will use to display the loaded data.
    mAdapter = new SimpleCursorAdapter(getActivity(),
            android.R.layout.simple_list_item_2, null,
            new String[] { MyContentProvider.Data.C_TITLE, MyContentProvider.Data.C_LAST },
            new int[] { android.R.id.text1, android.R.id.text2 },
            CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    setListAdapter(mAdapter);

    // Start out with a progress indicator.
    setListShown(false);

    // Prepare the loader.  Either re-connect with an existing one,
    // or start a new one.
    getActivity().getSupportLoaderManager().initLoader(CONTROLS_LOADER, null, this);
    db= new DbOp();
    getActivity().registerForContextMenu(getListView());
}

public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_controls, menu);      
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {

    case R.id.menu_add_control:
        Intent addContrInt = new Intent(getActivity(), ActNewControl.class);
        addContrInt.putExtra("contrNumber", numberSelected);
        startActivity(addContrInt);
        break;
    }
    return super.onOptionsItemSelected(item);
}


@Override public void onListItemClick(ListView l, View v, int position, long id) {

    String selection= Data.C_ID+" = ?";
    String[] args={String.valueOf(id)};
    Cursor c=resolver.query(Data.CONTENT_URI_CONTROLS, null, selection, args, null);
    c.moveToFirst();
    String text = c.getString(c.getColumnIndex(Data.C_TEXT));
    String number = c.getString(c.getColumnIndex(Data.C_NUMBER));
    c.close();
    sendSMS(number, text);

    Log.i("FragmentComplexList", "Item clicked: " + id);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    android.view.MenuInflater inflater = getActivity().getMenuInflater();
    inflater.inflate(R.menu.contr_context_menu, menu);
}


@Override
public boolean onContextItemSelected(MenuItem item) {

    AdapterView.AdapterContextMenuInfo info;
    try {
        info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
    } catch (ClassCastException e) {
        Log.e("", "bad menuInfo", e);
        return false;
    }
    long id = getListAdapter().getItemId(info.position);
    switch (item.getItemId()){
    case R.id.cm_delete:
        String selection= MyContentProvider.Data.C_ID +"='"+ id+"'";
        resolver.delete( MyContentProvider.Data.CONTENT_URI_CONTROLS,
                selection, null);
        break;
    case R.id.cm_edit:
        Intent editContrInt=  new Intent(getActivity(), ActNewControl.class);
        editContrInt.putExtra("contrNumber", numberSelected);
        editContrInt.putExtra("contrId", id);
        startActivity(editContrInt);
        break;
    }
    Log.d("", "id = " + id);
    Toast.makeText(getActivity(), "id = " + id, Toast.LENGTH_SHORT).show();
    return true;
}


static final String[] SUMMARY_PROJECTION = new String[] {
    MyContentProvider.Data.C_ID,
    MyContentProvider.Data.C_TITLE,
    MyContentProvider.Data.C_TEXT,
    MyContentProvider.Data.C_LAST,
    MyContentProvider.Data.C_NUMBER,

};

public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    String selection= MyContentProvider.Data.C_NUMBER +"=?";
    String[] selectionArgs= {numberSelected};

    return new CursorLoader(getActivity(),  MyContentProvider.Data.CONTENT_URI_CONTROLS,
            SUMMARY_PROJECTION, selection, selectionArgs,
            null);
}

public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

    mAdapter.swapCursor(data);


    if (isResumed()) {
        setListShown(true);
    } else {
        setListShownNoAnimation(true);
    }
}

public void onLoaderReset(Loader<Cursor> loader) {

    mAdapter.swapCursor(null);
}

public void setNumberSelected(String number){
    numberSelected = number;
    getActivity().getSupportLoaderManager().restartLoader(CONTROLS_LOADER, null, this);
}}

FragEvents:

public class FragEvents extends ListFragment implements  LoaderManager.LoaderCallbacks<Cursor>{



@Override
public void onPause() {
    db.allRead(resolver);
    super.onPause();

}

private static final int EVENTS_LOADER = 0x02;
private String numberSelected="0";
ContentResolver resolver;
// This is the Adapter being used to display the list's data.
SimpleCursorAdapter mAdapter;

// If non-null, this is the current filter the user has provided.
String mCurFilter;
DbOp db;

@Override public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    // Give some text to display if there is no data.  In a real
    // application this would come from a resource.
    setEmptyText(this.getString(R.string.perform_event)); 

    // We have a menu item to show in action bar.
    setHasOptionsMenu(true);

    // Create an empty adapter we will use to display the loaded data.
    mAdapter = new EventsAdapter(getActivity(),
            android.R.layout.simple_list_item_2, null,
            new String[] { MyContentProvider.Data.E_TEXT, MyContentProvider.Data.E_DATE, 
        MyContentProvider.Data.E_NUMBER, MyContentProvider.Data.E_TYPE  },
        new int[] { android.R.id.text1, android.R.id.text2 },
        CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    setListAdapter(mAdapter);

    // Start out with a progress indicator.
    setListShown(false);

    // Prepare the loader.  Either re-connect with an existing one,
    // or start a new one.
    getActivity().getSupportLoaderManager().initLoader(EVENTS_LOADER, null, this);
    resolver = getActivity().getContentResolver();
    db= new DbOp();
}

public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_events, menu);  
}



@Override public void onListItemClick(ListView l, View v, int position, long id) {
    //TODO Insert desired behavior here.
    Log.i("FragmentComplexList", "Item clicked: " + id);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    android.view.MenuInflater inflater = getActivity().getMenuInflater();
    inflater.inflate(R.menu.events_context_menu, menu);
}


@SuppressWarnings("deprecation")
@Override
public boolean onContextItemSelected(MenuItem item) {

    AdapterView.AdapterContextMenuInfo info;
    try {
        info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
    } catch (ClassCastException e) {
        Log.e("", "bad menuInfo", e);
        return false;
    }
    long id = getListAdapter().getItemId(info.position);
    switch (item.getItemId()){
    case R.id.cm_delete:
        String selection= MyContentProvider.Data.E_ID +"='"+ id+"'";
        resolver.delete( MyContentProvider.Data.CONTENT_URI_EVENTS,
                selection, null);
        break;
    case R.id.cm_copy_text:
        //TODO copiare testo negli appunti
        Cursor curs= mAdapter.getCursor();
        curs.moveToPosition(info.position);
        String text1 = curs.getString(curs.getColumnIndex(MyContentProvider.Data.E_TEXT));
        curs.close();
        int sdk = android.os.Build.VERSION.SDK_INT;
        if(sdk < android.os.Build.VERSION_CODES.HONEYCOMB) {
            android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
            clipboard.setText(text1);
        } else {
            android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE); 
            android.content.ClipData clip = android.content.ClipData.newPlainText("event text",text1);
            clipboard.setPrimaryClip(clip);
        }
        break;
    case R.id.cm_share:
        //TODO condividere testo
        Cursor cur= mAdapter.getCursor();
        cur.moveToPosition(info.position);
        String text = cur.getString(cur.getColumnIndex(MyContentProvider.Data.E_TEXT));
        cur.close();
        Intent sharingIntent = new Intent(Intent.ACTION_SEND);
        sharingIntent.setType("text/plain");
        sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, text);
        startActivity(Intent.createChooser(sharingIntent, "Share using"));
        break;
    }
    Log.d("", "id = " + id);
    Toast.makeText(getActivity(), "id = " + id, Toast.LENGTH_SHORT).show();
    return true;
}
// These are the Contacts rows that we will retrieve.
static final String[] SUMMARY_PROJECTION = new String[] {
    MyContentProvider.Data.E_ID,
    MyContentProvider.Data.E_DATE,
    MyContentProvider.Data.E_NUMBER,
    MyContentProvider.Data.E_TEXT,
    MyContentProvider.Data.E_TYPE,

};

public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    String selection= MyContentProvider.Data.E_NUMBER +" = ?";
    String[] selectionArgs= {numberSelected};

    return new CursorLoader(getActivity(),  MyContentProvider.Data.CONTENT_URI_EVENTS,
            SUMMARY_PROJECTION, selection, selectionArgs,
            Data.E_ID + " DESC");
}

public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    // Swap the new cursor in.  (The framework will take care of closing the
    // old cursor once we return.)
    mAdapter.swapCursor(data);

    // The list should now be shown.
    if (isResumed()) {
        setListShown(true);
    } else {
        setListShownNoAnimation(true);
    }
}

public void onLoaderReset(Loader<Cursor> loader) {
    // This is called when the last Cursor provided to onLoadFinished()
    // above is about to be closed.  We need to make sure we are no
    // longer using it.
    mAdapter.swapCursor(null);
}


public void setNumberSelected(String number){
    numberSelected = number;
    getActivity().getSupportLoaderManager().restartLoader(EVENTS_LOADER, null, this);
}

}

Sidenote:

Those 2 frag won't add menuitem, i think it's a ActionBarSherlock fault, but if i extend SherlokListFragment i get an error because the onOptionsItemSelected() is final and i cannot override it.

Foi útil?

Solução

1 You may want to explain better what is the problem, I didn't understand.

2 I think that instead of:

String selection = MyContentProvider.Data.C_ID + "=";
String[] args = {+ String.valueOf(id)}; // what is with the + sign??

you want this:

String selection = MyContentProvider.Data.C_ID + "= ?"; // the ? is the placeholder
String[] args = {String.valueOf(id)};

3 Try to uninstall the app then reinstall it and run it again. Also for the NUMBERS table you have this line in the ContentProvider's insert method:

rowId = db.insert(TABLE_NAME_EVENTS, Data.N_TITLE, values);

Are you sure it isn't:

rowId = db.insert(TABLE_NAME_NUMBERS, Data.N_TITLE, values);

?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top