1

I am new in Android. I have followed some tutorials about ContentProviders and Loaders. I have created a Notepad application, but I think it fails to save the content into database. I have two activities: NoteList with the list of notes and NoteEdit where the notes are created, and one ContentProvider: NotesDbAdapter. When I save the note , the list is empty.

NoteEdit.java

public class NoteEdit extends Activity{

public static int numTitle = 1; 
public static String curDate = "";
 public static String curText = "";  
private EditText mTitleText;
private EditText mBodyText;
private TextView mDateText;
private Long mRowId;
private String mode;
private Cursor note;

private NotesDbAdapter mDbHelper;

 @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

 //   mDbHelper = new NotesDbAdapter(this);
//   mDbHelper.open();        

setContentView(R.layout.note_edit);
setTitle(R.string.app_name);

mTitleText = (EditText) findViewById(R.id.title);
mBodyText = (EditText) findViewById(R.id.body);
mDateText = (TextView) findViewById(R.id.notelist_date);

long msTime = System.currentTimeMillis();  
Date curDateTime = new Date(msTime);

SimpleDateFormat formatter = new SimpleDateFormat("d'/'M'/'y");  
curDate = formatter.format(curDateTime);        

mDateText.setText(""+curDate);


mRowId = (savedInstanceState == null) ? null :
    (Long) savedInstanceState.getSerializable(NotesDbAdapter.KEY_ROWID);
if (mRowId == null) {
    Bundle extras = getIntent().getExtras();
    mode = extras.getString("mode");
    mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID)
                            : null;
}

populateFields();

}

 public static class LineEditText extends EditText{
    // we need this constructor for LayoutInflater
    public LineEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
            mRect = new Rect();
            mPaint = new Paint();
            mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            mPaint.setColor(Color.BLUE);
    }

    private Rect mRect;
    private Paint mPaint;       

    @Override
    protected void onDraw(Canvas canvas) {

        int height = getHeight();
        int line_height = getLineHeight();

        int count = height / line_height;

        if (getLineCount() > count)
            count = getLineCount();

        Rect r = mRect;
        Paint paint = mPaint;
        int baseline = getLineBounds(0, r);

        for (int i = 0; i < count; i++) {

            canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint);
            baseline += getLineHeight();

        super.onDraw(canvas);
    }

}
 }

  @Override
    protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    saveState();
    outState.putSerializable(NotesDbAdapter.KEY_ROWID, mRowId);
  }

  @Override
 protected void onPause() {
    super.onPause();
    saveState();
}

@Override
protected void onResume() {
    super.onResume();
    populateFields();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.noteedit_menu, menu);

    return true;        
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_delete:
        if(note != null){
            note.close();
            note = null;
        }
        if(mRowId != null){
            //mDbHelper.deleteNote(mRowId);
            Uri uri = Uri.parse(NotesDbAdapter.CONTENT_URI+"/"+mRowId);
            //getContentResolver().delete(uri, null, null);
            mDbHelper.delete(uri,null,null);
        }
        finish();

        return true;
    case R.id.menu_save:
        saveState();


        finish();           
    default:
        return super.onOptionsItemSelected(item);
    }
}

private void saveState() {
    String title = mTitleText.getText().toString();
    String body = mBodyText.getText().toString();
    String date = mDateText.getText().toString();

    ContentValues values = new ContentValues();
    values.put(NotesDbAdapter.KEY_TITLE, title);
    values.put(NotesDbAdapter.KEY_BODY, body);
    values.put(NotesDbAdapter.KEY_DATE,date);

    if(mode.trim().equalsIgnoreCase("add")){
    getContentResolver().insert(NotesDbAdapter.CONTENT_URI,values);
        }
          else {
                Uri uri = Uri.parse(NotesDbAdapter.CONTENT_URI + "/" + mRowId);
                getContentResolver().update(uri, values, null, null);
               }    
        }


