Browse Source

Add base application and activity (okhttp supported), Add drawer

master
Apostolos Fanakis 6 years ago
parent
commit
4147767a1f
  1. 5
      UI/AndroidApp/flavoursWithoutBorders/app/build.gradle
  2. 8
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/AndroidManifest.xml
  3. 4
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/java/gr/auth/databases/flavours/activities/LoginActivity.java
  4. 9
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/java/gr/auth/databases/flavours/activities/SignUpActivity.java
  5. 24
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/java/gr/auth/databases/flavours/activities/main/MainActivity.java
  6. 265
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/java/gr/auth/databases/flavours/base/BaseActivity.java
  7. 72
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/java/gr/auth/databases/flavours/base/BaseApplication.java
  8. 205
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/java/gr/auth/databases/flavours/session/SessionManager.java
  9. BIN
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-hdpi/ic_list_black_24dp.png
  10. BIN
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-hdpi/ic_menu_black_24dp.png
  11. BIN
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-mdpi/ic_list_black_24dp.png
  12. BIN
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-mdpi/ic_menu_black_24dp.png
  13. BIN
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-xhdpi/ic_list_black_24dp.png
  14. BIN
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-xhdpi/ic_menu_black_24dp.png
  15. BIN
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-xxhdpi/ic_list_black_24dp.png
  16. BIN
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-xxhdpi/ic_menu_black_24dp.png
  17. BIN
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-xxxhdpi/ic_list_black_24dp.png
  18. BIN
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-xxxhdpi/ic_menu_black_24dp.png
  19. 4
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/layout/activity_main_list_row.xml
  20. 2
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/values/colors.xml
  21. 8
      UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/values/strings.xml
  22. 1
      UI/AndroidApp/flavoursWithoutBorders/build.gradle

5
UI/AndroidApp/flavoursWithoutBorders/app/build.gradle

@ -26,9 +26,14 @@ dependencies {
implementation 'androidx.legacy:legacy-preference-v14:1.0.0' implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.0.0' implementation 'androidx.coordinatorlayout:coordinatorlayout:1.0.0'
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
implementation 'com.github.franmontiel:PersistentCookieJar:v1.0.1'
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.mikepenz:materialdrawer:6.1.1'
implementation 'androidx.recyclerview:recyclerview:1.0.0' implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
implementation 'com.mikepenz:fontawesome-typeface:4.7.0.0@aar'
implementation 'com.mikepenz:google-material-typeface:3.0.1.2.original@aar'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.0.0' implementation 'com.google.android.material:material:1.0.0'
implementation 'com.google.android.gms:play-services-maps:16.0.0' implementation 'com.google.android.gms:play-services-maps:16.0.0'

8
UI/AndroidApp/flavoursWithoutBorders/app/src/main/AndroidManifest.xml

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="gr.auth.databases.flavours"> package="gr.auth.databases.flavours">
<!-- <!--
@ -8,14 +9,17 @@
location permissions for the 'MyLocation' functionality. location permissions for the 'MyLocation' functionality.
--> -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application <application
android:name=".base.BaseApplication"
android:allowBackup="true" android:allowBackup="true"
android:icon="@drawable/logo" android:icon="@drawable/logo"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@drawable/logo_round" android:roundIcon="@drawable/logo_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".activities.LoginActivity"> <activity android:name=".activities.LoginActivity">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@ -40,7 +44,7 @@
<activity <activity
android:name=".activities.main.MainActivity" android:name=".activities.main.MainActivity"
android:label="@string/title_activity_main"></activity> android:label="@string/main_activity_title" />
</application> </application>
</manifest> </manifest>

4
UI/AndroidApp/flavoursWithoutBorders/app/src/main/java/gr/auth/databases/flavours/activities/LoginActivity.java

@ -4,11 +4,11 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import gr.auth.databases.flavours.R; import gr.auth.databases.flavours.R;
import gr.auth.databases.flavours.activities.main.MainActivity; import gr.auth.databases.flavours.activities.main.MainActivity;
import gr.auth.databases.flavours.base.BaseActivity;
public class LoginActivity extends AppCompatActivity { public class LoginActivity extends BaseActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {

9
UI/AndroidApp/flavoursWithoutBorders/app/src/main/java/gr/auth/databases/flavours/activities/SignUpActivity.java

@ -1,5 +1,6 @@
package gr.auth.databases.flavours.activities; package gr.auth.databases.flavours.activities;
import android.annotation.SuppressLint;
import android.app.DatePickerDialog; import android.app.DatePickerDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.Intent; import android.content.Intent;
@ -13,13 +14,13 @@ import java.util.Calendar;
import java.util.Objects; import java.util.Objects;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import gr.auth.databases.flavours.R; import gr.auth.databases.flavours.R;
import gr.auth.databases.flavours.activities.LoginActivity; import gr.auth.databases.flavours.base.BaseActivity;
public class SignUpActivity extends AppCompatActivity { public class SignUpActivity extends BaseActivity {
@SuppressLint("ClickableViewAccessibility")
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -65,7 +66,7 @@ public class SignUpActivity extends AppCompatActivity {
} }
public void onDateSet(DatePicker view, int year, int month, int day) { public void onDateSet(DatePicker view, int year, int month, int day) {
birthdayInput.setText("" + year + "-" + month + "-" + day); birthdayInput.setText(getResources().getString(R.string.sign_up_birthday_placeholder, year, month + 1, day));
} }
} }
} }

