Android Open Source - streaming_project Media Database Helper






From Project

Back to project page streaming_project.

License

The source code is released under:

GNU General Public License

If you think the Android project streaming_project listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.example.streaming.streaming;
//from   w  w w . j  a v  a  2s  .c  o m

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;


// It is a helper class that encapsulates the common tasks of creating, opening, and updating
// databases for storing the application data
// NOTE 1: MediaManager holds on to a private instance of MediaDatabaseHelper and provides the rest
// of the app with an API for inserting, querying, and otherwise managing the data in the database
// NOTE 2: Most apps have just one subclass of SQLiteOpenHelper and share a single instance of it
// with the rest of the application components
// NOTE 3: This is where we define the structure of the database, i.e. the database schema
// NOTE 4: SQLiteOpenHelper supports the ability to manage different versions of a database schema
// (that's why we have VERSION). However, it is not necessary for the Streaming app
// NOTE 5: getWritableDatabase() and getReadableDatabase() give access to an instance of
// SQLiteDatabase. getWritableDatabase() is used when writable database is needed, and
// getReadableDatabase() when only read access is required
// NOTE 6: The tables must contain a _id column so that the cursor associated with a ListView can
// retrieve the _ID column for a certain table
public class MediaDatabaseHelper extends SQLiteOpenHelper {
    // Constant name for the database file
    private static final String DB_NAME = "media_store.db";
    // Constant integer version number
    // NOTE: in a real app, each time changes are made to the database schema, the version constant
    // is incremented and code is written in onUpgrade()
    private static final int VERSION = 1;
    // Maximum number of rows in a media_store.db's table. It is used n MediaProvider
    // TODO: Is it necessary?
    public static final int MAX_ROWS = 1000000;

    // TODO: create more tables. Replace media table by two tables for each type of media: song and
    // TODO: movie. Should we create artist table? Don't think so, we should focus on the media files.
    public static final String TABLE_MEDIA = "media";
    // TODO: date should be called timestamp and year is when the media was produced
    // TODO: it is confusing to have _id and media_id. media_id refers to the id from the server media table
    // TODO: and _id refers to the media in the client media table. We should use another name for media_id
    // TODO: a possible solution would be to use media_id as the primary key of the media table. We are sure
    // TODO: that media_id is unique since it is a primary key in the server media table
    // Contract class constants
    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_MEDIA_ID = "media_id";
    public static final String COLUMN_MEDIA_FILENAME = "filename";
    public static final String COLUMN_MEDIA_TITLE = "title";
    public static final String COLUMN_MEDIA_ARTIST = "artist";
    public static final String COLUMN_MEDIA_ALBUM = "album"; // TODO: will not be used for the moment
    public static final String COLUMN_MEDIA_LENGTH = "length";
    public static final String COLUMN_MEDIA_MINUTES = "minutes";
    public static final String COLUMN_MEDIA_SECONDS = "seconds";
    public static final String COLUMN_MEDIA_ENCODER = "encoder";
    public static final String COLUMN_MEDIA_BITRATE = "bitrate";
    public static final String COLUMN_MEDIA_SAMPLE_RATE = "sample_rate";
    public static final String COLUMN_MEDIA_LAYER = "layer";
    public static final String COLUMN_MEDIA_YEAR = "year"; // TODO: will not be used for the moment
    public static final String COLUMN_MEDIA_DATE = "date"; // TODO: will not be used for the moment
    public static final String COLUMN_MEDIA_PHOTO = "photo"; // TODO: will not be used for the moment
    // TODO: we will save the image in an external folder (e.g. sd card?) and in the db we will
    // TODO: store only the path to the image

    // Instantiates an open helper for the provider's SQLite data repository
    // NOTE: Do not do database creation and upgrade here.
    public MediaDatabaseHelper(Context context) {
        // NOTE: the third param is the optional CursorFactory
        super(
                context,    // The application context
                DB_NAME,    // The name of the database)
                null,       // Uses the default SQLite cursor
                VERSION);   // The version number
    }