private void populateFields() {
    if (mRowId != null) {
        String[] projection = { 
                NotesDbAdapter.KEY_ROWID,
                NotesDbAdapter.KEY_TITLE,
                NotesDbAdapter.KEY_BODY,
                NotesDbAdapter.KEY_DATE};
              Uri uri = Uri.parse(NotesDbAdapter.CONTENT_URI + "/" + mRowId);
              Cursor cursor = getContentResolver().query(uri, projection, null, null,
                null);
              if (cursor.moveToFirst()) {

               String title = cursor.getString(cursor.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE));
               String body = cursor.getString(cursor.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY));
              String date = cursor.getString(cursor.getColumnIndexOrThrow(NotesDbAdapter.KEY_DATE));
               mTitleText.setText(title);
               mBodyText.setText(body);
               mDateText.setText(date);
              }
    }
}

NoteList.java

public class NoteList extends ListActivity implements LoaderManager.LoaderCallbacks<Cursor>{

  private SimpleCursorAdapter dataAdapter;

 private static final int ACTIVITY_CREATE=0;
 private static final int ACTIVITY_EDIT=1;

 private static final int DELETE_ID = Menu.FIRST;

 @Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.notelist);
  //  mDbHelper = new NotesDbAdapter(this);
   //  mDbHelper.open();
  fillData();             
 registerForContextMenu(getListView());
 Button addnote = (Button)findViewById(R.id.addnotebutton);
 addnote.setOnClickListener(new View.OnClickListener() {     
    @Override
    public void onClick(View v) {
        createNote();
        }
  });
  }


  @Override
 public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.notelist_menu, menu);
return true;        
 }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
        return super.onOptionsItemSelected(item);
    }


 private void createNote() {
Intent i = new Intent(this, NoteEdit.class);
Bundle bundle = new Bundle();
 bundle.putString("mode", "add");
 i.putExtras(bundle);
startActivityForResult(i, ACTIVITY_CREATE);     
  }

 @Override
  protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(this, NoteEdit.class);
Bundle bundle = new Bundle();
bundle.putString("mode", "update");
bundle.putLong(NotesDbAdapter.KEY_ROWID, id);
i.putExtras(bundle);
 //  i.putExtra(NotesDbAdapter.KEY_ROWID, id);
   startActivityForResult(i, ACTIVITY_EDIT);
   }

 private void fillData() {
  // The desired columns to be bound
 String[] columns = new String[] {
  NotesDbAdapter.KEY_TITLE,
  NotesDbAdapter.KEY_DATE
   };

// the XML defined views which the data will be bound to
int[] to = new int[] { 
  R.id.text1,
  R.id.date_row
};

// create an adapter from the SimpleCursorAdapter
dataAdapter = new SimpleCursorAdapter(
  this, 
  R.layout.notes_row, 
  null, 
  columns, 
  to,
  0);

setListAdapter(dataAdapter);
//Ensures a loader is initialized and active.
getLoaderManager().initLoader(0, null, this);

}

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
    ContextMenuInfo menuInfo) {
   super.onCreateContextMenu(menu, v, menuInfo);
   menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}

  @Override
  public boolean onContextItemSelected(MenuItem item) {
   switch(item.getItemId()) {
    case DELETE_ID:
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
       // mDbHelper.deleteNote(info.id);

        Uri uri = Uri.parse(NotesDbAdapter.CONTENT_URI + "/" + info.id);
        getContentResolver().delete(uri, null, null);

        fillData();
        return true;
   }
   return super.onContextItemSelected(item);
   }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
     fillData();        
   }   


  protected void onResume() {
  super.onResume();
  //Starts a new or restarts an existing Loader in this manager
  getLoaderManager().restartLoader(0, null, this);
   }


   // This is called when a new Loader needs to be created.
  @Override
 public Loader<Cursor> onCreateLoader(int id, Bundle args) {
   String[] projection = { 
   NotesDbAdapter.KEY_ROWID,
   NotesDbAdapter.KEY_TITLE, 
   NotesDbAdapter.KEY_BODY, 
   NotesDbAdapter.KEY_DATE};
 CursorLoader cursorLoader = new CursorLoader(this,
   NotesDbAdapter.CONTENT_URI, projection, null, null, null);
 return cursorLoader;
  }

  @Override
 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.)
       dataAdapter.swapCursor(data);
  }

  @Override
  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.
  dataAdapter.swapCursor(null);
   }

