Added detailed highscore ranking

This commit is contained in:
Caesar2011
2017-04-16 12:10:22 +02:00
parent fcb1ca3aa0
commit 976d74676c
31 changed files with 997 additions and 148 deletions

2
.idea/misc.xml generated
View File

@@ -29,7 +29,7 @@
</value> </value>
</option> </option>
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.8 (1)" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.8 (2)" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
<component name="ProjectType"> <component name="ProjectType">

View File

@@ -28,5 +28,6 @@ dependencies {
compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1' compile 'com.android.support:design:25.3.1'
compile 'com.android.support:support-v4:25.3.1' compile 'com.android.support:support-v4:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
} }

View File

@@ -11,22 +11,26 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity <activity
android:launchMode="singleInstance"
android:name=".MainActivity" android:name=".MainActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:windowSoftInputMode="adjustResize" android:launchMode="singleInstance"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<data android:scheme="postgrachelor"
android:host="postgrachelor" /> <data
android:host="postgrachelor"
android:scheme="postgrachelor" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".HighscoreActivity"></activity>
</application> </application>
</manifest> </manifest>

View File

@@ -0,0 +1,58 @@
package de.hwr_berlin.it14.postgrachelor;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.TextView;
import de.hwr_berlin.it14.postgrachelor.Utils.Conversion;
import de.hwr_berlin.it14.postgrachelor.Utils.HighscoreAdapter;
public class HighscoreActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_highscore);
if (getActionBar() != null) {
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setDisplayShowHomeEnabled(true);
} else if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
// Get the Intent that started this activity and extract the string
Intent intent = getIntent();
String categoryID = intent.getStringExtra("CategoryID");
String categoryName = intent.getStringExtra("CategoryName");
String categoryCount = intent.getStringExtra("CategoryCount");
ListView listView = (ListView) findViewById(R.id.category_listview);
HighscoreAdapter adapter = new HighscoreAdapter(Conversion.strToInt(categoryCount, 2), Conversion.strToInt(categoryID, -1), getApplicationContext());
listView.setAdapter(adapter);
setTitle(categoryName);
adapter.notifyDataSetChanged();
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
@Override
public boolean onNavigateUp() {
onBackPressed();
return true;
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
}
}

View File

@@ -1,11 +1,13 @@
package de.hwr_berlin.it14.postgrachelor; package de.hwr_berlin.it14.postgrachelor;
import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.app.Fragment; import android.app.Fragment;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
@@ -55,6 +57,11 @@ public class LoginFragment extends Fragment {
} catch (NotInstantiatedException e) { } catch (NotInstantiatedException e) {
e.printStackTrace(); e.printStackTrace();
} }
InputMethodManager mgr = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(v.getWindowToken(), 0);
} }
}); });

View File

@@ -3,6 +3,7 @@ package de.hwr_berlin.it14.postgrachelor;
import android.app.FragmentManager; import android.app.FragmentManager;
import android.app.FragmentTransaction; import android.app.FragmentTransaction;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log; import android.util.Log;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
@@ -10,6 +11,7 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import de.hwr_berlin.it14.postgrachelor.Exceptions.NotInstantiatedException; import de.hwr_berlin.it14.postgrachelor.Exceptions.NotInstantiatedException;
import de.hwr_berlin.it14.postgrachelor.Exceptions.NotLoggedInException;
import de.hwr_berlin.it14.postgrachelor.Services.GameService; import de.hwr_berlin.it14.postgrachelor.Services.GameService;
import de.hwr_berlin.it14.postgrachelor.Services.HighscoreService; import de.hwr_berlin.it14.postgrachelor.Services.HighscoreService;
import de.hwr_berlin.it14.postgrachelor.Services.LoginService; import de.hwr_berlin.it14.postgrachelor.Services.LoginService;
@@ -24,6 +26,7 @@ public class MainActivity extends AppCompatActivity {
} }
private static final String NAME = "MainActivity"; private static final String NAME = "MainActivity";
private int fragmentState = 0;
private FragmentManager myFragmentManager; private FragmentManager myFragmentManager;
private MainFragment mainFragment; private MainFragment mainFragment;
private LoginFragment loginFragment; private LoginFragment loginFragment;
@@ -33,6 +36,7 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Log.d("Activity fragment", "create"); Log.d("Activity fragment", "create");
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
@@ -45,20 +49,27 @@ public class MainActivity extends AppCompatActivity {
questionEndFragment = QuestionEndFragment.newInstance(); questionEndFragment = QuestionEndFragment.newInstance();
questionFragment = QuestionFragment.newInstance(); questionFragment = QuestionFragment.newInstance();
LoginService.instantiate(this);
HighscoreService.instantiate(this); if (savedInstanceState != null) {
GameService.initialize(this); this.fragmentState = savedInstanceState.getInt("selected fragment");
}
} }
@Override @Override
protected void onStart() { protected void onStart() {
super.onStart(); super.onStart();
final MainActivity that = this; final MainActivity that = this;
LoginService.addLoginEventListener(NAME, new LoginService.OnLoginEventListener() { LoginService.addLoginEventListener(NAME, new LoginService.OnLoginEventListener() {
@Override @Override
public void onLoginEvent(String name, String uid) { public void onLoginEvent(String name, String uid) {
Log.d("Activity fragment", "onLogin - name: " + name + " - uid: " + uid); Log.d("Activity fragment", "onLogin - name: " + name + " - uid: " + uid);
that.selectFragment(FragmentState.MAIN); that.selectFragment(FragmentState.MAIN);
try {
HighscoreService.updateHighscores();
} catch (NotInstantiatedException | NotLoggedInException e) {
e.printStackTrace();
}
} }
@Override @Override
@@ -75,11 +86,32 @@ public class MainActivity extends AppCompatActivity {
that.selectFragment(FragmentState.QUESTION); that.selectFragment(FragmentState.QUESTION);
else if (previous == GameService.States.ON_HOLD_RESULT && state == GameService.States.END) { else if (previous == GameService.States.ON_HOLD_RESULT && state == GameService.States.END) {
that.selectFragment(FragmentState.QUESTION_END); that.selectFragment(FragmentState.QUESTION_END);
try {
HighscoreService.updateHighscores();
} catch (NotInstantiatedException | NotLoggedInException e) {
e.printStackTrace();
}
} else if (state == GameService.States.PAUSED || state == GameService.States.END) { } else if (state == GameService.States.PAUSED || state == GameService.States.END) {
that.selectFragment(FragmentState.MAIN); that.selectFragment(FragmentState.MAIN);
} }
} }
}); });
HighscoreService.instantiate(this);
LoginService.instantiate(this);
GameService.initialize(this);
//this.selectFragment(this.fragmentState);
}
@Override
public void onBackPressed()
{
this.selectFragment(FragmentState.MAIN);
try {
HighscoreService.updateHighscores();
} catch (NotInstantiatedException | NotLoggedInException e) {
e.printStackTrace();
}
} }
@Override @Override
@@ -105,6 +137,7 @@ public class MainActivity extends AppCompatActivity {
} }
private void selectFragment(int item) { private void selectFragment(int item) {
this.fragmentState = item;
// Handle navigation view item clicks here. // Handle navigation view item clicks here.
try { try {
boolean isLoggedIn = LoginService.isLoggedIn(); boolean isLoggedIn = LoginService.isLoggedIn();
@@ -149,4 +182,10 @@ public class MainActivity extends AppCompatActivity {
} }
} }
} }
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("selected fragment", this.fragmentState);
super.onSaveInstanceState(savedInstanceState);
}
} }

