Implemented download service

This commit is contained in:
CappielloAntonio 2021-07-29 17:12:55 +02:00
parent f09d3b774d
commit 0e41cc20bd
9 changed files with 332 additions and 10 deletions

View file

@ -6,13 +6,15 @@ import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import com.cappielloantonio.play.database.dao.DownloadDao;
import com.cappielloantonio.play.database.dao.QueueDao;
import com.cappielloantonio.play.database.dao.RecentSearchDao;
import com.cappielloantonio.play.model.Download;
import com.cappielloantonio.play.model.Queue;
import com.cappielloantonio.play.model.RecentSearch;
import com.cappielloantonio.play.model.Song;
@Database(entities = {Queue.class, RecentSearch.class}, version = 3, exportSchema = false)
@Database(entities = {Queue.class, RecentSearch.class, Download.class}, version = 5, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
private static final String TAG = "AppDatabase";
@ -31,4 +33,6 @@ public abstract class AppDatabase extends RoomDatabase {
public abstract QueueDao queueDao();
public abstract RecentSearchDao recentSearchDao();
public abstract DownloadDao downloadDao();
}

View file

@ -0,0 +1,32 @@
package com.cappielloantonio.play.database.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import com.cappielloantonio.play.model.Download;
import java.util.List;
@Dao
public interface DownloadDao {
@Query("SELECT * FROM download")
LiveData<List<Download>> getAll();
@Query("SELECT * FROM download LIMIT :size")
LiveData<List<Download>> getSample(int size);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Download download);
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAll(List<Download> downloads);
@Query("DELETE FROM download WHERE id = :id")
void delete(String id);
@Query("DELETE FROM download")
void deleteAll();
}

View file

