做网站主要学什么,比较好的高端网站制作公司,如何制作自己的网址教学视频,做网站找 汇搜网络Music统计功能需求 1.记录歌曲名称与次数(歌曲播放结束算一次)#xff0c;根据播放次数制作一个排行列表;#xff08;开始说要记录歌手#xff0c;后面debug发现这个字段没有#xff0c;暂时不记录#xff09; 2.记录播放歌曲的时长#xff0c;时间累加#xff1b;…Music统计功能需求 1.记录歌曲名称与次数(歌曲播放结束算一次)根据播放次数制作一个排行列表;开始说要记录歌手后面debug发现这个字段没有暂时不记录 2.记录播放歌曲的时长时间累加经沟通需要细分成每一个月的播放时长另外再加一个首次使用的记录 前几天需要实现这功能昨天实现了今天验证Ok来谈谈我的做法先上图暂时版: 上面是一个简单的例子具体UI后期需要给图再做调整目前结构上面是一个通用的带返回键的titlebar下面recyclerview加文本做数据展示方便测试看数据当然我都是用sqlite expert去查看数据 这里需要注意的是当我们从设备导出数据库的时候需要把.db和.db-shm和.db-wal都要导出不然可能没有表和数据. 1.首先创建音乐播放数据库
package com.hiby.music.musicinfofetchermaster.db;import static com.hiby.music.musicinfofetchermaster.db.MusicRecordDao.COLUMN_PLAY_COUNT;
import static com.hiby.music.musicinfofetchermaster.db.MusicRecordDao.KEY_DB_TAB;import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;public class MusicRecordOpenHelper extends SQLiteOpenHelper {private volatile static MusicRecordOpenHelper instances null;public static final String DB_NAME music_record.db;public static final int DB_VERSION 1;public static MusicRecordOpenHelper getInstances(Context context) {if (instances null) {synchronized (MusicRecordOpenHelper.class) {if (instances null) {instances new MusicRecordOpenHelper(context.getApplicationContext());}}}return instances;}public MusicRecordOpenHelper(Context context) {super(context, DB_NAME, null, DB_VERSION);}Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(MusicRecordDao.CREATE_TABLE_SONGS);}Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL(DROP TABLE IF EXISTS KEY_DB_TAB);onCreate(db);}public void insertOrUpdateSong(String name, String author) {SQLiteDatabase db instances.getWritableDatabase();// 查询数据库中是否已经存在相同的歌曲String selection MusicRecordDao.COLUMN_NAME ? AND MusicRecordDao.COLUMN_AUTHOR ?;String[] selectionArgs {name, author};Cursor cursor db.query(KEY_DB_TAB,new String[]{COLUMN_PLAY_COUNT},selection,selectionArgs,null,null,null);if (cursor.moveToFirst()) {// 歌曲已存在更新播放次数int playCount cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_PLAY_COUNT));playCount; // 增加播放次数ContentValues values new ContentValues();values.put(COLUMN_PLAY_COUNT, playCount);db.update(KEY_DB_TAB, values, selection, selectionArgs);} else {// 歌曲不存在插入新记录ContentValues values new ContentValues();values.put(MusicRecordDao.COLUMN_NAME, name);values.put(MusicRecordDao.COLUMN_AUTHOR, author);values.put(COLUMN_PLAY_COUNT, 1); // 初始播放次数为1因为这是第一次插入db.insert(KEY_DB_TAB, null, values);}cursor.close();db.close();}// 插入新歌曲public void insertSong(String name, String author) {SQLiteDatabase db instances.getWritableDatabase();ContentValues values new ContentValues();values.put(MusicRecordDao.COLUMN_NAME, name);values.put(MusicRecordDao.COLUMN_AUTHOR, author);values.put(COLUMN_PLAY_COUNT, 0); // 初始播放次数为0db.insert(KEY_DB_TAB, null, values);db.close();}// 更新播放次数public void incrementPlayCount(String name, String author) {SQLiteDatabase db instances.getWritableDatabase();String selection MusicRecordDao.COLUMN_NAME ? AND MusicRecordDao.COLUMN_AUTHOR ?;String[] selectionArgs {name, author};Cursor cursor db.query(MusicRecordDao.KEY_DB_TAB, new String[]{COLUMN_PLAY_COUNT},selection, selectionArgs, null, null, null);if (cursor ! null cursor.moveToFirst()) {int playCount cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_PLAY_COUNT));playCount;ContentValues values new ContentValues();values.put(COLUMN_PLAY_COUNT, playCount);db.update(MusicRecordDao.KEY_DB_TAB, values, selection, selectionArgs);}if (cursor ! null) {cursor.close();}db.close();}// 获取按播放次数排序的音乐记录public Cursor getMusicSortedByPlayCount() {SQLiteDatabase db this.getReadableDatabase();return db.query(KEY_DB_TAB, null, null, null, null, null, COLUMN_PLAY_COUNT DESC);}
}
这里我直接把对数据进行插入的逻辑和查询写在里面了下面是建表放在Dao里 public class MusicRecordDao {public static final String KEY_DB_TAB music_record;public static final String COLUMN_ID id;public static final String COLUMN_NAME name;public static final String COLUMN_AUTHOR author;public static final String COLUMN_PLAY_COUNT play_count;public static final String CREATE_TABLE_SONGS CREATE TABLE KEY_DB_TAB ( COLUMN_ID INTEGER PRIMARY KEY AUTOINCREMENT, COLUMN_NAME TEXT NOT NULL, COLUMN_AUTHOR TEXT NOT NULL, COLUMN_PLAY_COUNT INTEGER DEFAULT 0);public static final String CLEAN_MUSIC_TAB DELETE FROM KEY_DB_TAB;}2.根据音乐播放生命周期的onAudioComplete中进行数据库的保存 Overridepublic void onAudioComplete(IPlayer player, AudioInfo audio) {saveMusicRecord(audio);LogPlus.d(###onAudioComplete###);}...private static void saveMusicRecord(AudioInfo audio) {ThreadPoolExecutor.execute(() - {SmartPlayerApplication.getMusicRecordOpenHelper().getWritableDatabase();String displayName audio.displayName();SmartPlayerApplication.getMusicRecordOpenHelper().insertOrUpdateSong(displayName, );});}上面就实现了音乐播放文件名和播放次数的更新插入 3.在具体页面进行查询 private List getDataFromDb() {ListMusicRankModel list new ArrayList();MusicRecordOpenHelper musicRecordOpenHelper SmartPlayerApplication.getMusicRecordOpenHelper();musicRecordOpenHelper.getReadableDatabase();Cursor cursor musicRecordOpenHelper.getMusicSortedByPlayCount();if (cursor ! null cursor.moveToFirst()) {do {SuppressLint(Range) String name cursor.getString(cursor.getColumnIndex(MusicRecordDao.COLUMN_NAME));SuppressLint(Range) int playCount cursor.getInt(cursor.getColumnIndex(MusicRecordDao.COLUMN_PLAY_COUNT));list.add(new MusicRankModel(name, playCount));} while (cursor.moveToNext());cursor.close();}if (list.size() 100) {list list.subList(0, 100);}return list;}上面是经典的数据库写法限制100个数量 4.下面是UI层的展示 private void initData() {recyclerView findViewById(R.id.rv_rank_list);recyclerView.setLayoutManager(new LinearLayoutManager(this));//从数据库获取musicList getDataFromDb();//musicList generateMusicList();adapter new MusicRankAdapter(musicList);recyclerView.setAdapter(adapter);}Adapter层做了TYPE_HEADER和TYPE_ITEM的处理 public class MusicRankAdapter extends RecyclerView.AdapterRecyclerView.ViewHolder {private ListMusicRankModel musicList;private static final int VIEW_TYPE_HEADER 0;private static final int VIEW_TYPE_ITEM 1;public static class MusicViewHolder extends RecyclerView.ViewHolder {public TextView musicName;public TextView playCount;public MusicViewHolder(NonNull View itemView) {super(itemView);musicName itemView.findViewById(R.id.musicName);playCount itemView.findViewById(R.id.playCount);}}public static class HeaderViewHolder extends RecyclerView.ViewHolder {public HeaderViewHolder(NonNull View itemView) {super(itemView);}}public MusicRankAdapter(ListMusicRankModel musicList) {this.musicList musicList;}NonNullOverridepublic RecyclerView.ViewHolder onCreateViewHolder(NonNull ViewGroup parent, int viewType) {if (viewType VIEW_TYPE_HEADER) {View headerView LayoutInflater.from(parent.getContext()).inflate(R.layout.item_music_header, parent, false);return new HeaderViewHolder(headerView);} else {View itemView LayoutInflater.from(parent.getContext()).inflate(R.layout.item_music, parent, false);return new MusicViewHolder(itemView);}}Overridepublic void onBindViewHolder(NonNull RecyclerView.ViewHolder holder, int position) {if (holder instanceof MusicViewHolder) {MusicRankModel currentMusic musicList.get(position - 1); // 减1因为第一个位置是头部视图((MusicViewHolder) holder).musicName.setText(currentMusic.getName());((MusicViewHolder) holder).playCount.setText(String.valueOf(currentMusic.getPlayCount()));}}Overridepublic int getItemViewType(int position) {return position 0 ? VIEW_TYPE_HEADER : VIEW_TYPE_ITEM;}Overridepublic int getItemCount() {return musicList.size() 1; // 加1表示包括头部视图}
}具体item两个的layout: item_music_header:
?xml version1.0 encodingutf-8?
LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:orientationhorizontalandroid:padding8dpTextViewandroid:layout_width0dpandroid:layout_heightwrap_contentandroid:layout_weight2android:text歌曲名android:gravitycenterandroid:textSize16spandroid:textStylebold /TextViewandroid:layout_width0dpandroid:layout_heightwrap_contentandroid:layout_weight1android:text播放次数android:gravitycenterandroid:textSize16spandroid:textStylebold /
/LinearLayoutitem_music:
?xml version1.0 encodingutf-8?
LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:orientationhorizontalandroid:padding8dpTextViewandroid:idid/musicNameandroid:layout_width0dpandroid:layout_heightwrap_contentandroid:layout_weight2android:gravitycenterandroid:textMusic Nameandroid:textSize16sp /TextViewandroid:idid/playCountandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:textPlay Countandroid:layout_weight1android:textSize16spandroid:gravitycenterandroid:paddingStart16dp/
/LinearLayout这样就实现了上面列表的效果。下面是时间戳记录和按月记录播放时长的思路放在下一篇去讲.