View File

@@ -1,8 +1,10 @@
package de.hwr_berlin.it14.postgrachelor; package de.hwr_berlin.it14.postgrachelor;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.app.Fragment; import android.app.Fragment;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayout; import android.support.v7.widget.GridLayout;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -12,6 +14,8 @@ import android.widget.ImageButton;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import org.json.JSONObject;
import java.util.Iterator; import java.util.Iterator;
import java.util.Locale; import java.util.Locale;
@@ -22,6 +26,7 @@ import de.hwr_berlin.it14.postgrachelor.Services.HighscoreService;
import de.hwr_berlin.it14.postgrachelor.Services.LoginService; import de.hwr_berlin.it14.postgrachelor.Services.LoginService;
import de.hwr_berlin.it14.postgrachelor.Types.Highscores; import de.hwr_berlin.it14.postgrachelor.Types.Highscores;
import de.hwr_berlin.it14.postgrachelor.Types.HighscoresCategories; import de.hwr_berlin.it14.postgrachelor.Types.HighscoresCategories;
import de.hwr_berlin.it14.postgrachelor.Utils.JsonRequestPG;
/** /**
* A simple {@link Fragment} subclass. * A simple {@link Fragment} subclass.
@@ -30,9 +35,11 @@ import de.hwr_berlin.it14.postgrachelor.Types.HighscoresCategories;
*/ */
public class MainFragment extends Fragment { public class MainFragment extends Fragment {
public static final String NAME = "MAIN_FRAGMENT"; public static final String NAME = "MAIN_FRAGMENT";
private boolean listenersRegistered;
public MainFragment() { public MainFragment() {
// Required empty public constructor // Required empty public constructor
this.listenersRegistered = false;
} }
/** /**
@@ -42,6 +49,7 @@ public class MainFragment extends Fragment {
* @return A new instance of fragment MainFragment. * @return A new instance of fragment MainFragment.
*/ */
public static MainFragment newInstance() { public static MainFragment newInstance() {
Log.d(NAME, "newInstance");
MainFragment fragment = new MainFragment(); MainFragment fragment = new MainFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
fragment.setArguments(args); fragment.setArguments(args);
@@ -51,17 +59,29 @@ public class MainFragment extends Fragment {
@Override @Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
Log.d(NAME, "onCreateView "+this.listenersRegistered);
final View view = inflater.inflate(R.layout.fragment_main, container, false); final View view = inflater.inflate(R.layout.fragment_main, container, false);
final View.OnClickListener categoryClick= new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), HighscoreActivity.class);
intent.putExtra("CategoryID", v.getTag(R.id.category_id).toString());
intent.putExtra("CategoryName", v.getTag(R.id.category_name).toString());
intent.putExtra("CategoryCount", v.getTag(R.id.category_count).toString());
startActivity(intent);
}
};
LoginService.addLoginEventListener(NAME, new LoginService.OnLoginEventListener() { LoginService.addLoginEventListener(NAME, new LoginService.OnLoginEventListener() {
@Override @Override
public void onLoginEvent(String name, String uid) { public void onLoginEvent(String name, String uid) {
TextView textView = (TextView) view.findViewById(R.id.fragment_main_status).findViewById(R.id.fragment_user_name); TextView textView = (TextView) view.findViewById(R.id.fragment_main_status).findViewById(R.id.fragment_user_name);
textView.setText(name); textView.setText(name);
Log.d(NAME, "onLogin"); Log.d(NAME, "onLogin", new Throwable());
} }
@Override public void onLogoutEvent(int status, String message) {} @Override
public void onLogoutEvent(int status, String message) {
}
}); });
HighscoreService.addHighscoreUpdateEventListener(new HighscoreService.OnHighscoreUpdateEventListener() { HighscoreService.addHighscoreUpdateEventListener(new HighscoreService.OnHighscoreUpdateEventListener() {
@Override @Override
@@ -101,6 +121,11 @@ public class MainFragment extends Fragment {
while (iterator.hasNext()) { while (iterator.hasNext()) {
HighscoresCategories category = iterator.next(); HighscoresCategories category = iterator.next();
categoryView = inflater.inflate(R.layout.fragment_main_category, gridLayoutCategories, false); categoryView = inflater.inflate(R.layout.fragment_main_category, gridLayoutCategories, false);
categoryView.setTag(R.id.category_id, category.getId());
categoryView.setTag(R.id.category_name, category.getName());
// TODO automated count
categoryView.setTag(R.id.category_count, scores.getAll());
categoryView.setOnClickListener(categoryClick);
textView = (TextView) categoryView.findViewById(R.id.textViewCategory); textView = (TextView) categoryView.findViewById(R.id.textViewCategory);
textView.setText(category.getName()); textView.setText(category.getName());
@@ -108,8 +133,10 @@ public class MainFragment extends Fragment {
textView.setText(String.format(Locale.getDefault(), "%1$d", category.getScore())); textView.setText(String.format(Locale.getDefault(), "%1$d", category.getScore()));
catProgress = (ProgressBar) categoryView.findViewById(R.id.progressBarCategory); catProgress = (ProgressBar) categoryView.findViewById(R.id.progressBarCategory);
catProgress.setProgress(scores.getAll()-category.getPlace()+1); Log.d(NAME, "all: " + scores.getAll() + " - place: " + category.getPlace() + " - prog: " + (scores.getAll() - category.getPlace() + 1));
catProgress.setProgress(0);
catProgress.setMax(scores.getAll()); catProgress.setMax(scores.getAll());
catProgress.setProgress(scores.getAll() - category.getPlace() + 1);
gridLayoutCategories.addView(categoryView); gridLayoutCategories.addView(categoryView);
param = new GridLayout.LayoutParams(GridLayout.spec(GridLayout.UNDEFINED, 1f), GridLayout.spec(GridLayout.UNDEFINED, 1f)); param = new GridLayout.LayoutParams(GridLayout.spec(GridLayout.UNDEFINED, 1f), GridLayout.spec(GridLayout.UNDEFINED, 1f));
@@ -120,6 +147,10 @@ public class MainFragment extends Fragment {
userStatusTextViewScore.setText(String.format(Locale.getDefault(), "%1$d", scores.getScore())); userStatusTextViewScore.setText(String.format(Locale.getDefault(), "%1$d", scores.getScore()));
userStatusProgressBar.setMax(scores.getAll()); userStatusProgressBar.setMax(scores.getAll());
userStatusProgressBar.setProgress(scores.getAll() - scores.getPlace() + 1); userStatusProgressBar.setProgress(scores.getAll() - scores.getPlace() + 1);
userStatusProgressBar.setTag(R.id.category_id, -1);
userStatusProgressBar.setTag(R.id.category_name, view.getResources().getString(R.string.app_name));
userStatusProgressBar.setTag(R.id.category_count, scores.getAll());
userStatusProgressBar.setOnClickListener(categoryClick);
} }
} }
}); });
@@ -142,6 +173,7 @@ public class MainFragment extends Fragment {
} }
} }
}); });
this.listenersRegistered = true;
// Inflate the layout for this fragment // Inflate the layout for this fragment
View fragmentMainGameView = view.findViewById(R.id.fragment_main_game); View fragmentMainGameView = view.findViewById(R.id.fragment_main_game);
@@ -162,6 +194,46 @@ public class MainFragment extends Fragment {
} }
}); });
// Lookup the swipe container view
final SwipeRefreshLayout swipeContainer = (SwipeRefreshLayout) view.findViewById(R.id.swipeContainer);
// Setup refresh listener which triggers new data loading
swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
try {
HighscoreService.updateHighscores(new JsonRequestPG.AsyncResponse() {
@Override
public void processFinish(JSONObject data) {
swipeContainer.setRefreshing(false);
}
@Override
public void processError(int status, String message) {
}
});
} catch (NotInstantiatedException ignored) {
} catch (NotLoggedInException e) {
try {
LoginService.setLogout(15999, "Not logged in");
} catch (NotInstantiatedException ignored) {
}
}
}
});
// Configure the refreshing colors
swipeContainer.setColorSchemeResources(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
return view; return view;
} }

