[- Video篇 -]:記一次SQLite的使用
0.前言
最近在重構我的影片播放器,專案有點點複雜,不可能全面的記錄
一些播放資訊的記錄感覺還是放在資料庫裡好一些,不然感覺很生硬
以前的SQLite介紹文章有點無病呻吟的感覺,這次來實際用一下,相信感觸會更深
1.解決影片播放量的記錄問題
2.解決影片進入時恢復到上次播放進度
3.解決查詢最近播放的n條記錄的問題
4.解決查詢播放最多的n條記錄的問題
一、SQLite使用步驟
1.表分析
表欄位
id 標識 主鍵,自增
path 影片名稱 varchar(120) 唯一 非空
current_pos 當前播放進度 TINYINT 預設為0
last_play_time 上次播放時間 CHAR(24) 2019-3-1 16:20:00
play_count 播放次數 INT 預設為0
|--- 建表語句 -------------------------------
CREATE TABLE video_player (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
path VARCHAR(120) UNIQUE NOT NULL,
current_pos TINYINT NOT NULL DEFAULT 0,
last_play_time CHAR(24) NOT NULL,
play_count INT NOT NULL DEFAULT 0
);
2.建立VideoDatabaseHelper繼承自SQLiteOpenHelper
public class VideoDatabaseHelper extends SQLiteOpenHelper {
private static String DATABASE_NAME = "i_video.db";//資料庫名
private static int DATABASE_VERSION = 1;//資料庫版本
public VideoDatabaseHelper(@Nullable Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
createSwordTable(db);
}
private void createSwordTable(SQLiteDatabase db) {
db.execSQL("CREATE TABLE video_player (n" +
"id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,n" +
"path VARCHAR(120) UNIQUE NOT NULL,n" +
"current_pos TINYINT NOT NULL DEFAULT 0,n" +
"last_play_time CHAR(24) NOT NULL,n" +
"play_count INT NOT NULL DEFAULT 0n" +
"); ");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
3.實體類簡單封裝
class VideoBean {
var id: Int = 0
var path: String = ""
var current_pos: Int = 0
var last_play_time: String = ""
var play_count: Int = 1
}
4.建立Dao來運算元據庫
用個單例來獲取VideoDao方便操作
public class VideoDao {
private static VideoDao sVideoDao;
private SQLiteOpenHelper mHelper;
public void setHelper(SQLiteOpenHelper helper) {
mHelper = helper;
}
private VideoDao() {
}
public static VideoDao newInstance() {
if (sVideoDao == null) {
synchronized (VideoDao.class) {
if (sVideoDao == null) {
sVideoDao = new VideoDao();
}
}
}
return sVideoDao;
}
/**
* 插入
*
* @param video
*/
public void insert(VideoBean video) {
if (contains(video.getPath())) {
addPlayCount(video.getPath());
} else {
mHelper.getWritableDatabase().execSQL(
"INSERT INTO video_player(path,current_pos,last_play_time,play_count) VALUES(?,?,?,?)",
new String[]{
video.getPath(),
video.getCurrent_pos() + "",
video.getLast_play_time(),
video.getPlay_count() + ""});
}
}
/**
* 將某影片播放量+1,並更新時間
*
* @param path 影片路徑
*/
private void addPlayCount(String path) {
int count = getPlayCount(path);
count++;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
String now = format.format(System.currentTimeMillis());
mHelper.getWritableDatabase().execSQL(
"UPDATE video_player SET play_count=? , last_play_time=?",
new String[]{count + "", now});
}
/**
* 根據路徑獲取播放量
*
* @param path 影片路徑
* @return 播放量
*/
private int getPlayCount(String path) {
int result = 0;
Cursor cursor = mHelper.getReadableDatabase().
rawQuery("SELECT play_count FROM video_player WHERE path=?", new String[]{path});
if (cursor.moveToNext()) {
result = cursor.getInt(cursor.getColumnIndex("play_count"));
}
cursor.close();
return result;
}
/**
* 檢測是否包含某影片
*
* @param path 影片路徑
* @return 否包含某影片
*/
public boolean contains(String path) {
Cursor cursor = mHelper.getReadableDatabase().
rawQuery("SELECT path FROM video_player WHERE path=?", new String[]{path});
boolean has = cursor.moveToNext();
cursor.close();
return has;
}
}
二、使用
1.關於插入
視屏播放器功能由VideoView實現,我上面封了一層VideoPlayerManager用來管理
在每次設定播放資源時插入資料,上面的插入方法在已經有值時,播放次數會 + 1
|--- 在每次設定播放資源時插入 -------------------------------
VideoBean videoBean = new VideoBean();
videoBean.setPath(info.getDataUrl());
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA);
videoBean.setLast_play_time(format.format(System.currentTimeMillis()));
VideoDao.newInstance().insert(videoBean);
注意點選前後的播放量數字
2.播放進度的記錄
核心在於暫停時儲存進度,在恰當的時機進行 seekTo 和介面資料回顯及渲染
使用MVP來解耦很方便,Presenter中獲取資料庫進度,順便seekTo,
再將進度資料設定給Model,呼叫View的render() 方法進行渲染
---->[VideoView#pause]------------------------------
@Override
public void pause() {
saveProgress();//儲存進度
if (canPlay() && mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
}
}
private void saveProgress() {
int per = (int) (getCurrentPosition() * 1.f / getDuration() * 100);
VideoDao.newInstance().saveProgress(mUri.getPath(), per);
}
---->[VideoDao#saveProgress]------------------------------
/**
* 儲存播放進度
*/
public void saveProgress(String path, int per) {
if (contains(path)) {
mHelper.getWritableDatabase().execSQL(
"UPDATE video_player SET current_pos=? WHERE path =?",
new String[]{per + "", path});
}
}
---->[VideoDao#getProgress]------------------------------
/**
* 根據路徑獲取播放進度
*
* @param path 影片路徑
* @return 播放進度
*/
public int getProgress(String path) {
int result = 0;
Cursor cursor = mHelper.getReadableDatabase().
rawQuery("SELECT current_pos FROM video_player WHERE path=?", new String[]{path});
if (cursor.moveToNext()) {
result = cursor.getInt(cursor.getColumnIndex("current_pos"));
}
cursor.close();
return result;
}
3.最近播放的n條記錄
/**
* 獲取最近播放的記錄
*
* @param count 條數
* @return 最近播放的count條記錄
*/
public String[] getRecent(int count) {
String[] strings = new String[count];
Cursor cursor = mHelper.getReadableDatabase().
rawQuery("SELECT path FROM video_player ORDER BY last_play_time DESC LIMIT ?",
new String[]{count + ""});
int i = 0;
while (cursor.moveToNext()) {
String path = cursor.getString(cursor.getColumnIndex("path"));
strings[i] = path;
i++;
}
cursor.close();
return strings;
}
|--- 使用 ---------------------------------
VideoDao.newInstance().getRecent(5);
4.獲取播放最多的n條
/**
* 獲取播放最多的n條記錄
*
* @param count 條數
* @return 獲取播放最多的n條記錄
*/
public String[] getMost(int count) {
String[] strings = new String[count];
Cursor cursor = mHelper.getReadableDatabase().
rawQuery("SELECT path FROM video_player ORDER BY play_count DESC LIMIT ?",
new String[]{count + ""});
int i = 0;
while (cursor.moveToNext()) {
String path = cursor.getString(cursor.getColumnIndex("path"));
strings[i] = path;
i++;
}
cursor.close();
return strings;
}
小插曲:很詭異的一件事,我檢視將這兩個方法封裝成一個
|--- 一開始我是這樣的 ---------------------
/**
* 獲取最近播放的記錄
*
* @param count 條數
* @return 最近播放的count條記錄
*/
public String[] getLimit(String by, int count) {
String[] strings = new String[count];
Cursor cursor = mHelper.getReadableDatabase().
rawQuery("SELECT path FROM video_player ORDER BY ? DESC LIMIT ?",
new String[]{by,count + ""});
int i = 0;
while (cursor.moveToNext()) {
String path = cursor.getString(cursor.getColumnIndex("path"));
strings[i] = path;
i++;
}
cursor.close();
return strings;
}
|--- 然後怎麼都搞不出想要的結果,鬱悶... 這裡說一下,問號只能用來傳值,其他的可以拼接字串
/**
* 獲取最近播放的記錄
*
* @param count 條數
* @return 最近播放的count條記錄
*/
public String[] getLimit(String by, int count) {
String[] strings = new String[count];
Cursor cursor = mHelper.getReadableDatabase().
rawQuery("SELECT path FROM video_player ORDER BY " + by + " DESC LIMIT ?",
new String[]{count + ""});
int i = 0;
while (cursor.moveToNext()) {
String path = cursor.getString(cursor.getColumnIndex("path"));
strings[i] = path;
i++;
}
cursor.close();
return strings;
}
/**
* 獲取播放最多的n條記錄
*
* @param count 條數
* @return 獲取播放最多的n條記錄
*/
public String[] getMost(int count) {
return getLimit("play_count", 3);
}
/**
* 獲取最近播放的記錄
*
* @param count 條數
* @return 最近播放的count條記錄
*/
public String[] getRecent(int count) {
return getLimit("last_play_time", count);
}
想增加其他的記錄,可以自己擴充套件。Over 本篇記錄 就這樣。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4301/viewspace-2824508/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [- Video篇 -]:記一次Handler的使用IDE
- 記一次uniapp video元件影片無法播放問題APPIDE元件
- 記一次beforeRouteEnter的使用
- Sqlite學習筆記之Sqlite歷史SQLite筆記
- 記一次面試後的經歷,求解篇面試
- 教你使用SQLite VacuumSQLite
- 記一次使用Oauth的情況OAuth
- 記一次使用 SelectMany 的經歷
- Swift之SQLite的基礎使用SwiftSQLite
- 記錄一次 Arthas 使用
- Android SQLite學習筆記AndroidSQLite筆記
- 記一次觀察者模式的使用模式
- SQLite 之 INSERT OR REPLACE使用SQLite
- SQLite中的SELECT子句使用表示式SQLite
- SQLite中的SELECT子句使用別名SQLite
- Android 原生 SQLite 資料庫的一次封裝實踐AndroidSQLite資料庫封裝
- Movavi Video Suite 使用教程|如何燒錄DVD ?使用Movavi Video Suite!IDEUI
- 記一次元件化開發中使用ButterKnife的使用元件化
- SQLite 命令列客戶端 sqlite3 使用指南SQLite命令列客戶端
- .NET 8 Video教程介紹(開篇)IDE
- 記一次 Homestead 中使用 norge
- SQLite語句學習筆記SQLite筆記
- SQLite中的SELECT子句使用萬用字元SQLite字元
- SQLite 基本命令使用方式SQLite
- 教你使用SQLite 子查詢SQLite
- ubuntu上使用sqlite3UbuntuSQLite
- 記一次使用windbg排查記憶體洩漏的過程記憶體
- 記一次控制器中介軟體的使用
- 記一次在 Laradock 中使用 beanstalkd 的經歷Bean
- 記一次 Mysql 日期使用不當造成的 bugMySql
- 記一次 Ant Design Menu元件的使用與深入元件
- 記一次HttpClient使用問題分析HTTPclient
- 記一次 Laravel 使用 Redis 踩得坑LaravelRedis
- 你會使用SQLite-Unions嗎?SQLite
- 教你使用SQLite-insert語句SQLite
- QT5中如何使用SQLiteQTSQLite
- Android 中使用 SQLite 資料庫AndroidSQLite資料庫
- 記一次Orika使用不當導致的記憶體溢位記憶體溢位