24
UI/AndroidApp/flavoursWithoutBorders/app/src/main/java/gr/auth/databases/flavours/activities/main/MainActivity.java

@ -4,9 +4,8 @@ import android.os.Bundle;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.ActionBar;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
@ -16,8 +15,9 @@ import androidx.viewpager.widget.ViewPager;
import gr.auth.databases.flavours.R; import gr.auth.databases.flavours.R;
import gr.auth.databases.flavours.activities.main.fragments.MainListFragment; import gr.auth.databases.flavours.activities.main.fragments.MainListFragment;
import gr.auth.databases.flavours.activities.main.fragments.MainMapFragment; import gr.auth.databases.flavours.activities.main.fragments.MainMapFragment;
import gr.auth.databases.flavours.base.BaseActivity;
public class MainActivity extends AppCompatActivity { public class MainActivity extends BaseActivity {
private static final int NUM_PAGES = 2; private static final int NUM_PAGES = 2;
private ViewPager viewPager; private ViewPager viewPager;
private MenuItem menuMapItem; private MenuItem menuMapItem;
@ -30,6 +30,12 @@ public class MainActivity extends AppCompatActivity {
Toolbar toolbar = findViewById(R.id.main_toolbar); Toolbar toolbar = findViewById(R.id.main_toolbar);
toolbar.setTitle("Restaurants"); toolbar.setTitle("Restaurants");
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
ActionBar actionbar = getSupportActionBar();
actionbar.setDisplayHomeAsUpEnabled(true);
actionbar.setHomeAsUpIndicator(R.drawable.ic_menu_black_24dp);
createDrawer();
viewPager = findViewById(R.id.main_pager); viewPager = findViewById(R.id.main_pager);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@ -45,9 +51,9 @@ public class MainActivity extends AppCompatActivity {
} }
if (position == 0) { if (position == 0) {
menuMapItem.setVisible(true); menuMapItem.setIcon(R.drawable.ic_map_black_24dp);
} else { } else {
menuMapItem.setVisible(false); menuMapItem.setIcon(R.drawable.ic_list_black_24dp);
} }
} }
}); });
@ -79,10 +85,18 @@ public class MainActivity extends AppCompatActivity {
if (id == R.id.main_toolbar_menu_filter) { if (id == R.id.main_toolbar_menu_filter) {
return true; return true;
} else if (id == R.id.main_toolbar_menu_map) { } else if (id == R.id.main_toolbar_menu_map) {
if (viewPager.getCurrentItem() == 0) {
viewPager.setCurrentItem(1); viewPager.setCurrentItem(1);
} else if (viewPager.getCurrentItem() == 1) {
viewPager.setCurrentItem(0);
}
return true;
} else if (id == android.R.id.home) {
drawer.openDrawer();
return true; return true;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }

265
UI/AndroidApp/flavoursWithoutBorders/app/src/main/java/gr/auth/databases/flavours/base/BaseActivity.java

@ -0,0 +1,265 @@
package gr.auth.databases.flavours.base;
import android.Manifest;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import com.mikepenz.fontawesome_typeface_library.FontAwesome;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.materialdrawer.AccountHeader;
import com.mikepenz.materialdrawer.AccountHeaderBuilder;
import com.mikepenz.materialdrawer.Drawer;
import com.mikepenz.materialdrawer.DrawerBuilder;
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
import gr.auth.databases.flavours.R;
import gr.auth.databases.flavours.activities.LoginActivity;
import gr.auth.databases.flavours.activities.main.MainActivity;
import gr.auth.databases.flavours.session.SessionManager;
import okhttp3.OkHttpClient;
public abstract class BaseActivity extends AppCompatActivity {
// Client & Cookies
protected static OkHttpClient client;
//SessionManager
protected static SessionManager sessionManager;
private SharedPreferences sharedPreferences;
//Common UI elements
protected Toolbar toolbar;
protected Drawer drawer;
private boolean isMainActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isMainActivity = this instanceof MainActivity;
if (client == null)
client = BaseApplication.getInstance().getClient(); //must check every time - e.g.
// they become null when app restarts after crash
if (sessionManager == null)
sessionManager = BaseApplication.getInstance().getSessionManager();
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
}
@Override
protected void onResume() {
super.onResume();
updateDrawer();
}
@Override
protected void onPause() {
super.onPause();
if (drawer != null) //close drawer animation after returning to activity
drawer.closeDrawer();
}
public static OkHttpClient getClient() {
return client;
}
public static SessionManager getSessionManager() {
return sessionManager;
}
//------------------------------------------DRAWER STUFF----------------------------------------
protected static final int HOME_ID = 0;
protected static final int LOG_ID = 4;
private AccountHeader accountHeader;
private ProfileDrawerItem profileDrawerItem;
private PrimaryDrawerItem loginLogoutItem;
protected void createDrawer() {
final int primaryColor = ContextCompat.getColor(this, R.color.textPrimary);
final int selectedPrimaryColor = ContextCompat.getColor(this, R.color.primary_dark);
final int selectedSecondaryColor = ContextCompat.getColor(this, R.color.iron);
PrimaryDrawerItem homeItem;
IconicsDrawable homeIcon, homeIconSelected;
//Drawer Icons
homeIcon = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_home)
.color(primaryColor);
homeIconSelected = new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_home)
.color(selectedSecondaryColor);
IconicsDrawable loginIcon = new IconicsDrawable(this)
.icon(FontAwesome.Icon.faw_sign_in)
.color(primaryColor);
IconicsDrawable logoutIcon = new IconicsDrawable(this)
.icon(FontAwesome.Icon.faw_sign_out)
.color(primaryColor);
//Drawer Items
homeItem = new PrimaryDrawerItem()
.withTextColor(primaryColor)
.withSelectedColor(selectedPrimaryColor)
.withSelectedTextColor(selectedSecondaryColor)
.withIdentifier(HOME_ID)
.withName(R.string.drawer_home)
.withIcon(homeIcon)
.withSelectedIcon(homeIconSelected);
if (sessionManager.isLoggedIn()) {
loginLogoutItem = new PrimaryDrawerItem()
.withTextColor(primaryColor)
.withSelectedColor(selectedSecondaryColor)
.withIdentifier(LOG_ID)
.withName(R.string.drawer_logout)
.withIcon(logoutIcon)
.withSelectable(false);
} else {
loginLogoutItem = new PrimaryDrawerItem()
.withTextColor(primaryColor)
.withSelectedColor(selectedSecondaryColor)
.withIdentifier(LOG_ID).withName(R.string.drawer_login)
.withIcon(loginIcon)
.withSelectable(false);
}
//Profile
profileDrawerItem = new ProfileDrawerItem().withName(sessionManager.getUsername()).withIdentifier(0);
//AccountHeader
accountHeader = new AccountHeaderBuilder()
.withActivity(this)
.withCompactStyle(true)
.withSelectionListEnabledForSingleProfile(false)
.withHeaderBackground(R.color.primary)
.withTextColor(getResources().getColor(R.color.iron))
.addProfiles(profileDrawerItem)
/*.withOnAccountHeaderListener((view, profile, currentProfile) -> {
if (sessionManager.isLoggedIn()) {
Intent intent = new Intent(BaseActivity.this, ProfileActivity.class);
Bundle extras = new Bundle();
extras.putString(BUNDLE_PROFILE_URL, "https://www.thmmy.gr/smf/index.php?action=profile");
extras.putString(BUNDLE_PROFILE_USERNAME, sessionManager.getUsername());
intent.putExtras(extras);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
return false;
} else
startLoginActivity();
return true;
})*/
.build();
DrawerBuilder drawerBuilder = new DrawerBuilder()
.withActivity(this)
.withToolbar(toolbar)
.withDrawerWidthDp((int) BaseApplication.getInstance().getDpWidth() / 2)
.withSliderBackgroundColor(ContextCompat.getColor(this, R.color.colorBackground))
.withAccountHeader(accountHeader)
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
@Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
if (drawerItem.equals(HOME_ID)) {
if (!isMainActivity) {
Intent intent = new Intent(BaseActivity.this, MainActivity.class);
startActivity(intent);
}
} else if (drawerItem.equals(LOG_ID)) {
if (!sessionManager.isLoggedIn()) //When logged out or if user is guest
startLoginActivity();
/*else
new LogoutTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);*/
}
drawer.closeDrawer();
return true;
}
});
drawerBuilder.addDrawerItems(homeItem, loginLogoutItem);
drawer = drawerBuilder.build();
if (!isMainActivity)
drawer.getActionBarDrawerToggle().setDrawerIndicatorEnabled(false);
drawer.setOnDrawerNavigationListener(new Drawer.OnDrawerNavigationListener() {
@Override
public boolean onNavigationClickListener(View clickedView) {
onBackPressed();
return true;
}
});
}
private void updateDrawer() {
if (drawer != null) {
accountHeader.updateProfile(profileDrawerItem);
drawer.updateItem(loginLogoutItem);
}
}
//-------PERMS---------
private static final int PERMISSIONS_REQUEST_CODE = 69;
//True if permissions are OK
private boolean checkPerms() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
return !(checkSelfPermission(PERMISSIONS_STORAGE[0]) == PackageManager.PERMISSION_DENIED ||
checkSelfPermission(PERMISSIONS_STORAGE[1]) == PackageManager.PERMISSION_DENIED);
}
return true;
}
//Display popup for user to grant permission
private void requestPerms() { //Runtime permissions request for devices with API >= 23
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestPermissions(PERMISSIONS_STORAGE, PERMISSIONS_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int permsRequestCode, @NonNull String[] permissions
, @NonNull int[] grantResults) {
switch (permsRequestCode) {
case PERMISSIONS_REQUEST_CODE:
//downloadFile();
break;
}
}
private void startLoginActivity() {
Intent intent = new Intent(BaseActivity.this, LoginActivity.class);
startActivity(intent);
}
}