@ -0,0 +1,121 @@
package com.cappielloantonio.play.model;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "download")
public class Download {
@NonNull
@PrimaryKey
@ColumnInfo(name = "id")
private String songID;
@ColumnInfo(name = "title")
private String title;
@ColumnInfo(name = "albumId")
private String albumId;
@ColumnInfo(name = "albumName")
private String albumName;
@ColumnInfo(name = "artistId")
private String artistId;
@ColumnInfo(name = "artistName")
private String artistName;
@ColumnInfo(name = "primary")
private String primary;
@ColumnInfo(name = "duration")
private long duration;
public Download(String songID, String title, String albumId, String albumName, String artistId, String artistName, String primary, long duration) {
this.songID = songID;
this.title = title;
this.albumId = albumId;
this.albumName = albumName;
this.artistId = artistId;
this.artistName = artistName;
this.primary = primary;
this.duration = duration;
}
public Download(Song song) {
this.songID = song.getId();
this.title = song.getTitle();
this.albumId = song.getAlbumId();
this.albumName = song.getAlbumName();
this.artistId = song.getArtistId();
this.artistName = song.getArtistName();
this.primary = song.getPrimary();
this.duration = song.getDuration();
}
public String getSongID() {
return songID;
}
public void setSongID(String songID) {
this.songID = songID;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAlbumId() {
return albumId;
}
public void setAlbumId(String albumId) {
this.albumId = albumId;
}
public String getAlbumName() {
return albumName;
}
public void setAlbumName(String albumName) {
this.albumName = albumName;
}
public String getArtistId() {
return artistId;
}
public void setArtistId(String artistId) {
this.artistId = artistId;
}
public String getArtistName() {
return artistName;
}
public void setArtistName(String artistName) {
this.artistName = artistName;
}
public String getPrimary() {
return primary;
}
public void setPrimary(String primary) {
this.primary = primary;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
}

View file

@ -89,6 +89,17 @@ public class Song implements Parcelable {
this.duration = queue.getDuration();
}
public Song(Download download) {
this.id = download.getSongID();
this.title = download.getTitle();
this.albumId = download.getAlbumId();
this.albumName = download.getAlbumName();
this.artistId = download.getArtistId();
this.artistName = download.getArtistName();
this.primary = download.getPrimary();
this.duration = download.getDuration();
}
public String getId() {
return id;
}

View file

@ -0,0 +1,122 @@
package com.cappielloantonio.play.repository;
import android.app.Application;
import androidx.lifecycle.LiveData;
import com.cappielloantonio.play.database.AppDatabase;
import com.cappielloantonio.play.database.dao.DownloadDao;
import com.cappielloantonio.play.database.dao.QueueDao;
import com.cappielloantonio.play.model.Download;
import com.cappielloantonio.play.model.Queue;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.util.MappingUtil;
import com.cappielloantonio.play.util.QueueUtil;
import java.util.ArrayList;
import java.util.List;
public class DownloadRepository {
private static final String TAG = "QueueRepository";
private DownloadDao downloadDao;
private LiveData<List<Download>> listLiveDownload;
private LiveData<List<Download>> listLiveDownloadSample;
public DownloadRepository(Application application) {
AppDatabase database = AppDatabase.getInstance(application);
downloadDao = database.downloadDao();
}
public LiveData<List<Download>> getLiveDownload() {
listLiveDownload = downloadDao.getAll();
return listLiveDownload;
}
public LiveData<List<Download>> getLiveDownloadSample(int size) {
listLiveDownloadSample = downloadDao.getSample(size);
return listLiveDownloadSample;
}
public void insert(Download download) {
InsertThreadSafe insert = new InsertThreadSafe(downloadDao, download);
Thread thread = new Thread(insert);
thread.start();
}
private static class InsertThreadSafe implements Runnable {
private DownloadDao downloadDao;
private Download download;
public InsertThreadSafe(DownloadDao downloadDao, Download download) {
this.downloadDao = downloadDao;
this.download = download;
}
@Override
public void run() {
downloadDao.insert(download);
}
}
public void insertAll(List<Download> downloads) {
InsertAllThreadSafe insertAll = new InsertAllThreadSafe(downloadDao, downloads);
Thread thread = new Thread(insertAll);
thread.start();
}
private static class InsertAllThreadSafe implements Runnable {
private DownloadDao downloadDao;
private List<Download> downloads;
public InsertAllThreadSafe(DownloadDao downloadDao, List<Download> downloads) {
this.downloadDao = downloadDao;
this.downloads = downloads;
}
@Override
public void run() {
downloadDao.insertAll(downloads);
}
}
public void deleteAll() {
DeleteAllThreadSafe deleteAll = new DeleteAllThreadSafe(downloadDao);
Thread thread = new Thread(deleteAll);
thread.start();
}
private static class DeleteAllThreadSafe implements Runnable {
private DownloadDao downloadDao;
public DeleteAllThreadSafe(DownloadDao downloadDao) {
this.downloadDao = downloadDao;
}
@Override
public void run() {
downloadDao.deleteAll();
}
}
public void delete(Download download) {
DeleteThreadSafe delete = new DeleteThreadSafe(downloadDao, download);
Thread thread = new Thread(delete);
thread.start();
}
private static class DeleteThreadSafe implements Runnable {
private DownloadDao downloadDao;
private Download download;
public DeleteThreadSafe(DownloadDao downloadDao, Download download) {
this.downloadDao = downloadDao;
this.download = download;
}
@Override
public void run() {
downloadDao.delete(download.getSongID());
}
}
}

View file

@ -8,7 +8,9 @@ import androidx.annotation.Nullable;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.DownloadRepository;
import com.cappielloantonio.play.repository.SongRepository;
import com.cappielloantonio.play.util.MappingUtil;
import com.cappielloantonio.play.util.MusicUtil;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.offline.Download;
@ -71,7 +73,7 @@ public class DownloadTracker {
}
public void toggleDownload(List<Song> songs) {
SongRepository songRepository = new SongRepository(App.getInstance());
DownloadRepository downloadRepository = new DownloadRepository(App.getInstance());
for (Song song : songs) {
MediaItem mediaItem = MusicUtil.getMediaItemFromSong(song);
@ -81,12 +83,12 @@ public class DownloadTracker {
if (download != null && download.state != Download.STATE_FAILED) {
song.setOffline(false);
DownloadService.sendRemoveDownload(context, DownloaderService.class, download.request.id, false);
downloadRepository.delete(MappingUtil.mapToDownload(song));
} else {
song.setOffline(true);
DownloadService.sendAddDownload(context, DownloaderService.class, getDownloadRequest(song.getId(), mediaItem.playbackProperties.uri), false);
downloadRepository.insert(MappingUtil.mapToDownload(song));
}
// songRepository.setOfflineStatus(song);
}
}

View file

@ -28,6 +28,7 @@ import com.cappielloantonio.play.databinding.FragmentHomeBinding;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.MappingUtil;
import com.cappielloantonio.play.util.UIUtil;
import com.cappielloantonio.play.viewmodel.HomeViewModel;
@ -254,9 +255,9 @@ public class HomeFragment extends Fragment {
dowanloadedMusicAdapter = new RecentMusicAdapter(activity, requireContext(), getChildFragmentManager());
bind.downloadedTracksRecyclerView.setAdapter(dowanloadedMusicAdapter);
homeViewModel.getDownloaded().observe(requireActivity(), songs -> {
if(bind != null) bind.homeDownloadedTracksSector.setVisibility(!songs.isEmpty() ? View.VISIBLE : View.GONE);
dowanloadedMusicAdapter.setItems(songs);
homeViewModel.getDownloaded().observe(requireActivity(), downloads -> {
if(bind != null) bind.homeDownloadedTracksSector.setVisibility(!downloads.isEmpty() ? View.VISIBLE : View.GONE);
dowanloadedMusicAdapter.setItems(MappingUtil.mapDownload(downloads));
});
}

View file

@ -2,6 +2,7 @@ package com.cappielloantonio.play.util;
import com.cappielloantonio.play.model.Album;
import com.cappielloantonio.play.model.Artist;
import com.cappielloantonio.play.model.Download;
import com.cappielloantonio.play.model.Playlist;
import com.cappielloantonio.play.model.Queue;
import com.cappielloantonio.play.model.Song;
@ -68,4 +69,28 @@ public class MappingUtil {
return playlist;
}
public static ArrayList<Song> mapDownload(List<Download> downloads) {
ArrayList<Song> songs = new ArrayList();
for(Download download : downloads){
songs.add(new Song(download));
}
return songs;
}
public static ArrayList<Download> mapToDownload(List<Song> songs) {
ArrayList<Download> downloads = new ArrayList();
for(Song song : songs){
downloads.add(new Download(song));
}
return downloads;
}
public static Download mapToDownload(Song song) {
return new Download(song);
}
}

View file

@ -10,9 +10,11 @@ import androidx.lifecycle.MutableLiveData;
import com.cappielloantonio.play.interfaces.MediaCallback;
import com.cappielloantonio.play.model.Album;
import com.cappielloantonio.play.model.Artist;
import com.cappielloantonio.play.model.Download;
import com.cappielloantonio.play.model.Song;
import com.cappielloantonio.play.repository.AlbumRepository;
import com.cappielloantonio.play.repository.ArtistRepository;
import com.cappielloantonio.play.repository.DownloadRepository;
import com.cappielloantonio.play.repository.SongRepository;
import java.util.ArrayList;
@ -23,8 +25,9 @@ public class HomeViewModel extends AndroidViewModel {
private SongRepository songRepository;
private AlbumRepository albumRepository;
private ArtistRepository artistRepository;
private DownloadRepository downloadRepository;
private LiveData<List<Song>> downloadedSongSample;
private LiveData<List<Download>> downloadedSongSample;
private List<Integer> years;
private MutableLiveData<List<Song>> dicoverSongSample;
@ -42,6 +45,7 @@ public class HomeViewModel extends AndroidViewModel {
songRepository = new SongRepository(application);
albumRepository = new AlbumRepository(application);
artistRepository = new ArtistRepository(application);
downloadRepository = new DownloadRepository(application);
// favoritesSongSample = songRepository.getListLiveFavoritesSampleSong(20);
// downloadedSongSample = songRepository.getListLiveDownloadedSampleSong(20);
@ -49,7 +53,7 @@ public class HomeViewModel extends AndroidViewModel {
setDicoverSongSample();
dicoverSongSample = new MutableLiveData<>();
downloadedSongSample = new MutableLiveData<>();
downloadedSongSample = downloadRepository.getLiveDownloadSample(10);
years = new ArrayList<>();
mostPlayedAlbumSample = albumRepository.getAlbums("frequent", 20);
@ -85,7 +89,7 @@ public class HomeViewModel extends AndroidViewModel {
return starredArtists;
}
public LiveData<List<Song>> getDownloaded() {
public LiveData<List<Download>> getDownloaded() {
return downloadedSongSample;
}