    // Establishes the schema for the newly created database
    // NOTE 1: SQLiteDatabase is a Java front-end to SQLite included by Android. It provides results
    // sets as Cursor instances.
    // NOTE 2: getWritableDatabase() trigger the creation of the database (i.e. onCreate() is
    // called) if it doesn't already exist.
    // TODO: call onUpgrade() every time you change the db schema, e.g. add a new column
    // TODO: see http://stackoverflow.com/a/19333750
    @Override
    public void onCreate(SQLiteDatabase db) {
        // NOTE 1: the most common pattern for database design is to use one database table for each
        // class in the application's model data
        // NOTE 2: One table will be created: media TODO: add more tables

        // Execute "CREATE TABLE" SQL statements on the freshly-created database

        // Create the "media" table
        // TODO: Check that the data types for the columns are valid,  especially year and date
        // TODO: which they can also be of type integer
        // TODO: Should we store both length and minutes+seconds or just length?
        // TODO: You should use COLUMN_MEDIA_* variables when referring to a column name
        db.execSQL("create table media (" +
                " _id integer primary key autoincrement, media_id integer, filename text, " +
                "title text, artist text, album text, length real, minutes integer, " +
                "seconds integer, encoder text, bitrate integer, sample_rate integer, " +
                "layer integer, year text, date text, photo text)");
    }

    // Executes migration code to move from one version of the database schema to another
    // It handles any schema or data changes that were necessary between versions
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Implement schema changes and data massage here when upgrading