72
UI/AndroidApp/flavoursWithoutBorders/app/src/main/java/gr/auth/databases/flavours/base/BaseApplication.java

@ -0,0 +1,72 @@
package gr.auth.databases.flavours.base;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.DisplayMetrics;
import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.cache.SetCookieCache;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
import java.util.concurrent.TimeUnit;
import gr.auth.databases.flavours.session.SessionManager;
import okhttp3.OkHttpClient;
public class BaseApplication extends Application {
private static BaseApplication baseApplication; //BaseApplication singleton
//Client & SessionManager
private OkHttpClient client;
private SessionManager sessionManager;
private static final String SHARED_PREFS = "ThmmySharedPrefs";
private static float dpWidth;
public static BaseApplication getInstance() {
return baseApplication;
}
@Override
public void onCreate() {
super.onCreate();
baseApplication = this; //init singleton
//Shared Preferences
SharedPreferences sharedPrefs = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
SharedPrefsCookiePersistor sharedPrefsCookiePersistor = new SharedPrefsCookiePersistor(getApplicationContext());
PersistentCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), sharedPrefsCookiePersistor);
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.cookieJar(cookieJar)
.connectTimeout(40, TimeUnit.SECONDS)
.writeTimeout(40, TimeUnit.SECONDS)
.readTimeout(40, TimeUnit.SECONDS);
client = builder.build();
sessionManager = new SessionManager(client, cookieJar, sharedPrefsCookiePersistor, sharedPrefs);
DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics();
dpWidth = displayMetrics.widthPixels / displayMetrics.density;
}
//Getters
public Context getContext() {
return getApplicationContext();
}
public OkHttpClient getClient() {
return client;
}
public SessionManager getSessionManager() {
return sessionManager;
}
public float getDpWidth() {
return dpWidth;
}
}

