Back to project page streaming_project.
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.
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; } } }