View File

@@ -7,6 +7,9 @@ import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
@@ -20,6 +23,7 @@ import de.hwr_berlin.it14.postgrachelor.Types.Question;
import de.hwr_berlin.it14.postgrachelor.Types.QuestionResult; import de.hwr_berlin.it14.postgrachelor.Types.QuestionResult;
import de.hwr_berlin.it14.postgrachelor.Types.Timings; import de.hwr_berlin.it14.postgrachelor.Types.Timings;
import de.hwr_berlin.it14.postgrachelor.Utils.Conversion; import de.hwr_berlin.it14.postgrachelor.Utils.Conversion;
import de.hwr_berlin.it14.postgrachelor.Utils.ReverseInterpolator;
/** /**
@@ -50,7 +54,10 @@ public class QuestionFragment extends Fragment {
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
Log.d(NAME, "onCreateView");
final View view = inflater.inflate(R.layout.fragment_question, container, false); final View view = inflater.inflate(R.layout.fragment_question, container, false);
View layout = view.findViewById(R.id.layout_fragment_question);
final TextView questionTitleView = (TextView) view.findViewById(R.id.questionTitle); final TextView questionTitleView = (TextView) view.findViewById(R.id.questionTitle);
final TextView questionCategoryView = (TextView) view.findViewById(R.id.questionCategory); final TextView questionCategoryView = (TextView) view.findViewById(R.id.questionCategory);
@@ -65,13 +72,30 @@ public class QuestionFragment extends Fragment {
(Button) view.findViewById(R.id.questionAnswer3) (Button) view.findViewById(R.id.questionAnswer3)
}; };
// Inflate the layout for this fragment // Inflate the layout for this fragment
layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (GameService.isNextNeeded())
try {
GameService.runNext();
} catch (NotInstantiatedException e) {
e.printStackTrace();
}
}
});
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
questionAnswerViews[i].setTag(i); questionAnswerViews[i].setTag(i);
questionAnswerViews[i].setOnClickListener(new View.OnClickListener() { questionAnswerViews[i].setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (GameService.isNextNeeded()) {
try {
GameService.runNext();
} catch (NotInstantiatedException e) {
e.printStackTrace();
}
} else {
try { try {
if (GameService.getState() != GameService.States.ON_HOLD_RESULT) if (GameService.getState() != GameService.States.ON_HOLD_RESULT)
GameService.answer((int) v.getTag()); GameService.answer((int) v.getTag());
@@ -79,6 +103,7 @@ public class QuestionFragment extends Fragment {
e.printStackTrace(); e.printStackTrace();
} }
} }
}
}); });
} }
GameService.addResultEventListener(NAME, new GameService.OnResultEventListener() { GameService.addResultEventListener(NAME, new GameService.OnResultEventListener() {
@@ -105,6 +130,12 @@ public class QuestionFragment extends Fragment {
totalView.setText(Conversion.intToStr(result.getTotal())); totalView.setText(Conversion.intToStr(result.getTotal()));
scoreView.setText(Conversion.intToStr(result.getScore())); scoreView.setText(Conversion.intToStr(result.getScore()));
if (result.isCorrect()) {
Animation animation = AnimationUtils.loadAnimation(getActivity().getApplicationContext(), R.anim.scale_up);
animation.setInterpolator(new ReverseInterpolator(new AccelerateInterpolator()));
totalView.startAnimation(animation);
}
} }
} }
}); });

View File

@@ -6,8 +6,10 @@ import android.content.SharedPreferences;
import android.util.Log; import android.util.Log;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@@ -31,12 +33,14 @@ public class GameService {
private static final int GAME_TICK_INTERVAL = 100; private static final int GAME_TICK_INTERVAL = 100;
private static final int NEXT_QUESTION_DELAY = 1250; private static final int NEXT_QUESTION_DELAY = 1250;
private static final int QUESTION_COUNT = 10; private static final int QUESTION_COUNT = 10;
private static final String NAME = "SERVICE_GAME";
private static long startTime; private static long startTime;
private static long endTime; private static long endTime;
private static int answer; private static int answer;
private static Timer timer; private static Timer timer;
private static JSONObject data = null;
public static final class States { public static final class States {
private States() {} private States() {}
@@ -58,7 +62,7 @@ public class GameService {
private static final HashMap<String, OnResultEventListener> resultEventListeners = new HashMap<>(); private static final HashMap<String, OnResultEventListener> resultEventListeners = new HashMap<>();
private static final HashMap<String, OnGameEndEventListener> gameEndEventListeners = new HashMap<>(); private static final HashMap<String, OnGameEndEventListener> gameEndEventListeners = new HashMap<>();
private static final HashMap<String, OnTickEventListener> gameTickEventListeners = new HashMap<>(); private static final HashMap<String, OnTickEventListener> gameTickEventListeners = new HashMap<>();
private static int state = States.END; private static int state = States.UNINITIALIZED;
private static Question question = null; private static Question question = null;
private static QuestionResult result = null; private static QuestionResult result = null;
private static GameScores scores = null; private static GameScores scores = null;
@@ -89,6 +93,11 @@ public class GameService {
GameService.activity = activity; GameService.activity = activity;
GameService.settings = activity.getSharedPreferences(GameService.PREFS_NAME, 0); GameService.settings = activity.getSharedPreferences(GameService.PREFS_NAME, 0);
GameService.initialized = true; GameService.initialized = true;
try {
GameService.data = GameService.getNeededNext();
} catch (NotInstantiatedException e) {
e.printStackTrace();
}
emitNextQuestionEvent(); emitNextQuestionEvent();
emitGameEndEvent(); emitGameEndEvent();
@@ -156,8 +165,6 @@ public class GameService {
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")
public static void addTickEventListener(String key, OnTickEventListener onTickEventListener) { public static void addTickEventListener(String key, OnTickEventListener onTickEventListener) {
gameTickEventListeners.put(key, onTickEventListener); gameTickEventListeners.put(key, onTickEventListener);
if (GameService.initialized)
onTickEventListener.onTickEvent(GameService.getTimingsSave());
} }
private static Timings getTimingsSave() { private static Timings getTimingsSave() {
@@ -373,6 +380,8 @@ public class GameService {
} }
public static void answer(int id) throws NotInstantiatedException, NotLoggedInException, NoCurrentQuestionException { public static void answer(int id) throws NotInstantiatedException, NotLoggedInException, NoCurrentQuestionException {
if (GameService.isNextNeeded())
throw new IllegalStateException();
if (!GameService.initialized) if (!GameService.initialized)
throw new NotInstantiatedException(); throw new NotInstantiatedException();
final int state = GameService.getState(); final int state = GameService.getState();
@@ -384,10 +393,10 @@ public class GameService {
time = end - start; time = end - start;
id = GameService.getAnswer(id); id = GameService.getAnswer(id);
} else if (state == States.RUNNING) { } else if (state == States.RUNNING) {
GameService.setState(States.ON_HOLD_LOADING);
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
long start = GameService.getStartTime(); long start = GameService.getStartTime();
GameService.setEndTime(end); GameService.setEndTime(end);
GameService.setState(States.ON_HOLD_LOADING);
time = end - start; time = end - start;
GameService.setAnswer(id); GameService.setAnswer(id);
} else { } else {
@@ -412,26 +421,9 @@ public class GameService {
data_result.optInt("correctPos", 0), data_result.optInt("correctPos", 0),
data_result.optInt("total", 0) data_result.optInt("total", 0)
); );
GameService.setStateSave(States.ON_HOLD_RESULT);
GameService.setResultSave(result); GameService.setResultSave(result);
GameService.setNeededNextSave(data);
new android.os.Handler().postDelayed(new Runnable() { GameService.setStateSave(States.ON_HOLD_RESULT);
@Override
public void run() {
if (data.has("next")) {
JSONObject data_next = data.optJSONObject("next");
GameService.setQuestionSave(GameService.parseQuestion(data_next));
GameService.setStartTimeSave(System.currentTimeMillis());
GameService.setStateSave(States.RUNNING);
} else {
JSONObject data_end = data.optJSONObject("end");
GameService.setScoresSave(GameService.parseScores(data_end));
GameService.setStateSave(States.END);
GameService.unsetStartTimeSave();
GameService.unsetEndTimeSave();
}
}
}, GameService.NEXT_QUESTION_DELAY);
} }
@Override @Override
@@ -452,6 +444,7 @@ public class GameService {
if (!GameService.initialized) if (!GameService.initialized)
throw new NotInstantiatedException(); throw new NotInstantiatedException();
GameService.setNeededNext(null);
HashMap<String, String> params = new HashMap<>(); HashMap<String, String> params = new HashMap<>();
String uid; String uid;
uid = LoginService.getLoginUID(); uid = LoginService.getLoginUID();
@@ -487,6 +480,112 @@ public class GameService {
requester.execute(); requester.execute();
} }
private static void setNeededNext(JSONObject data) throws NotInstantiatedException {
GameService.data = data;
if (!GameService.initialized)
throw new NotInstantiatedException();
SharedPreferences.Editor editor = GameService.settings.edit();
if (data!=null && data.has("next")) {
data = data.optJSONObject("next");
JSONArray array = data.optJSONArray("answers");
editor.putString("nextCategoryName", data.optString("categoryName", ""));
editor.putInt("nextCategoryID", data.optInt("categoryID", 0));
editor.putString("nextQuestion", data.optString("question", ""));
editor.putString("nextAnswers0", array.optString(0, ""));
editor.putString("nextAnswers1", array.optString(1, ""));
editor.putString("nextAnswers2", array.optString(2, ""));
editor.putString("nextAnswers3", array.optString(3, ""));
} else {
editor.remove("nextCategoryName");
editor.remove("nextCategoryID");
editor.remove("nextQuestion");
editor.remove("nextAnswers0");
editor.remove("nextAnswers1");
editor.remove("nextAnswers2");
editor.remove("nextAnswers3");
}
if (data!=null && data.has("end")) {
data = data.optJSONObject("end");
editor.putInt("endScore", data.optInt("score", 0));
editor.putLong("endTime", data.optLong("time", 0));
} else {
editor.remove("endScore");
editor.remove("endTime");
}
editor.apply();
}
private static void setNeededNextSave(JSONObject data) {
try {
GameService.setNeededNext(data);
} catch (NotInstantiatedException e) {
e.printStackTrace();
}
}
private static JSONObject getNeededNext() throws NotInstantiatedException {
if (GameService.data == null) {
if (!GameService.initialized)
throw new NotInstantiatedException();
JSONObject data;
if (GameService.settings.contains("nextCategoryName")) {
data = new JSONObject();
try {
data.put("categoryName", GameService.settings.getString("nextCategoryName", ""));
data.put("categoryID", GameService.settings.getInt("nextCategoryID", 0));
data.put("question", GameService.settings.getString("nextQuestion", ""));
ArrayList<String> list = new ArrayList<>();
list.add(GameService.settings.getString("nextAnswers0", ""));
list.add(GameService.settings.getString("nextAnswers1", ""));
list.add(GameService.settings.getString("nextAnswers2", ""));
list.add(GameService.settings.getString("nextAnswers3", ""));
data.put("answers", new JSONArray(list));
data = (new JSONObject()).put("next", data);
} catch (JSONException e) {
data = null;
e.printStackTrace();
}
} else if (GameService.settings.contains("endScore")) {
data = new JSONObject();
try {
data.put("score", GameService.settings.getInt("endScore", 0));
data.put("time", GameService.settings.getLong("endTime", 0));
data = (new JSONObject()).put("end", data);
} catch (JSONException e) {
data = null;
e.printStackTrace();
}
} else {
data = null;
}
GameService.data = data;
}
return GameService.data;
}
public static boolean isNextNeeded() {
return GameService.data != null;
}
public static void runNext() throws IllegalStateException, NotInstantiatedException {
JSONObject data = GameService.getNeededNext();
if (data == null)
throw new IllegalStateException();
if (data.has("next")) {
JSONObject data_next = data.optJSONObject("next");
GameService.setQuestionSave(GameService.parseQuestion(data_next));
GameService.setStartTimeSave(System.currentTimeMillis());
GameService.setStateSave(States.RUNNING);
} else {
JSONObject data_end = data.optJSONObject("end");
GameService.setScoresSave(GameService.parseScores(data_end));
GameService.setStateSave(States.END);
GameService.unsetStartTimeSave();
GameService.unsetEndTimeSave();
}
GameService.setNeededNext(null);
}
private static void setQuestion(Question question) throws NotInstantiatedException { private static void setQuestion(Question question) throws NotInstantiatedException {
if (!initialized) if (!initialized)
throw new NotInstantiatedException(); throw new NotInstantiatedException();
@@ -528,8 +627,9 @@ public class GameService {
int previous = GameService.getState(); int previous = GameService.getState();
GameService.state = state; GameService.state = state;
SharedPreferences.Editor editor = GameService.settings.edit(); SharedPreferences.Editor editor = GameService.settings.edit();
if (state==States.UNINITIALIZED) if (state!=States.UNINITIALIZED) {
editor.putInt("gameState", state); editor.putInt("gameState", state);
}
else else
editor.remove("gameState"); editor.remove("gameState");
editor.apply(); editor.apply();

View File

@@ -15,6 +15,8 @@ import de.hwr_berlin.it14.postgrachelor.Exceptions.NotInstantiatedException;
import de.hwr_berlin.it14.postgrachelor.Exceptions.NotLoggedInException; import de.hwr_berlin.it14.postgrachelor.Exceptions.NotLoggedInException;
import de.hwr_berlin.it14.postgrachelor.Types.GameScores; import de.hwr_berlin.it14.postgrachelor.Types.GameScores;
import de.hwr_berlin.it14.postgrachelor.Types.Highscores; import de.hwr_berlin.it14.postgrachelor.Types.Highscores;
import de.hwr_berlin.it14.postgrachelor.Types.HighscoresUser;
import de.hwr_berlin.it14.postgrachelor.Utils.Conversion;
import de.hwr_berlin.it14.postgrachelor.Utils.JsonRequestPG; import de.hwr_berlin.it14.postgrachelor.Utils.JsonRequestPG;
/** /**
@@ -24,6 +26,7 @@ import de.hwr_berlin.it14.postgrachelor.Utils.JsonRequestPG;
public class HighscoreService { public class HighscoreService {
private static final String NAME = "HighscoreService"; private static final String NAME = "HighscoreService";
private static final long MIN_REFRESH_RATE = 1000;
//private static final String PREFS_NAME = "PrefsHighscore"; //private static final String PREFS_NAME = "PrefsHighscore";
//private static SharedPreferences settings = null; //private static SharedPreferences settings = null;
private static Highscores latestScores = null; private static Highscores latestScores = null;
@@ -31,6 +34,7 @@ public class HighscoreService {
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
private static Activity activity = null; private static Activity activity = null;
private static final ArrayList<OnHighscoreUpdateEventListener> highscoreUpdateEventListeners = new ArrayList<>(); private static final ArrayList<OnHighscoreUpdateEventListener> highscoreUpdateEventListeners = new ArrayList<>();
private static long lastUpdate = 0;
public interface OnHighscoreUpdateEventListener { public interface OnHighscoreUpdateEventListener {
void onHighscoreUpdateEvent(Highscores scores); void onHighscoreUpdateEvent(Highscores scores);
@@ -51,34 +55,6 @@ public class HighscoreService {
//settings = activity.getSharedPreferences(PREFS_NAME, 0); //settings = activity.getSharedPreferences(PREFS_NAME, 0);
HighscoreService.activity = activity; HighscoreService.activity = activity;
instantiated = true; instantiated = true;
LoginService.addLoginEventListener(NAME, new LoginService.OnLoginEventListener() {
@Override
public void onLoginEvent(String name, String uid) {
try {
HighscoreService.updateHighscores();
} catch (NotInstantiatedException | NotLoggedInException e) {
e.printStackTrace();
HighscoreService.setLatestScores(null);
}
}
@Override
public void onLogoutEvent(int status, String message) {
HighscoreService.setLatestScores(null);
}
});
GameService.addGameEndEventListener(NAME, new GameService.OnGameEndEventListener() {
@Override
public void onGameEndEvent(GameScores scores) {
try {
HighscoreService.updateHighscores();
} catch (NotInstantiatedException | NotLoggedInException e) {
e.printStackTrace();
HighscoreService.setLatestScores(null);
}
}
});
} }
public static boolean available() { public static boolean available() {
@@ -94,7 +70,14 @@ public class HighscoreService {
emitHighscoreUpdateEvent(); emitHighscoreUpdateEvent();
} }
private static void updateHighscores() throws NotInstantiatedException, NotLoggedInException { public static void updateHighscores() throws NotInstantiatedException, NotLoggedInException {
HighscoreService.updateHighscores(null);
}
public static void updateHighscores(final JsonRequestPG.AsyncResponse asyncResponse) throws NotInstantiatedException, NotLoggedInException {
//if (lastUpdate >= System.currentTimeMillis()-MIN_REFRESH_RATE)
// return;
//lastUpdate = System.currentTimeMillis();
if (!instantiated) if (!instantiated)
throw new NotInstantiatedException(); throw new NotInstantiatedException();
@@ -105,9 +88,6 @@ public class HighscoreService {
JsonRequestPG requester = new JsonRequestPG("highscores.php", params, activity, new JsonRequestPG.AsyncResponse() { JsonRequestPG requester = new JsonRequestPG("highscores.php", params, activity, new JsonRequestPG.AsyncResponse() {
@Override @Override
public void processFinish(JSONObject output) { public void processFinish(JSONObject output) {
Log.d("Activity fragment", "output");
Log.d("Activity fragment", output.toString());
// never reached if not instantiated // never reached if not instantiated
Highscores result = new Highscores( Highscores result = new Highscores(
output.optInt("score", 0), output.optInt("score", 0),
@@ -132,6 +112,10 @@ public class HighscoreService {
} }
} }
setLatestScores(result); setLatestScores(result);
if (asyncResponse != null) {
asyncResponse.processFinish(output);
}
} }
@Override @Override
@@ -144,8 +128,57 @@ public class HighscoreService {
e.printStackTrace(); e.printStackTrace();
} }
} }
if (asyncResponse != null) {
asyncResponse.processError(status, message);
}
} }
}); });
requester.execute(); requester.execute();
} }
public static ArrayList<HighscoresUser> getHighscoreDetailsSync(final int limit, int offset, int category, final JsonRequestPG.AsyncResponse asyncResponse) {
HashMap<String, String> params = new HashMap<>();
if (limit >= 0)
params.put("limit", Conversion.intToStr(limit));
if (offset >= 0)
params.put("offset", Conversion.intToStr(offset));
if (category >= 0)
params.put("category", Conversion.intToStr(category));
final ArrayList<HighscoresUser> highscoresUsers = new ArrayList<>();
JsonRequestPG requester = new JsonRequestPG("allhighscores.php", params, activity, new JsonRequestPG.AsyncResponse() {
@Override
public void processFinish(JSONObject output) {
if (output != null) {
JSONArray array = output.optJSONArray("array");
if (array != null) {
for (int i = 0; i < array.length(); i++) {
JSONObject objectItem = array.optJSONObject(i);
if (objectItem != null) {
highscoresUsers.add(new HighscoresUser(
objectItem.optString("name", "A Random User"),
objectItem.optInt("score"),
objectItem.optInt("place")
));
} else {
highscoresUsers.add(null);
}
}
}
}
if (asyncResponse != null) {
asyncResponse.processFinish(output);
}
}
@Override
public void processError(int status, String message) {
if (asyncResponse != null) {
asyncResponse.processError(status, message);
}
}
});
requester.executeSync();
return highscoresUsers;
}
} }

View File

@@ -40,7 +40,7 @@ public class LoginService {
e.printStackTrace(); e.printStackTrace();
} }
} else { } else {
onLoginEventListener.onLogoutEvent(-6, null); //onLoginEventListener.onLogoutEvent(-6, null);
} }
} }
@@ -118,7 +118,7 @@ public class LoginService {
emitLoginEvent(name, uid); emitLoginEvent(name, uid);
} }
static void setLogout(int status, String message) throws NotInstantiatedException { public static void setLogout(int status, String message) throws NotInstantiatedException {
if (!instantiated) if (!instantiated)
throw new NotInstantiatedException(); throw new NotInstantiatedException();
SharedPreferences.Editor editor = settings.edit(); SharedPreferences.Editor editor = settings.edit();

View File

@@ -0,0 +1,37 @@
package de.hwr_berlin.it14.postgrachelor.Types;
/**
* Created by Sebastian on 11.04.2017.
*/
public class HighscoresUser extends Requestable {
private final String name;
private final int score;
private final int place;
public HighscoresUser(String name, int score, int place) {
this.name = name;
this.score = score;
this.place = place;
this.unrequested();
}
public HighscoresUser() {
super();
this.name = "";
this.score = 0;
this.place = 0;
}
public String getName() {
return name;
}
public int getScore() {
return score;
}
public int getPlace() {
return place;
}
}