205
UI/AndroidApp/flavoursWithoutBorders/app/src/main/java/gr/auth/databases/flavours/session/SessionManager.java

@ -0,0 +1,205 @@
package gr.auth.databases.flavours.session;
import android.content.SharedPreferences;
import com.franmontiel.persistentcookiejar.PersistentCookieJar;
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
import java.util.List;
import okhttp3.Cookie;
import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class SessionManager {
//Generic constants
public static final HttpUrl indexUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?theme=4");
private static final HttpUrl loginUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=login2");
// Client & Cookies
private final OkHttpClient client;
private final PersistentCookieJar cookieJar;
private final SharedPrefsCookiePersistor cookiePersistor; //Used to explicitly edit cookies in cookieJar
//Shared Preferences & its keys
private final SharedPreferences sharedPrefs;
private static final String USERNAME = "Username";
private static final String USER_ID = "UserID";
private static final String LOGOUT_LINK = "LogoutLink";
private static final String LOGGED_IN = "LoggedIn";
private static final String LOGIN_SCREEN_AS_DEFAULT = "LoginScreenAsDefault";
//Constructor
public SessionManager(OkHttpClient client, PersistentCookieJar cookieJar,
SharedPrefsCookiePersistor cookiePersistor, SharedPreferences sharedPrefs) {
this.client = client;
this.cookiePersistor = cookiePersistor;
this.cookieJar = cookieJar;
this.sharedPrefs = sharedPrefs;
}
public int login(String... strings) {
//Builds the login request for each case
Request request;
if (strings.length == 2) {
clearSessionData();
String loginName = strings[0];
String password = strings[1];
RequestBody formBody = new FormBody.Builder()
.add("user", loginName)
.add("passwrd", password)
.add("cookielength", "-1") //-1 is forever
.build();
request = new Request.Builder()
.url(loginUrl)
.post(formBody)
.build();
} else {
request = new Request.Builder()
.url(loginUrl)
.build();
}
try {
//Makes request & handles response
Response response = client.newCall(request).execute();
if (validateRetrievedCookies()) {
setPersistentCookieSession(); //Store cookies
//Edit SharedPreferences, save session's data
SharedPreferences.Editor editor = sharedPrefs.edit();
setLoginScreenAsDefault(false);
editor.putBoolean(LOGGED_IN, true);
/*editor.putString(USERNAME, extractUserName(document));
editor.putInt(USER_ID, extractUserId(document));
String avatar = extractAvatarLink(document);*/
/*if (avatar != null)
editor.putString(AVATAR_LINK, avatar);
editor.putBoolean(HAS_AVATAR, avatar != null);
editor.putString(LOGOUT_LINK, extractLogoutLink(document));*/
editor.apply();
return 0;
} else {
//Investigates login failure
/*if (error.size() > 0) { //Wrong username
return WRONG_USER;
}
if (error.size() > 0) { //Wrong password
return WRONG_PASSWORD;
}
if (error.size() > 0) { //User is banned
return BANNED_USER;
}*/
//Other error e.g. session was reset server-side
clearSessionData(); //Clear invalid saved data
return 1;
}
//Handles exceptions
} catch (Exception e) {
return 2;
}
}
public void validateSession() {
if (isLoggedIn()) {
int loginResult = login();
if (loginResult != 1)
return;
} else if (isLoginScreenDefault())
return;
setLoginScreenAsDefault(true);
clearSessionData();
}
public int logout() {
Request request = new Request.Builder()
.url(sharedPrefs.getString(LOGOUT_LINK, "LogoutLink"))
.build();
try {
//Makes request & handles response
Response response = client.newCall(request).execute();
} catch (Exception e) {
return 2;
} finally {
//All data should always be cleared from device regardless the result of logout
clearSessionData();
}
return 0;
}
public String getUsername() {
return sharedPrefs.getString(USERNAME, USERNAME);
}
public int getUserId() {
return sharedPrefs.getInt(USER_ID, -1);
}
public Cookie getThmmyCookie() {
List<Cookie> cookieList = cookieJar.loadForRequest(indexUrl);
for (Cookie cookie : cookieList) {
if (cookie.name().equals("THMMYgrC00ki3"))
return cookie;
}
return null;
}
public boolean isLoggedIn() {
return sharedPrefs.getBoolean(LOGGED_IN, false);
}
public boolean isLoginScreenDefault() {
return sharedPrefs.getBoolean(LOGIN_SCREEN_AS_DEFAULT, true);
}
private boolean validateRetrievedCookies() {
List<Cookie> cookieList = cookieJar.loadForRequest(indexUrl);
for (Cookie cookie : cookieList) {
if (cookie.name().equals("THMMYgrC00ki3"))
return true;
}
return false;
}
// Call validateRetrievedCookies() first
private void setPersistentCookieSession() {
List<Cookie> cookieList = cookieJar.loadForRequest(indexUrl);
Cookie.Builder builder = new Cookie.Builder();
builder.name(cookieList.get(1).name())
.value(cookieList.get(1).value())
.domain(cookieList.get(1).domain())
.expiresAt(cookieList.get(0).expiresAt());
cookieList.remove(1);
cookieList.add(builder.build());
cookiePersistor.clear();
cookiePersistor.saveAll(cookieList);
}
private void clearSessionData() {
cookieJar.clear();
sharedPrefs.edit().clear().apply(); //Clear session data
sharedPrefs.edit().putString(USERNAME, "Guest").apply();
sharedPrefs.edit().putInt(USER_ID, -1).apply();
sharedPrefs.edit().putBoolean(LOGGED_IN, false).apply(); //User logs out
}
private void setLoginScreenAsDefault(boolean b) {
sharedPrefs.edit().putBoolean(LOGIN_SCREEN_AS_DEFAULT, b).apply();
}
}