NotesDbAdapter.java

 public class NotesDbAdapter extends ContentProvider{

private Context mCtx;
     static final String PROVIDER_NAME = "com.example.note.contentprovider.notesdbadapter";
     static final String URL = "content://" + PROVIDER_NAME + "/notes";
     static final Uri CONTENT_URI = Uri.parse(URL);

public static final String KEY_TITLE = "title";
public static final String KEY_DATE = "date";
public static final String KEY_BODY = "body";
public static final String KEY_ROWID = "_id";

public static final int NOTES = 1;
public static final int NOTES_ID = 2;

private static HashMap<String,String> Notes;

static final UriMatcher uriMatcher;
       static{
          uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
          uriMatcher.addURI(PROVIDER_NAME, "notes", NOTES);
          uriMatcher.addURI(PROVIDER_NAME, "notes/#", NOTES_ID);
       }

private static final String TAG = "NotesDbAdapter";
private DatabaseHelper mhelper;
private SQLiteDatabase database;
private static final String DATABASE_NAME = "data";
private static final String DATABASE_TABLE = "notes";
private static final int DATABASE_VERSION = 2;

private static final String DATABASE_CREATE =
    "create table notes (_id integer primary key autoincrement, "
    + "title text not null, body text not null, date text not null);";

private static class DatabaseHelper extends SQLiteOpenHelper {

    DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DATABASE_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS notes");
        onCreate(db);
    }
}

public boolean onCreate() {
            // TODO Auto-generated method stub
            Context context = getContext();
            mhelper = new DatabaseHelper(context);
            // permissions to be writabl
            database =mhelper.getWritableDatabase();
            if(database == null)
                return false;
            else
                return true;   
        }

@Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        // TODO Auto-generated method stub
         SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
         // the TABLE_NAME to query on
         queryBuilder.setTables(DATABASE_TABLE);
          switch (uriMatcher.match(uri)) {
          // maps all database column names
          case NOTES:
              queryBuilder.setProjectionMap(Notes);
             break;
          case NOTES_ID:
              queryBuilder.appendWhere( KEY_ROWID + "=" + uri.getLastPathSegment());
             break;
          default:
             throw new IllegalArgumentException("Unknown URI " + uri);
          }
          Cursor cursor = queryBuilder.query(database, projection, selection,
                  selectionArgs, null, null, sortOrder);

          cursor.setNotificationUri(getContext().getContentResolver(), uri);
          return cursor;
    }

@Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO Auto-generated method stub
        long row = database.insert(DATABASE_TABLE, "", values);
        // If record is added successfully
          if(row > 0) {
             Uri newUri = ContentUris.withAppendedId(CONTENT_URI, row);
             getContext().getContentResolver().notifyChange(newUri, null);
             return newUri;
          }
          throw new SQLException("Fail to add a new record into " + uri);
    }

@Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
         int count = 0;
          switch (uriMatcher.match(uri)){
          case NOTES:
             count = database.update(DATABASE_TABLE, values, selection, selectionArgs);
             break;
          case NOTES_ID:
             count = database.update(DATABASE_TABLE, values, KEY_ROWID +
                     " = " + uri.getLastPathSegment() +
                     (!TextUtils.isEmpty(selection) ? " AND (" +
                     selection + ')' : ""), selectionArgs);
             break;
          default:
             throw new IllegalArgumentException("Unsupported URI " + uri );
          }
          getContext().getContentResolver().notifyChange(uri, null);
          return count;
    }

@Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // TODO Auto-generated method stub
        int count = 0;
         switch (uriMatcher.match(uri)){
          case NOTES:
              // delete all the records of the table
              count = database.delete(DATABASE_TABLE, selection, selectionArgs);
              break;
          case NOTES_ID:
              String id = uri.getLastPathSegment(); //gets the id
              count = database.delete( DATABASE_TABLE, KEY_ROWID +  " = " + id +
                    (!TextUtils.isEmpty(selection) ? " AND (" +
                    selection + ')' : ""), selectionArgs);
              break;
          default:
              throw new IllegalArgumentException("Unsupported URI " + uri);
          }
          getContext().getContentResolver().notifyChange(uri, null);
          return count;
    }

