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:
kdeng00
2019-10-08 23:28:19 -04:00
parent 9483c6b834
commit 6b746cd1d0
13 changed files with 589 additions and 412 deletions
+4 -3
View File
@@ -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>
+76
View File
@@ -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
+43 -2
View File
@@ -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;
}
+2 -1
View File
@@ -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" />