Finally got around to adding the song downloading functionality
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user