Finally got around to adding the song downloading functionality

This commit is contained in:
kdeng00
2020-01-06 22:13:52 -05:00
parent 2fce9e7e19
commit 1fa7df4aa2
7 changed files with 87 additions and 41 deletions
-7
View File
@@ -11,15 +11,8 @@ cmake_minimum_required(VERSION 3.10)
# Gradle automatically packages shared libraries with your APK. # Gradle automatically packages shared libraries with your APK.
# set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
# set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=c++17")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -g -O0 -std=c++17")
# set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -std=c++17 -DNDEBUG")
set (HEADERS set (HEADERS
Demo.hpp Demo.hpp
+27 -1
View File
@@ -6,6 +6,7 @@
#define MEAR_DEMO_H #define MEAR_DEMO_H
#include <iostream> #include <iostream>
#include <algorithm>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <cstring> #include <cstring>
@@ -402,8 +403,34 @@ Java_com_example_mear_repositories_TrackRepository_retrieveSongsIncludingDownloa
auto allSongs = retrieveSongs(tk, uri); auto allSongs = retrieveSongs(tk, uri);
jobjectArray songs = env->NewObjectArray(allSongs.size(), songClass, nullptr); jobjectArray songs = env->NewObjectArray(allSongs.size(), songClass, nullptr);
auto i = 0; auto i = 0;
repository::local::SongRepository localSongRepo(appPath);
auto localSongs = (localSongRepo.isTableEmpty(appPath)) ?
localSongRepo.retrieveAllSongs(appPath) : std::vector<model::Song>();
for (auto& sng: allSongs) { for (auto& sng: allSongs) {
try { try {
if (localSongs.size() > 0) {
auto result = std::any_of(localSongs.begin(), localSongs.end(),
[&](model::Song s) {
auto result = s.artist.compare(sng.artist) == 0 &&
s.title.compare(sng.title) == 0 &&
s.album.compare(sng.album) == 0 &&
s.albumArtist.compare(sng.albumArtist) == 0;
if (result) {
auto song = songToObj<model::Song>(env, s);
env->SetObjectArrayElement(songs, i++, song);
}
return result;
});
if (result) {
continue;
}
}
auto song = songToObj<model::Song>(env, sng); auto song = songToObj<model::Song>(env, sng);
env->SetObjectArrayElement(songs, i++, song); env->SetObjectArrayElement(songs, i++, song);
} catch (std::exception& ex) { } catch (std::exception& ex) {
@@ -750,7 +777,6 @@ Java_com_example_mear_repositories_TrackRepository_downloadSong(
jobject songObj, jobject songObj,
jstring pathStr jstring pathStr
) { ) {
// TODO: left off here
auto tokenClass = env->GetObjectClass(tokenObj); auto tokenClass = env->GetObjectClass(tokenObj);
auto accessTokenId = env->GetFieldID(tokenClass, "accessToken", "Ljava/lang/String;"); auto accessTokenId = env->GetFieldID(tokenClass, "accessToken", "Ljava/lang/String;");
auto accessTokenVal = (jstring) env->GetObjectField(tokenObj, accessTokenId); auto accessTokenVal = (jstring) env->GetObjectField(tokenObj, accessTokenId);
@@ -52,6 +52,7 @@ namespace repository { namespace local {
queryStr.append(m_tableName); queryStr.append(m_tableName);
SQLite::Statement query(db, queryStr); SQLite::Statement query(db, queryStr);
auto r = query.exec();
const auto result = query.hasRow(); const auto result = query.hasRow();
+11 -1
View File
@@ -183,11 +183,21 @@ namespace repository {
m_tableName = songTable(); m_tableName = songTable();
} }
template<typename Str = std::string>
SongRepository(const Str& val) {
m_tableName = songTable();
if (!databaseExist(val)) {
initializedDatabase(val);
}
if (!doesTableExist(val)) {
createSongTable(val);
}
}
std::vector<Song> retrieveAllSongs(const std::string& appPath) { std::vector<Song> retrieveAllSongs(const std::string& appPath) {
std::vector<Song> downloadedSongs; std::vector<Song> downloadedSongs;
try { try {
// TODO: left off here
const auto dbPath = pathOfDatabase(appPath); const auto dbPath = pathOfDatabase(appPath);
SQLite::Database db(dbPath, SQLite::OPEN_READONLY); SQLite::Database db(dbPath, SQLite::OPEN_READONLY);
@@ -4,7 +4,6 @@ import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.SearchView import android.support.v7.widget.SearchView
import kotlinx.android.synthetic.main.activity_icarus_song.*
import kotlinx.android.synthetic.main.content_song_view.* import kotlinx.android.synthetic.main.content_song_view.*
import com.example.mear.adapters.SongAdapter import com.example.mear.adapters.SongAdapter
@@ -58,7 +57,7 @@ class IcarusSongActivity : BaseServiceActivity() {
val apiRepo = APIRepository() val apiRepo = APIRepository()
val token = tokenRepo.retrieveToken(pa) val token = tokenRepo.retrieveToken(pa)
val apiInfo = apiRepo.retrieveRecord(pa) val apiInfo = apiRepo.retrieveRecord(pa)
val fetchedSongs = trackRepo.fetchSongs(token, apiInfo.uri).toCollection(ArrayList()) val fetchedSongs = trackRepo.fetchSongsIncludingDownloaded(token, apiInfo.uri, pa).toCollection(ArrayList())
songs = fetchedSongs songs = fetchedSongs
songs!!.sortedWith(compareBy{it.title}) songs!!.sortedWith(compareBy{it.title})
@@ -1,26 +1,17 @@
package com.example.mear.adapters package com.example.mear.adapters
import android.app.Activity import java.lang.Exception
import kotlinx.android.synthetic.main.fragment_song_view.view.*
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Filter import android.widget.Filter
import android.widget.Filterable import android.widget.Filterable
import java.lang.Exception
import kotlinx.android.synthetic.main.fragment_song_view.view.*
import kotlinx.coroutines.GlobalScope
import com.squareup.picasso.Picasso
import com.example.mear.constants.Filenames
import com.example.mear.inflate import com.example.mear.inflate
import com.example.mear.models.Song import com.example.mear.models.Song
import com.example.mear.models.TrackItems
import com.example.mear.R import com.example.mear.R
import com.example.mear.util.ConvertByteArray
import com.example.mear.util.ExtractCover
import org.jetbrains.anko.imageBitmap
class SongAdapter(val mOnClickListener: (Song) -> Unit, class SongAdapter(val mOnClickListener: (Song) -> Unit,
@@ -21,19 +21,11 @@ import com.example.mear.repositories.ShuffleRepository.ShuffleTypes
class MusicService(var appPath: String = ""): Service() { class MusicService(var appPath: String = ""): Service() {
companion object {
//fun curSongIndex(): Int = currentSongIndex
}
private var trackPlayer: MediaPlayer? = null private var trackPlayer: MediaPlayer? = null
//private var trackMgr: TrackManager? = null
private var songQueue = mutableListOf<Song>() private var songQueue = mutableListOf<Song>()
//private var currentTrack = Track()
private var currentSong = Song() private var currentSong = Song()
private var currentSongIndex: Int? = null private var currentSongIndex: Int? = null
//private var addingMusic: Boolean? = false
private var shuffleOn: Boolean? = null private var shuffleOn: Boolean? = null
//private var repeatOn: Boolean? = null
private val mBinder = LocalBinder() private val mBinder = LocalBinder()
private val seconds = Interval.SONG_REWIND private val seconds = Interval.SONG_REWIND
@@ -77,6 +69,11 @@ class MusicService(var appPath: String = ""): Service() {
fun icarusPlaySong(token: Token, song: Song, apiInfo: APIInfo) { fun icarusPlaySong(token: Token, song: Song, apiInfo: APIInfo) {
if (song.downloaded) {
offlinePlaySong(song)
return
}
val uri = APIRepository.retrieveSongStreamUri(apiInfo, song) val uri = APIRepository.retrieveSongStreamUri(apiInfo, song)
val hddr = APIRepository.retrieveSongStreamHeader(token) val hddr = APIRepository.retrieveSongStreamHeader(token)
currentSong = song currentSong = song
@@ -142,11 +139,16 @@ class MusicService(var appPath: String = ""): Service() {
} }
currentSong = songQueue[currentSongIndex!!] currentSong = songQueue[currentSongIndex!!]
trackPlayer!!.reset()
if (currentSong.downloaded) {
trackPlayer!!.setDataSource(currentSong.path)
}
else {
val uri = APIRepository.retrieveSongStreamUri(apiInfo, currentSong) val uri = APIRepository.retrieveSongStreamUri(apiInfo, currentSong)
val hddr = APIRepository.retrieveSongStreamHeader(token) val hddr = APIRepository.retrieveSongStreamHeader(token)
trackPlayer!!.reset()
trackPlayer!!.setDataSource(this, trackPlayer!!.setDataSource(this,
uri, hddr) uri, hddr)
}
trackPlayer!!.prepare() trackPlayer!!.prepare()
trackPlayer!!.start() trackPlayer!!.start()
@@ -181,9 +183,14 @@ class MusicService(var appPath: String = ""): Service() {
currentSong = songQueue[currentSongIndex!!] currentSong = songQueue[currentSongIndex!!]
if (currentSong.downloaded) {
trackPlayer!!.setDataSource(currentSong.path)
}
else {
trackPlayer!!.setDataSource(this, trackPlayer!!.setDataSource(this,
APIRepository.retrieveSongStreamUri(apiInfo, currentSong), APIRepository.retrieveSongStreamUri(apiInfo, currentSong),
APIRepository.retrieveSongStreamHeader(token)) APIRepository.retrieveSongStreamHeader(token))
}
trackPlayer!!.prepare() trackPlayer!!.prepare()
trackPlayer!!.start() trackPlayer!!.start()
} }
@@ -228,9 +235,15 @@ class MusicService(var appPath: String = ""): Service() {
} }
currentSong = songQueue[currentSongIndex!!] currentSong = songQueue[currentSongIndex!!]
if (currentSong.downloaded) {
trackPlayer!!.setDataSource(currentSong.path)
}
else {
trackPlayer!!.setDataSource(this, trackPlayer!!.setDataSource(this,
APIRepository.retrieveSongStreamUri(apiInfo, currentSong), APIRepository.retrieveSongStreamUri(apiInfo, currentSong),
APIRepository.retrieveSongStreamHeader(token)) APIRepository.retrieveSongStreamHeader(token))
}
trackPlayer!!.prepareAsync() trackPlayer!!.prepareAsync()
trackPlayer!!.setOnCompletionListener { trackPlayer!!.setOnCompletionListener {
playNextTrack() playNextTrack()
@@ -264,4 +277,17 @@ class MusicService(var appPath: String = ""): Service() {
return repeatOn!! return repeatOn!!
} }
private fun offlinePlaySong(song: Song) {
try {
trackPlayer!!.reset()
trackPlayer!!.setDataSource(song.path)
trackPlayer!!.prepare()
trackPlayer!!.start()
} }
catch (ex: Exception) {
var msg = ex.message
}
}
}