@Override
    public String getType(Uri uri) {
        // TODO Auto-generated method stub
        switch (uriMatcher.match(uri)){
          // Get all friend-birthday record
          case NOTES:
             return "vnd.android.cursor.dir/vnd.com.example.note.contentprovider.notesdbadapter/notes";
          // Get a particular friend
          case NOTES_ID:
             return "vnd.android.cursor.item/vnd.com.example.note.contentprovider.notesdbadapter/notes";
          default:
             throw new IllegalArgumentException("Unsupported URI: " + uri);
        }
    }


 public NotesDbAdapter(){

   }

    public NotesDbAdapter(Context ctx) {
     this.mCtx = ctx;

   }

  public NotesDbAdapter open() throws SQLException {
    mhelper = new DatabaseHelper(mCtx);
    database = mhelper.getWritableDatabase();
   return this;
   }

   public void close() {
    mhelper.close();
    }

notelist.xml

  <?xml version="1.0" encoding="utf-8"?>
  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
  android:layout_height="match_parent"
   android:background="@drawable/notelist">

   <TextView
    android:id="@+id/textViewTop"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:paddingBottom="35dp" />

<ListView
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/btmLayout"
    android:layout_below="@+id/textViewTop"
    android:background="#FFF9C8"
    android:divider="#D3D3D3"
    android:dividerHeight="1sp" 
    android:footerDividersEnabled="true" />

<LinearLayout
    android:id="@+id/btmLayout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:gravity="center"        
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="3dp"
    android:layout_marginTop="10dp">

    <Button
        android:id="@+id/addnotebutton"
        android:layout_width="50dp"
        android:layout_height="wrap_content"
        android:background="@drawable/create_note" />

</LinearLayout>

notes_row.xml

   <?xml version="1.0" encoding="utf-8"?>
   <RelativeLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
    android:layout_height="match_parent">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_marginLeft="10sp"
    android:textSize="25sp"
    android:hint="@string/no_title"
    android:id="@+id/text1"/>

<TextView 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize = "25sp"
    android:id="@+id/date_row"      
    android:layout_alignParentRight="true"      
    android:layout_marginRight="10sp"/>
     </RelativeLayout>
Madalina
  • 65
  • 6
  • Please don't flag your questions with terms like "pls help" or "urgent". – Bart Kiers Apr 16 '14 at 09:24
  • I'm sorry.It won't happen again.I'm just a bit stressed out. – Madalina Apr 16 '14 at 10:08
  • I don't know exactly what you are trying to do with `queryBuilder.setProjectionMap(Notes);`, but `Notes` is not initialized, and I don't think you need a projection map anyway. – njzk2 Apr 17 '14 at 19:37
  • Still not working. I can't see my sqlite database to check if database have something stored. My data folder from File Explorer is empty – Madalina Apr 17 '14 at 19:49
  • The data should be inserted in the database if you use the provider's insert method, otherwise you would get an exception. Judging by the fact that you restart the loader each time the activity comes to the foreground are you sure the `ListView` is visible in the `R.layout.notelist` layout file? – user Apr 17 '14 at 20:16
  • Yes, the ListView is visible. – Madalina Apr 17 '14 at 20:37
  • Can you still post that layout? – user Apr 17 '14 at 20:59
  • Oh my mistake. The ListView is not visible :( – Madalina Apr 17 '14 at 22:15
  • I manage to make the ListView visible but it's not showing the Textviews.Should I use a Custom ArrayAdapter? – Madalina Apr 17 '14 at 23:27
  • It's not showing the Textviews, meaning that you see blank rows or you don't see any rows at all? Also, just out of curiosity, if you insert a note and then you click back until you get out of the application, when you restart it do you see the new data? – user Apr 18 '14 at 06:37
  • I don't see any rows at all, also any new data. – Madalina Apr 18 '14 at 09:44

0 Answers0