BIN
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-hdpi/ic_list_black_24dp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

BIN
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-hdpi/ic_menu_black_24dp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 B

BIN
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-mdpi/ic_list_black_24dp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

BIN
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-mdpi/ic_menu_black_24dp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

BIN
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-xhdpi/ic_list_black_24dp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

BIN
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-xhdpi/ic_menu_black_24dp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

BIN
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-xxhdpi/ic_list_black_24dp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

BIN
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-xxhdpi/ic_menu_black_24dp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

BIN
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-xxxhdpi/ic_list_black_24dp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

BIN
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/drawable-xxxhdpi/ic_menu_black_24dp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

4
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/layout/activity_main_list_row.xml

@ -4,9 +4,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:foreground="?android:attr/selectableItemBackground" android:foreground="?android:attr/selectableItemBackground"
card_view:cardCornerRadius="5dp" card_view:cardCornerRadius="5dp"
card_view:cardElevation="1dp" card_view:cardElevation="2dp"
card_view:cardPreventCornerOverlap="false" card_view:cardPreventCornerOverlap="false"
card_view:cardUseCompatPadding="true"> card_view:cardUseCompatPadding="true">

2
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/values/colors.xml

@ -4,4 +4,6 @@
<color name="colorPrimaryDark">#00574B</color> <color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color> <color name="colorAccent">#D81B60</color>
<color name="colorBackground">#DDDDDD</color> <color name="colorBackground">#DDDDDD</color>
<color name="iron">#F6F8Fa</color>
<color name="textPrimary">#303030</color>
</resources> </resources>

