Able to retrieve an access token. Next implement fetching all songs. I left a TODO.
This commit was merged in pull request #56.
This commit is contained in:
+1
-1
@@ -64,6 +64,7 @@
|
|||||||
<output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/classes" />
|
<output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/classes" />
|
||||||
<exclude-output />
|
<exclude-output />
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/cpp" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debug/out" isTestSource="false" generated="true" />
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debug/out" isTestSource="false" generated="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" />
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||||
@@ -125,7 +126,6 @@
|
|||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/cpp" isTestSource="false" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.cxx" />
|
<excludeFolder url="file://$MODULE_DIR$/.cxx" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.externalNativeBuild" />
|
<excludeFolder url="file://$MODULE_DIR$/.externalNativeBuild" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||||
|
|||||||
@@ -15,13 +15,16 @@ cmake_minimum_required(VERSION 3.4.1)
|
|||||||
|
|
||||||
set (SOURCES
|
set (SOURCES
|
||||||
Demo.cpp
|
Demo.cpp
|
||||||
|
SongRepository.cpp
|
||||||
Tok.cpp
|
Tok.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set (HEADERS
|
set (HEADERS
|
||||||
model/Song.h
|
model/Song.h
|
||||||
model/User.h
|
model/User.h
|
||||||
|
SongRepository.h
|
||||||
Tok.h
|
Tok.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||||
|
|
||||||
@@ -29,13 +32,12 @@ set(JSON_BuildTests OFF CACHE INTERNAL "")
|
|||||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/json)
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/json)
|
||||||
|
|
||||||
|
|
||||||
add_library(native-lib
|
add_library(native-lib SHARED
|
||||||
SHARED
|
|
||||||
|
|
||||||
# Provides a relative path to your source file(s).
|
# Provides a relative path to your source file(s).
|
||||||
${SOURCES}
|
${SOURCES}
|
||||||
${HEADERS}
|
${HEADERS}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Searches for a specified prebuilt library and stores the path as a
|
# Searches for a specified prebuilt library and stores the path as a
|
||||||
@@ -44,27 +46,26 @@ add_library(native-lib
|
|||||||
# you want to add. CMake verifies that the library exists before
|
# you want to add. CMake verifies that the library exists before
|
||||||
# completing its build.
|
# completing its build.
|
||||||
|
|
||||||
find_library( # Sets the name of the path variable.
|
find_library(log-lib
|
||||||
log-lib
|
|
||||||
|
|
||||||
# Specifies the name of the NDK library that
|
# Specifies the name of the NDK library that
|
||||||
# you want CMake to locate.
|
# you want CMake to locate.
|
||||||
log )
|
log
|
||||||
|
)
|
||||||
|
|
||||||
# message(${CMAKE_ANDROID_ARCH_ABI})
|
|
||||||
|
|
||||||
set (CURL_LIBRARY
|
set (CURL_LIBRARY
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/${ANDROID_ABI}
|
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/${ANDROID_ABI}
|
||||||
)
|
)
|
||||||
|
|
||||||
set (CURL_INCLUDE_DIR
|
set (CURL_INCLUDE_DIR
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/include/curl
|
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/include/curl
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/include
|
${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/include
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(boo STATIC IMPORTED)
|
add_library(boo STATIC IMPORTED)
|
||||||
set_target_properties(boo PROPERTIES IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/${ANDROID_ABI}/libcurl.a")
|
set_target_properties(boo PROPERTIES IMPORTED_LOCATION
|
||||||
#find_package(CURL REQUIRED)
|
"${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/android/${ANDROID_ABI}/libcurl.a"
|
||||||
|
)
|
||||||
|
|
||||||
include_directories(${CURL_INCLUDE_DIR})
|
include_directories(${CURL_INCLUDE_DIR})
|
||||||
|
|
||||||
@@ -72,15 +73,10 @@ include_directories(${CURL_INCLUDE_DIR})
|
|||||||
# can link multiple libraries, such as libraries you define in this
|
# can link multiple libraries, such as libraries you define in this
|
||||||
# build script, prebuilt third-party libraries, or system libraries.
|
# build script, prebuilt third-party libraries, or system libraries.
|
||||||
|
|
||||||
#target_include_directories(native-lib PUBLIC ${CURL_INCLUDE_DIR})
|
target_link_libraries(native-lib PRIVATE
|
||||||
target_link_libraries( # Specifies the target library.
|
|
||||||
native-lib
|
|
||||||
PRIVATE nlohmann_json::nlohmann_json
|
|
||||||
boo
|
|
||||||
#${CURL_LIBRARIES}
|
|
||||||
|
|
||||||
# Links the target library to the log library
|
nlohmann_json::nlohmann_json
|
||||||
# included in the NDK.
|
boo
|
||||||
${log-lib}
|
${log-lib}
|
||||||
z
|
z
|
||||||
)
|
)
|
||||||
+21
-115
@@ -20,134 +20,40 @@
|
|||||||
|
|
||||||
#include "model/Song.h"
|
#include "model/Song.h"
|
||||||
#include "model/User.h"
|
#include "model/User.h"
|
||||||
|
#include "Tok.h"
|
||||||
|
|
||||||
|
|
||||||
std::string fetchToken();
|
std::string fetchToken(const std::string&, const std::string&, const std::string&);
|
||||||
|
|
||||||
model::Song initSong();
|
|
||||||
model::User initUser();
|
|
||||||
|
|
||||||
size_t funcTest(void*, size_t, size_t, char*);
|
|
||||||
//size_t funcTest(void*, size_t, size_t, std::string&);
|
|
||||||
|
|
||||||
int demoCall();
|
|
||||||
|
|
||||||
void printSong(const model::Song&);
|
|
||||||
|
|
||||||
|
|
||||||
std::string fetchToken()
|
std::string fetchToken(const std::string& username, const std::string& password,
|
||||||
|
const std::string& apiUri)
|
||||||
{
|
{
|
||||||
auto user = initUser();
|
model::User user(username, password);
|
||||||
nlohmann::json usr;
|
manager::Tok tokMgr;
|
||||||
usr["username"] = user.username;
|
|
||||||
usr["password"] = user.password;
|
|
||||||
|
|
||||||
CURL *curl;
|
auto token = tokMgr.fetchToken(user, apiUri);
|
||||||
CURLcode res;
|
|
||||||
|
|
||||||
curl = curl_easy_init();
|
return token;
|
||||||
|
|
||||||
std::string tok;
|
|
||||||
if (curl) {
|
|
||||||
const auto url = "";
|
|
||||||
|
|
||||||
char resp[2048];
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
||||||
const std::string a = usr.dump();
|
|
||||||
//std::string r;
|
|
||||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, a.c_str());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, funcTest);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, resp);
|
|
||||||
//curl_easy_setopt(curl, CURLOPT_WRITEDATA, r);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
|
||||||
|
|
||||||
res = curl_easy_perform(curl);
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
|
|
||||||
const std::string i = resp;
|
|
||||||
auto s = nlohmann::json::parse(i);
|
|
||||||
tok = s["token"].get<std::string>();
|
|
||||||
return tok;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
model::Song initSong()
|
|
||||||
{
|
|
||||||
model::Song song;
|
|
||||||
song.title = "hello";
|
|
||||||
song.artist = "some artist";
|
|
||||||
|
|
||||||
return song;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
model::User initUser()
|
|
||||||
{
|
|
||||||
model::User user;
|
|
||||||
user.username = "";
|
|
||||||
user.password = "";
|
|
||||||
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t funcTest(void* ptr, size_t size, size_t nmemb, char *e)
|
|
||||||
{
|
|
||||||
std::memcpy(e, ptr, nmemb);
|
|
||||||
e[nmemb] = '\0';
|
|
||||||
|
|
||||||
return nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t funcTest(void* ptr, size_t size, size_t nmemb, std::string& e)
|
|
||||||
{
|
|
||||||
e = (char*) ptr;
|
|
||||||
|
|
||||||
return nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int demoCall()
|
|
||||||
{
|
|
||||||
model::Song song = initSong();
|
|
||||||
|
|
||||||
std::cout << "testing" << std::endl;
|
|
||||||
printSong(song);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void printSong(const model::Song& song)
|
|
||||||
{
|
|
||||||
std::cout << "\nsong information" << std::endl;
|
|
||||||
std::cout << "title: " << song.title << std::endl;
|
|
||||||
std::cout << "artist: " << song.artist << std::endl;
|
|
||||||
std::cout << "album: " << song.album << std::endl;
|
|
||||||
std::cout << "genre: " << song.genre << std::endl;
|
|
||||||
std::cout << "year: " << song.year << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT void
|
JNIEXPORT jstring
|
||||||
JNICALL
|
|
||||||
Java_com_example_mear_activities_MainActivity_test(
|
|
||||||
JNIEnv *env,
|
|
||||||
jobject /* this */) {
|
|
||||||
|
|
||||||
demoCall();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT void
|
|
||||||
JNICALL
|
JNICALL
|
||||||
Java_com_example_mear_activities_DemoStreamActivity_test(
|
Java_com_example_mear_activities_DemoStreamActivity_logUser(
|
||||||
JNIEnv *env,
|
JNIEnv *env,
|
||||||
jobject /* this */) {
|
jobject thisObj,
|
||||||
|
jstring username,
|
||||||
|
jstring password,
|
||||||
|
jstring apiUri ) {
|
||||||
|
|
||||||
auto tok = fetchToken();
|
const std::string usr = env->GetStringUTFChars(username, NULL);
|
||||||
|
const std::string pass = env->GetStringUTFChars(password, NULL);
|
||||||
|
const std::string api = env->GetStringUTFChars(apiUri, NULL);
|
||||||
|
|
||||||
|
auto token = fetchToken(usr, pass, api);
|
||||||
|
|
||||||
|
return env->NewStringUTF(token.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// Created by brahmix on 10/3/19.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SongRepository.h"
|
||||||
|
|
||||||
|
namespace repository {
|
||||||
|
// TODO: implement this
|
||||||
|
std::vector<model::Song> SongRepository::fetchSongs(const std::string& token,
|
||||||
|
const std::string& uri)
|
||||||
|
{
|
||||||
|
std::vector<model::Song> songs;
|
||||||
|
|
||||||
|
return songs;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// Created by brahmix on 10/3/19.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MEAR_SONGREPOSITORY_H
|
||||||
|
#define MEAR_SONGREPOSITORY_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "model/Song.h"
|
||||||
|
|
||||||
|
namespace repository {
|
||||||
|
|
||||||
|
class SongRepository {
|
||||||
|
public:
|
||||||
|
std::vector<model::Song> fetchSongs(const std::string&, const std::string&);
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MEAR_SONGREPOSITORY_H
|
||||||
@@ -3,3 +3,69 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "Tok.h"
|
#include "Tok.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
namespace manager {
|
||||||
|
std::string Tok::fetchToken(const model::User &user, const std::string& uri) {
|
||||||
|
CURL *curl;
|
||||||
|
CURLcode res;
|
||||||
|
|
||||||
|
curl = curl_easy_init();
|
||||||
|
|
||||||
|
if (!curl) {
|
||||||
|
return "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
char resp[2048];
|
||||||
|
|
||||||
|
const auto loginUri = fetchLoginUri(uri);
|
||||||
|
const auto obj = userJsonString(user);
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, loginUri.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, obj.c_str());
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, respBodyRetriever);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, resp);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||||
|
|
||||||
|
res = curl_easy_perform(curl);
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
|
||||||
|
if (res == CURLE_OK) {
|
||||||
|
auto s = nlohmann::json::parse(resp);
|
||||||
|
return s["token"].get<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "failure";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string Tok::fetchLoginUri(const std::string& baseUri)
|
||||||
|
{
|
||||||
|
std::string uri(baseUri);
|
||||||
|
uri.append("/api/v1/login");
|
||||||
|
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Tok::userJsonString(const model::User& user)
|
||||||
|
{
|
||||||
|
nlohmann::json usr;
|
||||||
|
usr["username"] = user.username;
|
||||||
|
usr["password"] = user.password;
|
||||||
|
|
||||||
|
return usr.dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t Tok::respBodyRetriever(void* ptr, size_t size, size_t nmemb, char *e)
|
||||||
|
{
|
||||||
|
std::memcpy(e, ptr, nmemb);
|
||||||
|
e[nmemb] = '\0';
|
||||||
|
|
||||||
|
return nmemb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+13
-2
@@ -7,9 +7,20 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class Tok {
|
#include "model/User.h"
|
||||||
|
|
||||||
};
|
namespace manager {
|
||||||
|
|
||||||
|
class Tok {
|
||||||
|
public:
|
||||||
|
std::string fetchToken(const model::User&, const std::string&);
|
||||||
|
private:
|
||||||
|
std::string fetchLoginUri(const std::string&);
|
||||||
|
std::string userJsonString(const model::User&);
|
||||||
|
|
||||||
|
static size_t respBodyRetriever(void*, size_t, size_t, char*);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif //MEAR_TOK_H
|
#endif //MEAR_TOK_H
|
||||||
|
|||||||
@@ -5,11 +5,14 @@
|
|||||||
#ifndef MEAR_USER_H
|
#ifndef MEAR_USER_H
|
||||||
#define MEAR_USER_H
|
#define MEAR_USER_H
|
||||||
|
|
||||||
//#include "../../../../../../../../Android/Sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/string"
|
|
||||||
|
|
||||||
namespace model {
|
namespace model {
|
||||||
struct User
|
struct User
|
||||||
{
|
{
|
||||||
|
User() = default;
|
||||||
|
User(const std::string& user, const std::string& pass) :
|
||||||
|
username(user), password(pass) { }
|
||||||
|
|
||||||
std::string username;
|
std::string username;
|
||||||
std::string password;
|
std::string password;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.example.mear.R
|
|||||||
|
|
||||||
import kotlinx.android.synthetic.main.activity_demo_stream.*
|
import kotlinx.android.synthetic.main.activity_demo_stream.*
|
||||||
import kotlinx.android.synthetic.main.content_demo_stream.*
|
import kotlinx.android.synthetic.main.content_demo_stream.*
|
||||||
|
import org.jetbrains.anko.toast
|
||||||
|
|
||||||
class DemoStreamActivity : AppCompatActivity() {
|
class DemoStreamActivity : AppCompatActivity() {
|
||||||
|
|
||||||
@@ -17,7 +18,8 @@ class DemoStreamActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
external fun test();
|
private external fun logUser(usr: String, pass: String, api: String): String
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -25,7 +27,11 @@ class DemoStreamActivity : AppCompatActivity() {
|
|||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
|
|
||||||
demoStream.setOnClickListener {
|
demoStream.setOnClickListener {
|
||||||
test()
|
toast("vacant").show()
|
||||||
|
}
|
||||||
|
|
||||||
|
login.setOnClickListener {
|
||||||
|
loginButton()
|
||||||
}
|
}
|
||||||
|
|
||||||
fab.setOnClickListener {view ->
|
fab.setOnClickListener {view ->
|
||||||
@@ -34,4 +40,32 @@ class DemoStreamActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun loginButton() {
|
||||||
|
if (!validFields()) {
|
||||||
|
toast("Fields are invalid").show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var usernameStr = username.text.toString()
|
||||||
|
var passwordStr = password.text.toString()
|
||||||
|
var apiUriStr = apiUri.text.toString()
|
||||||
|
|
||||||
|
var token = logUser(usernameStr, passwordStr, apiUriStr)
|
||||||
|
toast(token).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validFields(): Boolean {
|
||||||
|
if (username.text.isEmpty()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (password.text.isEmpty()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (password.text.isEmpty()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,60 @@
|
|||||||
android:id="@+id/demoStream"
|
android:id="@+id/demoStream"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="140dp"
|
android:layout_marginStart="16dp"
|
||||||
android:text="Stream"
|
android:text="Stream"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintVertical_bias="0.499" />
|
app:layout_constraintVertical_bias="0.954" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/username"
|
||||||
|
android:layout_width="245dp"
|
||||||
|
android:layout_height="43dp"
|
||||||
|
android:layout_marginBottom="32dp"
|
||||||
|
android:ems="10"
|
||||||
|
android:hint="username"
|
||||||
|
android:inputType="textPersonName"
|
||||||
|
android:text="kverse"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/password"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/password"
|
||||||
|
android:layout_width="245dp"
|
||||||
|
android:layout_height="43dp"
|
||||||
|
android:layout_marginBottom="32dp"
|
||||||
|
android:ems="10"
|
||||||
|
android:hint="password"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:text="demolaugh"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/apiUri"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/apiUri"
|
||||||
|
android:layout_width="245dp"
|
||||||
|
android:layout_height="43dp"
|
||||||
|
android:layout_marginBottom="76dp"
|
||||||
|
android:ems="10"
|
||||||
|
android:hint="apiUri"
|
||||||
|
android:inputType="textPersonName"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/login"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/login"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="92dp"
|
||||||
|
android:text="Login"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.498"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
Reference in New Issue
Block a user