        // NOTE: every time the app is started, I drop the media Table if it exists and re-create it
        // see MediaManager private constructor's note about the reason of doing it
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_MEDIA);
        onCreate(db);
    }

    // Inserts a NEW row in the media table and returns its ID
    public long insertMedia(Media media) {
        // NOTE: ContentValues objects represent the mapping of column names to values
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_MEDIA_ID, media.getMediaId());
        cv.put(COLUMN_MEDIA_FILENAME, media.getFilename());
        cv.put(COLUMN_MEDIA_TITLE, media.getTitle());
        cv.put(COLUMN_MEDIA_ARTIST, media.getArtist());
        cv.put(COLUMN_MEDIA_ALBUM, media.getAlbum());
        cv.put(COLUMN_MEDIA_LENGTH, media.getLength());
        cv.put(COLUMN_MEDIA_MINUTES, media.getMins());
        cv.put(COLUMN_MEDIA_SECONDS, media.getSecs());
        cv.put(COLUMN_MEDIA_ENCODER, media.getEncoder());
        cv.put(COLUMN_MEDIA_BITRATE, media.getBitrate());
        cv.put(COLUMN_MEDIA_SAMPLE_RATE, media.getSampleRate());
        cv.put(COLUMN_MEDIA_LAYER, media.getLayer());
        // TODO: add the year and date in the media table
        //cv.put(COLUMN_MEDIA_YEAR, media.getYear());
        //cv.put(COLUMN_MEDIA_DATE, media.getDate());
        // TODO: there is a NULLPointerException when trying to retrieve the photo filename
        // TODO: Photo is null when a Media object is created
        //cv.put(COLUMN_MEDIA_PHOTO, media.getPhoto().getFilename());
        return getWritableDatabase().insert(TABLE_MEDIA, null, cv);
    }

    // TODO: add description
    public void compiledInsertMedia(Media media) {
        String sql = "INSERT INTO " + TABLE_MEDIA + " VALUES (?,?,?,?,?,?,?,?,?,?,?,?);";
        SQLiteStatement statement = getWritableDatabase().compileStatement(sql);

        statement.clearBindings();
        statement.bindLong(1, media.getMediaId());
        statement.bindString(2, media.getFilename());
        statement.bindString(3, media.getTitle());
        statement.bindString(4, media.getArtist());
        statement.bindString(5, media.getAlbum());
        statement.bindDouble(6, media.getLength());
        statement.bindLong(7, media.getMins());
        statement.bindLong(8, media.getSecs());
        statement.bindString(9, media.getEncoder());
        statement.bindLong(10, media.getBitrate());
        statement.bindLong(11, media.getSampleRate());
        statement.bindLong(12, media.getLayer());
        // TODO: add the year and date in the media table
        //statement.bindString(COLUMN_MEDIA_YEAR, media.getYear());
        //statement.bindString(COLUMN_MEDIA_DATE, media.getDate());
        // TODO: there is a NULLPointerException when trying to retrieve the photo filename
        // TODO: Photo is null when a Media object is created
        //statement.bindString(COLUMN_MEDIA_PHOTO, media.getPhoto().getFilename());
        statement.execute();
    }

    // Returns a MediaCursor listing all the media in ascending order by media_id
    // NOTE 1: Querying a SQLiteDatabase returns an instance of Cursor describing the results
    // NOTE 2: The Cursors treat their results as a series of rows and columns, and only supports
    // Strings and primitive types for values
    // NOTE 3: The returned cursor will be wrapped in a CursorWrapper so that we can easily get
    // Media objects from a Cursor
    // NOTE 4: It is called in MediaManager and MediaListFragment
    public MediaCursor queryMediaList() {
        // Equivalent to "select * from media order by media_id asc"
        Cursor wrapped = getReadableDatabase().query(TABLE_MEDIA,
                null, null, null, null, null, COLUMN_MEDIA_ID + " asc");
        return new MediaCursor(wrapped);
    }

    // Returns a MediaCursor for a single media given its ID (not the media_id)
    public MediaCursor queryMedia(long id) {
        // Fetch all columns from TABLE_MEDIA, filtering them by the ID column, which is passed as
        // an argument to the where clause using a single-element string array
        // NOTE 1: the query is limited to returning only one row
        // NOTE 2: the result of the query is wrapped in a MediaCursor and returned to the caller
        Cursor wrapped = getReadableDatabase().query(TABLE_MEDIA,
                null, // All columns
                COLUMN_ID + " = ?", // Look for an ID (not media_id)
                new String[]{ String.valueOf(id) }, // with this value
                null, // group by
                null, // order by
                null, // having
                "1"); // limit 1 row
        return new MediaCursor(wrapped);
    }

    /**
     * A convenience class to wrap a cursor that returns rows from the "media" table.
     * The getMedia() method will give you a Media instance representing the current row.
     */
    // NOTE 1: CursorWrapper is a subclass of Cursor that is designed to wrap an existing Cursor and
    // forward along all of the method calls to it. It can provide with a good foundation on which
    // to build custom cursor implementations specific of the model objects. It allows us to get
    // instances of Media from a Cursor
    // NOTE 2: Its main purpose is to encapsulate the grunt work of turning a row in the media table
    // into an instance of Media, marshaling and massaging the data as needed
    public static class MediaCursor extends CursorWrapper {
        public MediaCursor(Cursor c) {
            super(c);
        }
        /**
         * Returns a Media object configured for the current row,
         * or null if the current row is invalid.
         */
        // NOTE: A user of MediaCursor would iterate over the rows in the result set and call getMedia()
        // for each row to get a nice object instead of a bunch of nasty primitives
        public Media getMedia() {
            // Check to ensure that the cursor is within its bounds
            // NOTE: isAfterLast() returns false if there are any results at all
            // TODO: do not understand what it does
            if (isBeforeFirst() || isAfterLast())
                return null;
            // Create and configure an instance of Media based on the values fo the current row's
            // columns
            Media media = new Media();
            media.setMediaId(getInt(getColumnIndex(COLUMN_MEDIA_ID)));
            media.setFilename(getString(getColumnIndex(COLUMN_MEDIA_FILENAME)));
            media.setTitle(getString(getColumnIndex(COLUMN_MEDIA_TITLE)));
            media.setArtist(getString(getColumnIndex(COLUMN_MEDIA_ARTIST)));
            media.setAlbum(getString(getColumnIndex(COLUMN_MEDIA_ALBUM)));
            media.setLength(getFloat(getColumnIndex(COLUMN_MEDIA_LENGTH)));
            media.setMins(getInt(getColumnIndex(COLUMN_MEDIA_MINUTES)));
            media.setSecs(getInt(getColumnIndex(COLUMN_MEDIA_SECONDS)));
            media.setEncoder(getString(getColumnIndex(COLUMN_MEDIA_ENCODER)));
            media.setBitrate(getInt(getColumnIndex(COLUMN_MEDIA_BITRATE)));
            media.setSampleRate(getInt(getColumnIndex(COLUMN_MEDIA_SAMPLE_RATE)));
            media.setLayer(getInt(getColumnIndex(COLUMN_MEDIA_LAYER)));
            // TODO: set the photo filename

            return media;
        }
    }
}




Java Source Code List

com.example.streaming.streaming.ApplicationTest.java
com.example.streaming.streaming.AssetsPropertyReader.java
com.example.streaming.streaming.DataFetcher.java
com.example.streaming.streaming.DataLoader.java
com.example.streaming.streaming.MainActivity.java
com.example.streaming.streaming.MediaActivity.java
com.example.streaming.streaming.MediaDatabaseHelper.java
com.example.streaming.streaming.MediaFragment.java
com.example.streaming.streaming.MediaListActivity.java
com.example.streaming.streaming.MediaListFragment.java
com.example.streaming.streaming.MediaLoader.java
com.example.streaming.streaming.MediaManager.java
com.example.streaming.streaming.MediaProvider.java
com.example.streaming.streaming.Media.java
com.example.streaming.streaming.SQLiteCursorLoader.java
com.example.streaming.streaming.SingleFragmentActivity.java