Able to fetch all of the songs. Create Token repository to store tokens. Next need to transition from the login screen to the song view screen.
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.mear">
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
@@ -9,6 +12,7 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".activities.IcarusSongActivity"></activity>
|
||||
<activity
|
||||
android:name=".activities.LoginActivity"
|
||||
android:label="@string/title_activity_demo_stream"
|
||||
@@ -53,7 +57,4 @@
|
||||
<service android:name=".playback.service.MusicService" />
|
||||
</application>
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
|
||||
</manifest>
|
||||
@@ -24,11 +24,15 @@
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include "model/Song.h"
|
||||
#include "model/Token.h"
|
||||
#include "model/User.h"
|
||||
#include "SongRepository.h"
|
||||
#include "Tok.h"
|
||||
#include "UserRepository.h"
|
||||
|
||||
std::vector<model::Song> retrieveSongs(const model::Token&, const std::string&);
|
||||
|
||||
jobject songToObj(JNIEnv *env, const model::Song&);
|
||||
|
||||
model::Song retrieveSong(const std::string&, const std::string&, const int);
|
||||
|
||||
@@ -42,6 +46,50 @@ bool userCredentialExist(const std::string&);
|
||||
void saveCredentials(const model::User&, const std::string&);
|
||||
|
||||
|
||||
std::vector<model::Song> retrieveSongs(const model::Token& token, const std::string& baseUri)
|
||||
{
|
||||
std::vector<model::Song> songs;
|
||||
repository::SongRepository songRepo;
|
||||
songs = songRepo.fetchSongs(token, baseUri);
|
||||
|
||||
return songs;
|
||||
}
|
||||
|
||||
|
||||
jobject songToObj(JNIEnv *env, const model::Song& song)
|
||||
{
|
||||
jclass songClass = env->FindClass( "com/example/mear/models/Song");
|
||||
jmethodID jconstructor = env->GetMethodID( songClass, "<init>", "()V" );
|
||||
jobject songObj = env->NewObject( songClass, jconstructor );
|
||||
|
||||
jmethodID songId = env->GetMethodID( songClass, "setId", "(I)V" );
|
||||
jmethodID songTitle = env->GetMethodID( songClass, "setTitle", "(Ljava/lang/String;)V" );
|
||||
jmethodID songAlbum = env->GetMethodID( songClass, "setAlbum", "(Ljava/lang/String;)V" );
|
||||
jmethodID songArtist = env->GetMethodID( songClass, "setArtist", "(Ljava/lang/String;)V" );
|
||||
jmethodID songGenre = env->GetMethodID( songClass, "setGenre", "(Ljava/lang/String;)V" );
|
||||
jmethodID songDuration = env->GetMethodID( songClass, "setDuration", "(I)V" );
|
||||
jmethodID songYear = env->GetMethodID( songClass, "setYear", "(I)V" );
|
||||
|
||||
jint id = song.id;
|
||||
jstring title = env->NewStringUTF(song.title.c_str());
|
||||
jstring album = env->NewStringUTF(song.album.c_str());
|
||||
jstring artist = env->NewStringUTF(song.artist.c_str());
|
||||
jstring genre = env->NewStringUTF(song.genre.c_str());
|
||||
jint duration = song.duration;
|
||||
jint year = song.year;
|
||||
|
||||
env->CallVoidMethod( songObj, songId, id );
|
||||
env->CallVoidMethod(songObj, songTitle, title);
|
||||
env->CallVoidMethod(songObj, songAlbum, album);
|
||||
env->CallVoidMethod(songObj, songArtist, artist);
|
||||
env->CallVoidMethod(songObj, songGenre, genre);
|
||||
env->CallVoidMethod(songObj, songDuration, duration);
|
||||
env->CallVoidMethod(songObj, songYear, year);
|
||||
|
||||
return songObj;
|
||||
}
|
||||
|
||||
|
||||
model::Song retrieveSong(const std::string& token, const std::string& baseUri, const int songId)
|
||||
{
|
||||
repository::SongRepository songRepo;
|
||||
@@ -49,6 +97,7 @@ model::Song retrieveSong(const std::string& token, const std::string& baseUri, c
|
||||
420, 420);
|
||||
|
||||
song = songRepo.retrieveSong(token, baseUri, song);
|
||||
auto songs = songRepo.fetchSongs(model::Token(token), baseUri);
|
||||
|
||||
return song;
|
||||
}
|
||||
@@ -126,6 +175,33 @@ void saveCredentials(const model::User& user, const std::string& appDirectory)
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jobjectArray
|
||||
JNICALL
|
||||
Java_com_example_mear_activities_IcarusSongActivity_retrieveSongs(
|
||||
JNIEnv *env,
|
||||
jobject thisOnj,
|
||||
jobject token,
|
||||
jstring baseUri
|
||||
) {
|
||||
jclass songClass = env->FindClass( "com/example/mear/models/Song");
|
||||
jclass tokenClass = env->FindClass("com/example/mear/models/Token");
|
||||
jobjectArray songs = env->NewObjectArray(2, songClass, nullptr);
|
||||
auto tok = env->CallObjectMethod(token, env->GetMethodID(tokenClass, "setAccessToken", "(Ljava/lang/String;)V"));
|
||||
std::string tokStr = env->GetStringUTFChars((jstring)tok, nullptr);
|
||||
model::Token tk(tokStr);
|
||||
const std::string uri = env->GetStringUTFChars(baseUri, nullptr);
|
||||
|
||||
auto allSongs = retrieveSongs(tk, uri);
|
||||
for (auto i = 0; i != allSongs.size(); ++i) {
|
||||
auto song = songToObj(env, allSongs[i]);
|
||||
env->SetObjectArrayElement(songs, i, song);
|
||||
}
|
||||
|
||||
return songs;
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jobject
|
||||
JNICALL
|
||||
|
||||
@@ -8,12 +8,53 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace repository {
|
||||
// TODO: implement this
|
||||
std::vector<model::Song> SongRepository::fetchSongs(const std::string& token,
|
||||
std::vector<model::Song> SongRepository::fetchSongs(const model::Token& token,
|
||||
const std::string& uri)
|
||||
{
|
||||
std::string fullUri(uri);
|
||||
if (fullUri.at(fullUri.size()-1) != '/') {
|
||||
fullUri.append("/");
|
||||
}
|
||||
fullUri.append("api/v1/song");
|
||||
std::vector<model::Song> songs;
|
||||
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct curl_slist *chunk = nullptr;
|
||||
curl = curl_easy_init();
|
||||
|
||||
if (!curl) {
|
||||
return songs;
|
||||
}
|
||||
|
||||
constexpr auto EXPECTED_CHAR_AMOUNT = 100000;
|
||||
auto resp = std::make_unique<char[]>(EXPECTED_CHAR_AMOUNT);
|
||||
|
||||
std::string authInfo("Authorization: Bearer ");
|
||||
authInfo.append(token.accessToken);
|
||||
chunk = curl_slist_append(chunk, authInfo.c_str());
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, fullUri.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, respBodyRetriever);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, resp.get());
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if (res == CURLE_OK) {
|
||||
auto songsJson = nlohmann::json::parse(resp.get());
|
||||
for (auto& songJson: songsJson) {
|
||||
model::Song song(songJson["id"].get<int>(), songJson["title"].get<std::string>(),
|
||||
songJson["artist"].get<std::string>(), songJson["album"].get<std::string>(),
|
||||
songJson["genre"].get<std::string>(), songJson["duration"].get<int>(),
|
||||
songJson["year"].get<int>());
|
||||
|
||||
songs.push_back(song);
|
||||
}
|
||||
}
|
||||
|
||||
return songs;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,13 @@
|
||||
#include <vector>
|
||||
|
||||
#include "model/Song.h"
|
||||
#include "model/Token.h"
|
||||
|
||||
namespace repository {
|
||||
|
||||
class SongRepository {
|
||||
public:
|
||||
std::vector<model::Song> fetchSongs(const std::string&, const std::string&);
|
||||
std::vector<model::Song> fetchSongs(const model::Token&, const std::string&);
|
||||
|
||||
model::Song retrieveSong(const std::string&, const int);
|
||||
model::Song retrieveSong(const std::string&, const std::string&, const int);
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.example.mear.activities
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.support.annotation.RequiresApi
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.SearchView
|
||||
|
||||
import kotlinx.android.synthetic.main.activity_icarus_song.*
|
||||
import kotlinx.android.synthetic.main.content_song_view.*
|
||||
|
||||
import com.example.mear.activities.BaseServiceActivity
|
||||
import com.example.mear.adapters.RecyclerAdapter
|
||||
import com.example.mear.models.TrackItems
|
||||
import com.example.mear.models.Song
|
||||
import com.example.mear.R
|
||||
import com.example.mear.repositories.TrackRepository
|
||||
|
||||
|
||||
class IcarusSongActivity : BaseServiceActivity() {
|
||||
|
||||
private lateinit var adapter: RecyclerAdapter
|
||||
private lateinit var linearLayoutManager: LinearLayoutManager
|
||||
|
||||
private var songs: ArrayList<Song>? = null
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_icarus_song)
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
|
||||
try {
|
||||
val colr = R.color.track_seek
|
||||
window.statusBarColor = resources.getColor(R.color.track_seek)
|
||||
doBindService()
|
||||
initializeAdapter()
|
||||
//initializeSongSearchListener()
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val msg = ex.message
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun initializeAdapter() {
|
||||
try {
|
||||
linearLayoutManager = LinearLayoutManager(this)
|
||||
trackList.layoutManager = linearLayoutManager
|
||||
|
||||
songs!!.sortedWith(compareBy{it.title})
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val msg = ex.message
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.example.mear.activities
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.support.design.widget.Snackbar
|
||||
@@ -87,6 +88,7 @@ class LoginActivity : BaseServiceActivity() {
|
||||
if (saveCred && isUserTableEmpty(pa)) {
|
||||
saveUserCredentials(usernameStr, passwordStr, pa)
|
||||
}
|
||||
//startActivity(Intent(this, IcarusSongActivity::class.java))
|
||||
}
|
||||
catch (ex: Exception) {
|
||||
val msg = ex.message
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".activities.IcarusSongActivity">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/color_background"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
|
||||
<include
|
||||
android:id="@+id/include2"
|
||||
layout="@layout/content_song_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
@@ -51,7 +51,6 @@
|
||||
android:ems="10"
|
||||
android:hint="apiUri"
|
||||
android:inputType="textPersonName"
|
||||
android:text="https://www.soaricarus.com"
|
||||
app:layout_constraintBottom_toTopOf="@+id/saveUserCred"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
Reference in New Issue
Block a user