View File

@@ -0,0 +1,25 @@
package de.hwr_berlin.it14.postgrachelor.Types;
/**
* Created by Sebastian on 12.04.2017.
*/
public class Requestable {
private long requested;
public Requestable() {
this.requested();
}
public boolean isRequested() {
return this.requested != 0;
}
protected void unrequested() {
this.requested = 0;
}
protected void requested() {
this.requested = System.currentTimeMillis();
}
}

View File

@@ -0,0 +1,151 @@
package de.hwr_berlin.it14.postgrachelor.Utils;
import android.os.AsyncTask;
import android.test.suitebuilder.annotation.Suppress;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.ArrayList;
import de.hwr_berlin.it14.postgrachelor.Types.Requestable;
/**
* Created by Sebastian on 10.04.2017.
*/
public abstract class AsyncAdapter<T extends Requestable> extends BaseAdapter {
private int count;
private ArrayList<Requestable> items;
private AsyncAdapter() {}
public AsyncAdapter(int count) {
super();
items = new ArrayList<>();
this.setCount(count);
}
@Override
public int getCount() {
return this.count;
}
@Override
public Integer getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = this.inflateView(position, parent);
convertView = this.clearView(position, convertView);
this.loadView(position, convertView, parent);
return convertView;
}
@SuppressWarnings("unchecked")
private void loadView(int position, View convertView, ViewGroup parent) {
if (position >= this.items.size() || this.items.get(position) == null) {
AsyncRequest request = new AsyncRequest(position, convertView);
request.execute();
} else if (!this.items.get(position).isRequested()) {
this.fillView((T) this.items.get(position), position, convertView);
}
}
abstract void fillView(T item, int position, View convertView);
abstract View inflateView(int position, ViewGroup parent);
abstract View clearView(int position, View convertView);
abstract ListSequence<T> getAsyncListSequence(int position);
private void setCount(int count) {
this.count = count;
}
protected abstract int getRequestedLength(int position);
class AsyncRequest extends AsyncTask<Void, Void, ListSequence<T>> {
private final int position;
private View convertView;
AsyncRequest(int position, View convertView) {
this.position = position;
this.convertView = convertView;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
for (int i = items.size(); i < this.position; i++) {
items.add(null);
}
for (int i = this.position; i < this.position+getRequestedLength(this.position); i++) {
if (i < items.size())
items.set(i, new Requestable());
else
items.add(new Requestable());
}
}
@Override
protected ListSequence<T> doInBackground(Void... arg0) {
return getAsyncListSequence(position);
}
@Override
@SuppressWarnings("unchecked")
protected void onPostExecute(ListSequence<T> result) {
super.onPostExecute(result);
int start = result.getStart();
ArrayList<T> list = result.getItems();
for (int i = items.size(); i < start; i++) {
items.add(null);
}
while (list.size() > 0) {
if (start < items.size())
items.set(start, list.remove(0));
else
items.add(list.remove(0));
start++;
}
if (position < items.size())
fillView((T) items.get(position), position, convertView);
notifyDataSetChanged();
}
}
class ListSequence<T> {
private final int start;
private final ArrayList<T> items;
public ListSequence(int start, int end, ArrayList<T> items) {
this.start = start;
this.items = items;
}
public int getStart() {
return start;
}
public ArrayList<T> getItems() {
return items;
}
}
}