8
UI/AndroidApp/flavoursWithoutBorders/app/src/main/res/values/strings.xml

@ -16,9 +16,15 @@
<string name="sign_up_hint_birthday">Birthday</string> <string name="sign_up_hint_birthday">Birthday</string>
<string name="sign_up_btn_sign_up">SIGN UP</string> <string name="sign_up_btn_sign_up">SIGN UP</string>
<string name="sign_up_btn_go_to_login">or login</string> <string name="sign_up_btn_go_to_login">or login</string>
<string name="title_activity_main">Main</string> <string name="sign_up_birthday_placeholder">%1$d-%2$d-%3$d</string>
<!-- Drawer -->
<string name="drawer_home">Home</string>
<string name="drawer_logout">Logout</string>
<string name="drawer_login">Login</string>
<!-- Main --> <!-- Main -->
<string name="main_activity_title">Main</string>
<string name="main_toolbar_menu_filter">Filter results</string> <string name="main_toolbar_menu_filter">Filter results</string>
<string name="main_toolbar_menu_map">Show in map</string> <string name="main_toolbar_menu_map">Show in map</string>

1
UI/AndroidApp/flavoursWithoutBorders/build.gradle

@ -19,6 +19,7 @@ allprojects {
repositories { repositories {
google() google()
jcenter() jcenter()
maven { url "https://jitpack.io" }
} }
} }

Loading…
Cancel
Save