View File

@@ -34,4 +34,12 @@ public class Conversion {
private static String intToStr(int i, int padding, char padChar) { private static String intToStr(int i, int padding, char padChar) {
return Conversion.intToStr(i, padding).replace(' ', padChar); return Conversion.intToStr(i, padding).replace(' ', padChar);
} }
public static int strToInt(String string, int defValue) {
try{
return Integer.parseInt(string);
}catch(NumberFormatException e){
return defValue;
}
}
} }

View File

@@ -0,0 +1,82 @@
package de.hwr_berlin.it14.postgrachelor.Utils;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import de.hwr_berlin.it14.postgrachelor.R;
import de.hwr_berlin.it14.postgrachelor.Services.HighscoreService;
import de.hwr_berlin.it14.postgrachelor.Types.HighscoresUser;
/**
* Created by Sebastian on 11.04.2017.
*/
public class HighscoreAdapter extends AsyncAdapter<HighscoresUser> {
private Context context;
private int category;
public HighscoreAdapter(int count, int category, Context context) {
super(count);
this.category = category;
this.context = context;
}
@Override
void fillView(HighscoresUser item, int position, View convertView) {
if (item == null) {
return;
}
TextView userNameView = (TextView) convertView.findViewById(R.id.tvName);
TextView userPlaceView = (TextView) convertView.findViewById(R.id.tvPlace);
TextView userScoreView = (TextView) convertView.findViewById(R.id.tvScore);
if (userNameView != null) {
userNameView.setText(item.getName());
}
if (userPlaceView != null) {
userPlaceView.setText(convertView.getContext().getResources().getString(R.string.place, Conversion.intToStr(item.getPlace())));
}
if (userScoreView != null) {
userScoreView.setText(Conversion.intToStr(item.getScore()));
}
}
@Override
View inflateView(int position, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return inflater.inflate(R.layout.adapter_highscore_details, parent, false);
}
@Override
View clearView(int position, View convertView) {
TextView userNameView = (TextView) convertView.findViewById(R.id.tvName);
TextView userPlaceView = (TextView) convertView.findViewById(R.id.tvPlace);
TextView userScoreView = (TextView) convertView.findViewById(R.id.tvScore);
if (userNameView != null) {
userNameView.setText(R.string.loading);
}
if (userPlaceView != null) {
userPlaceView.setText(convertView.getContext().getResources().getString(R.string.place, Conversion.intToStr(position+1)));
}
if (userScoreView != null) {
userScoreView.setText("");
}
return convertView;
}
@Override
ListSequence<HighscoresUser> getAsyncListSequence(int position) {
int limit = this.getRequestedLength(position);
ArrayList<HighscoresUser> items = HighscoreService.getHighscoreDetailsSync(limit, position, this.category, null);
return new ListSequence<>(position, position+items.size()-1, items);
}
@Override
protected int getRequestedLength(int position) {
return Math.min(10, getCount()-position);
}
}

View File

@@ -36,12 +36,18 @@ abstract class JsonRequest extends AsyncTask<Void, Void, JSONObject> {
this.path = path; this.path = path;
this.params = params; this.params = params;
this.activity = activity; this.activity = activity;
Log.d("fragment, JSONRequest", connectionURL+path); Log.d("JSONRequest create", connectionURL+path);
} }
@SuppressWarnings("SameReturnValue") @SuppressWarnings("SameReturnValue")
protected abstract String getConnectionURL(); protected abstract String getConnectionURL();
public JSONObject executeSync() {
JSONObject result = this.doInBackground();
Log.d("JSONRequest excecute", result.toString());
return result;
}
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
super.onPreExecute(); super.onPreExecute();
@@ -68,6 +74,7 @@ abstract class JsonRequest extends AsyncTask<Void, Void, JSONObject> {
if (url == null) if (url == null)
return new JSONObject(); return new JSONObject();
try { try {
Log.d("JSONRequest url", url.toString());
urlConnection = (HttpURLConnection) url.openConnection(); urlConnection = (HttpURLConnection) url.openConnection();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View File

@@ -4,8 +4,11 @@ import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
/** /**
@@ -15,7 +18,7 @@ import java.util.HashMap;
public class JsonRequestPG extends JsonRequest { public class JsonRequestPG extends JsonRequest {
private final AsyncResponse delegate; private final ArrayList<AsyncResponse> delegates;
public interface AsyncResponse { public interface AsyncResponse {
void processFinish(JSONObject data); void processFinish(JSONObject data);
@@ -24,7 +27,53 @@ public class JsonRequestPG extends JsonRequest {
public JsonRequestPG(String path, HashMap<String, String> params, Activity activity, AsyncResponse delegate) { public JsonRequestPG(String path, HashMap<String, String> params, Activity activity, AsyncResponse delegate) {
super(path, params, activity); super(path, params, activity);
this.delegate = delegate; this.delegates = new ArrayList<>();
this.delegates.add(delegate);
}
private void processError(int status, String message) {
for (AsyncResponse delegate: delegates) {
delegate.processError(status, message);
}
}
private void processFinish(JSONObject data) {
for (AsyncResponse delegate: delegates) {
delegate.processFinish(data);
}
}
public JSONObject executeSync() {
JSONObject result = super.executeSync();
if (result == null) {
this.processError(-1, "Internal error occurred!");
return null;
}
JSONObject meta = result.optJSONObject("meta");
if (meta==null) {
this.processError(-2, "Invalid JSON: Meta tag not found!");
return null;
}
int status = meta.optInt("status", -3);
String message = meta.optString("message", "");
if (status != 0) {
this.processError(status, message);
return null;
}
JSONArray array = result.optJSONArray("data");
JSONObject data;
if (array != null) {
data = new JSONObject();
try {
data.put("array", array);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
data = result.optJSONObject("data");
}
this.processFinish(data);
return data;
} }
@Override @Override
@@ -36,12 +85,12 @@ public class JsonRequestPG extends JsonRequest {
protected void onPostExecute(JSONObject result) { protected void onPostExecute(JSONObject result) {
super.onPostExecute(result); super.onPostExecute(result);
if (result == null) { if (result == null) {
delegate.processError(-1, "Internal error occurred!"); this.processError(-1, "Internal error occurred!");
return; return;
} }
JSONObject meta = result.optJSONObject("meta"); JSONObject meta = result.optJSONObject("meta");
if (meta==null) { if (meta==null) {
delegate.processError(-2, "Invalid JSON: Meta tag not found!"); this.processError(-2, "Invalid JSON: Meta tag not found!");
return; return;
} }
int status = meta.optInt("status", -3); int status = meta.optInt("status", -3);
@@ -57,10 +106,21 @@ public class JsonRequestPG extends JsonRequest {
}) })
.setIcon(android.R.drawable.ic_dialog_alert) .setIcon(android.R.drawable.ic_dialog_alert)
.show(); .show();
delegate.processError(status, message); this.processError(status, message);
return; return;
} }
JSONObject data = result.optJSONObject("data"); JSONArray array = result.optJSONArray("data");
delegate.processFinish(data); JSONObject data;
if (array != null) {
data = new JSONObject();
try {
data.put("array", array);
} catch (JSONException e) {
e.printStackTrace();
}
} else {
data = result.optJSONObject("data");
}
this.processFinish(data);
} }
} }

View File

@@ -0,0 +1,35 @@
package de.hwr_berlin.it14.postgrachelor.Utils;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
/**
* Created by Sebastian on 08.04.2017.
*/
public class ReverseInterpolator implements Interpolator {
private final Interpolator delegate;
public ReverseInterpolator(Interpolator delegate){
this.delegate = delegate;
}
public ReverseInterpolator(){
this(new LinearInterpolator());
}
@Override
public float getInterpolation(float input) {
return this.delegate.getInterpolation(this.reverseInput(input));
}
/**
* Map value so 0-0.5 = 0-1 and 0.5-1 = 1-0
*/
private float reverseInput(float input){
if(input <= 0.5)
return input*2;
else
return Math.abs(input-1)*2;
}
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<scale
android:duration="500"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="2.0"
android:toYScale="2.0"
android:pivotX="100%"
android:pivotY="100%" >
</scale>
</set>

View File

@@ -0,0 +1,15 @@
<?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="de.hwr_berlin.it14.postgrachelor.HighscoreActivity">
<ListView
android:id="@+id/category_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/adapter_highscore_details" />
</android.support.constraint.ConstraintLayout>

View File

@@ -4,8 +4,7 @@
android:id="@+id/drawer_layout" android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true" android:fitsSystemWindows="true">
tools:openDrawer="start">
<include <include
layout="@layout/app_bar_main" layout="@layout/app_bar_main"

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvPlace"
style="@style/TextAppearance.AppCompat.Body1"
android:textColor="@android:color/primary_text_light"
android:padding="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:width="70sp"
android:maxWidth="70sp"
android:text="@string/_0" />
<TextView
android:id="@+id/tvName"
style="@style/TextAppearance.AppCompat.Body1"
android:textColor="@android:color/primary_text_light"
android:padding="20dp"
android:layout_marginLeft="70sp"
android:layout_marginStart="70sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/start_test" />
<TextView
android:id="@+id/tvScore"
style="@style/TextAppearance.AppCompat.Body1"
android:textColor="@android:color/primary_text_light"
android:padding="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
tools:ignore="RelativeOverlap"
android:text="@string/_1337" />
</RelativeLayout>

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView <android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/swipeContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay"
tools:context="de.hwr_berlin.it14.postgrachelor.MainFragment"> tools:context="de.hwr_berlin.it14.postgrachelor.MainFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -34,6 +38,25 @@
grid:columnCount="2" grid:columnCount="2"
grid:rowOrderPreserved="false" grid:rowOrderPreserved="false"
grid:useDefaultMargins="true"> grid:useDefaultMargins="true">
<include layout="@layout/fragment_main_category"
android:layout_width="0dp"
android:layout_height="wrap_content"
grid:layout_columnWeight="1"
grid:layout_gravity="fill"
/>
<include layout="@layout/fragment_main_category"
android:layout_width="0dp"
android:layout_height="wrap_content"
grid:layout_columnWeight="1"
grid:layout_gravity="fill"
/>
<include layout="@layout/fragment_main_category"
android:layout_width="0dp"
android:layout_height="wrap_content"
grid:layout_columnWeight="1"
grid:layout_gravity="fill"
/>
</android.support.v7.widget.GridLayout> </android.support.v7.widget.GridLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>

View File

@@ -17,19 +17,13 @@
<ProgressBar <ProgressBar
style="@style/Widget.AppCompat.ProgressBar.Horizontal" style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:id="@+id/progressBarCategory" android:id="@+id/progressBarCategory"
android:progressDrawable="@drawable/circular_progress_drawable_red" android:progressDrawable="@drawable/horizontal_progress_drawable_red"
android:rotation="-90"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:paddingEnd="10dp"
android:minHeight="100dp"
android:maxWidth="100dp"
android:indeterminate="false" android:indeterminate="false"
android:max="900" android:max="900"
android:progress="300" android:progress="300"
android:paddingRight="10dp" android:layout_alignParentBottom="true"/>
android:paddingLeft="10dp"/>
<TextView <TextView
android:id="@+id/textViewScore" android:id="@+id/textViewScore"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@@ -2,6 +2,8 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clickable="true"
android:id="@+id/layout_fragment_question"
tools:context="de.hwr_berlin.it14.postgrachelor.QuestionFragment"> tools:context="de.hwr_berlin.it14.postgrachelor.QuestionFragment">
<TextView <TextView
@@ -17,7 +19,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:layout_margin="20dp" android:layout_margin="20dp"
android:paddingTop="20sp" android:layout_alignTop="@id/questionCategory"
android:textAppearance="@style/TextAppearance.AppCompat.Title" android:textAppearance="@style/TextAppearance.AppCompat.Title"
android:id="@+id/questionTitle" android:id="@+id/questionTitle"
android:text="@string/welcome_text" /> android:text="@string/welcome_text" />
@@ -27,7 +29,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/_02_15" android:text="@string/_02_15"
android:layout_marginBottom="330sp" android:layout_marginBottom="320sp"
android:textAppearance="@style/TextAppearance.AppCompat.Large" android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
/> />
@@ -36,7 +38,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/_1337" android:text="@string/_1337"
android:layout_marginBottom="330sp" android:layout_marginBottom="320sp"
android:textAppearance="@style/TextAppearance.AppCompat.Large" android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
@@ -45,7 +47,7 @@
android:id="@+id/questionTotal" android:id="@+id/questionTotal"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="330sp" android:layout_marginBottom="320sp"
android:textAppearance="@style/TextAppearance.AppCompat.Large" android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"

View File

@@ -19,4 +19,6 @@
<string name="no_question_available">Keine Fragen verfügbar!</string> <string name="no_question_available">Keine Fragen verfügbar!</string>
<string name="play_a_game">Spiele ein Spiel!</string> <string name="play_a_game">Spiele ein Spiel!</string>
<string name="please_wait">Bitte warten…</string> <string name="please_wait">Bitte warten…</string>
<string name="loading">Lädt…</string>
<string name="place">%1$s.</string>
</resources> </resources>

View File

@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="colorPrimary">#3F51B5</color> <!--<color name="colorPrimary">#3F51B5</color>-->
<color name="colorPrimaryDark">#303F9F</color> <color name="colorPrimary">#5262BC</color>
<!--<color name="colorPrimaryDark">#303F9F</color>-->
<color name="colorPrimaryDark">#2B388F</color>
<color name="colorAccent">#FF4081</color> <color name="colorAccent">#FF4081</color>
</resources> </resources>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="category_name" type="id" />
<item name="category_id" type="id" />
<item name="category_count" type="id" />
</resources>

View File

@@ -24,4 +24,6 @@
<string name="_0" translatable="false">0</string> <string name="_0" translatable="false">0</string>
<string name="play_a_game">Play a Game!</string> <string name="play_a_game">Play a Game!</string>
<string name="please_wait">Please wait…</string> <string name="please_wait">Please wait…</string>
<string name="loading">Loading…</string>
<string name="place">#%1$s</string>
</resources> </resources>

View File

@@ -5,7 +5,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.3.0' classpath 'com.android.tools.build:gradle:2.3.1'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files