Added module detail fragment

This commit is contained in:
Caesar2011
2018-04-24 22:18:04 +02:00
parent 49af8ddae1
commit f2e959df87
20 changed files with 448 additions and 426 deletions

Binary file not shown.

View File

@@ -6,7 +6,6 @@ import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View; import android.view.View;
import android.support.design.widget.NavigationView; import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat; import android.support.v4.view.GravityCompat;
@@ -18,6 +17,7 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import de.sebse.fuplanner.fragments.LoginFragment; import de.sebse.fuplanner.fragments.LoginFragment;
import de.sebse.fuplanner.fragments.moddetails.ModDetailFragment;
import de.sebse.fuplanner.fragments.ModulesFragment; import de.sebse.fuplanner.fragments.ModulesFragment;
import de.sebse.fuplanner.fragments.StartupFragment; import de.sebse.fuplanner.fragments.StartupFragment;
import de.sebse.fuplanner.services.GoogleAuth.ConnectedListener; import de.sebse.fuplanner.services.GoogleAuth.ConnectedListener;
@@ -27,7 +27,7 @@ import de.sebse.fuplanner.services.GoogleAuth.GoogleAuth;
import de.sebse.fuplanner.services.KVV.KVV; import de.sebse.fuplanner.services.KVV.KVV;
import de.sebse.fuplanner.services.KVV.LoginToken; import de.sebse.fuplanner.services.KVV.LoginToken;
import de.sebse.fuplanner.services.KVV.Modules; import de.sebse.fuplanner.services.KVV.Modules;
import de.sebse.fuplanner.tools.activity.Logger; import de.sebse.fuplanner.tools.logging.Logger;
import de.sebse.fuplanner.tools.network.NetworkCallback; import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkError; import de.sebse.fuplanner.tools.network.NetworkError;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback; import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
@@ -35,13 +35,13 @@ import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
public class MainActivity extends AppCompatActivity public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, implements NavigationView.OnNavigationItemSelectedListener,
LoginFragment.OnLoginFragmentInteractionListener, LoginFragment.OnLoginFragmentInteractionListener,
StartupFragment.OnStartupFragmentInteractionListener, ModulesFragment.OnModulesFragmentInteractionListener,
ModulesFragment.OnModulesFragmentInteractionListener { ModDetailFragment.OnModuleDetailFragmentInteractionListener {
FragmentManager fragmentManager; FragmentManager fragmentManager;
private GoogleAuth mGoogleAuth; private GoogleAuth mGoogleAuth;
private KVV mKVV; private KVV mKVV;
private Logger log = new Logger("MainAct"); private Logger log = new Logger(this);
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -94,6 +94,7 @@ public class MainActivity extends AppCompatActivity
}, new NetworkErrorCallback() { }, new NetworkErrorCallback() {
@Override @Override
public void onError(NetworkError error) { public void onError(NetworkError error) {
log.e(error);
MainActivity.this.getKVV().endUpdate(); MainActivity.this.getKVV().endUpdate();
changeLoginState(null); changeLoginState(null);
} }
@@ -142,11 +143,19 @@ public class MainActivity extends AppCompatActivity
// Handle navigation view item clicks here. // Handle navigation view item clicks here.
int id = item.getItemId(); int id = item.getItemId();
if (id == R.id.nav_schedule) { switch (id) {
case R.id.nav_modules:
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragcontainer, ModulesFragment.newInstance());
fragmentTransaction.commit();
break;
case R.id.nav_schedule:
} else if (id == R.id.nav_share) { break;
case R.id.nav_share:
} else if (id == R.id.nav_logout) { break;
case R.id.nav_logout:
this.getKVV().logout(); this.getKVV().logout();
this.getGoogleAuth().getLoginState(new CredentialsListener() { this.getGoogleAuth().getLoginState(new CredentialsListener() {
@Override @Override
@@ -157,6 +166,7 @@ public class MainActivity extends AppCompatActivity
MainActivity.this.changeLoginState(null); MainActivity.this.changeLoginState(null);
} }
}); });
break;
} }
DrawerLayout drawer = findViewById(R.id.drawer_layout); DrawerLayout drawer = findViewById(R.id.drawer_layout);
@@ -227,7 +237,7 @@ public class MainActivity extends AppCompatActivity
getKVV().getModuleList(new NetworkCallback<Modules>() { getKVV().getModuleList(new NetworkCallback<Modules>() {
@Override @Override
public void onResponse(@NonNull Modules success) { public void onResponse(@NonNull Modules success) {
log.d("Modules.get "+success.size()); log.d("Modules.get", success.size());
//SubMenu moduleMenu = navigationView.getMenu().findItem(R.id.nav_modules).getSubMenu(); //SubMenu moduleMenu = navigationView.getMenu().findItem(R.id.nav_modules).getSubMenu();
int i = 0; int i = 0;
for (Modules.Module module: success) { for (Modules.Module module: success) {
@@ -248,7 +258,7 @@ public class MainActivity extends AppCompatActivity
}, new NetworkErrorCallback() { }, new NetworkErrorCallback() {
@Override @Override
public void onError(NetworkError error) { public void onError(NetworkError error) {
log.d("Modules.error "+error.toString()); log.d("Modules.error", error);
} }
}); });
} }
@@ -269,18 +279,13 @@ public class MainActivity extends AppCompatActivity
changeLoginState(credentials); changeLoginState(credentials);
} }
@Override
public void onStartupFragmentInteraction(Uri uri) {
}
@Override @Override
public void onModulesFragmentInteraction(final int itemPosition) { public void onModulesFragmentInteraction(final int itemPosition) {
Log.d("MainAct", "Item clicked "+itemPosition); log.d("Item clicked", itemPosition);
getKVV().getModuleList(new NetworkCallback<Modules>() { getKVV().getModuleList(new NetworkCallback<Modules>() {
@Override @Override
public void onResponse(@NonNull Modules success) { public void onResponse(@NonNull Modules success) {
Log.d("MainAct", success.get(itemPosition).title); log.d(success.get(itemPosition).title);
} }
}, new NetworkErrorCallback() { }, new NetworkErrorCallback() {
@Override @Override
@@ -288,5 +293,14 @@ public class MainActivity extends AppCompatActivity
// TODO // TODO
} }
}); });
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragcontainer, ModDetailFragment.newInstance(itemPosition));
fragmentTransaction.commit();
}
@Override
public void onModuleDetailFragmentInteraction(Uri uri) {
log.d("Cooles ding");
} }
} }

View File

@@ -17,6 +17,7 @@ import de.sebse.fuplanner.services.GoogleAuth.Credentials;
import de.sebse.fuplanner.services.GoogleAuth.GoogleAuth; import de.sebse.fuplanner.services.GoogleAuth.GoogleAuth;
import de.sebse.fuplanner.services.KVV.KVV; import de.sebse.fuplanner.services.KVV.KVV;
import de.sebse.fuplanner.services.KVV.LoginToken; import de.sebse.fuplanner.services.KVV.LoginToken;
import de.sebse.fuplanner.tools.logging.Logger;
import de.sebse.fuplanner.tools.network.NetworkCallback; import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkError; import de.sebse.fuplanner.tools.network.NetworkError;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback; import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
@@ -36,6 +37,7 @@ public class LoginFragment extends Fragment {
// TODO: Rename and change types of parameters // TODO: Rename and change types of parameters
private OnLoginFragmentInteractionListener mListener; private OnLoginFragmentInteractionListener mListener;
private Logger log = new Logger(this);
public LoginFragment() { public LoginFragment() {
// Required empty public constructor // Required empty public constructor
@@ -83,7 +85,7 @@ public class LoginFragment extends Fragment {
if (input_usr != null) { if (input_usr != null) {
if (input_pwd != null) { if (input_pwd != null) {
if (LoginFragment.this.getActivity() == null) { if (LoginFragment.this.getActivity() == null) {
Log.e("KVVLogin", "Login fragment has no activity!"); log.e("Login fragment has no activity!");
return; return;
} }
final String username = input_usr.getText().toString(); final String username = input_usr.getText().toString();
@@ -94,7 +96,7 @@ public class LoginFragment extends Fragment {
@Override @Override
public void onResponse(@NonNull LoginToken success) { public void onResponse(@NonNull LoginToken success) {
progressDialog.dismiss(); progressDialog.dismiss();
Log.d("KVVLogin", success.toString()); log.d("success", success.toString());
gauth.setLoginState(username, password); gauth.setLoginState(username, password);
if (LoginFragment.this.mListener != null) { if (LoginFragment.this.mListener != null) {
Credentials cred = new Credentials(username, password); Credentials cred = new Credentials(username, password);
@@ -105,7 +107,7 @@ public class LoginFragment extends Fragment {
@Override @Override
public void onError(NetworkError error) { public void onError(NetworkError error) {
progressDialog.dismiss(); progressDialog.dismiss();
Log.e("KVVLoginError", error.getCode()+""); log.e("error", error);
} }
}); });
} }

View File

@@ -3,6 +3,7 @@ package de.sebse.fuplanner.fragments;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -19,12 +20,6 @@ import de.sebse.fuplanner.R;
* create an instance of this fragment. * create an instance of this fragment.
*/ */
public class StartupFragment extends Fragment { public class StartupFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
// TODO: Rename and change types of parameters
private OnStartupFragmentInteractionListener mListener;
public StartupFragment() { public StartupFragment() {
// Required empty public constructor // Required empty public constructor
@@ -36,7 +31,6 @@ public class StartupFragment extends Fragment {
* *
* @return A new instance of fragment StartupFragment. * @return A new instance of fragment StartupFragment.
*/ */
// TODO: Rename and change types and number of parameters
public static StartupFragment newInstance() { public static StartupFragment newInstance() {
StartupFragment fragment = new StartupFragment(); StartupFragment fragment = new StartupFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
@@ -50,42 +44,9 @@ public class StartupFragment extends Fragment {
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_startup, container, false); return inflater.inflate(R.layout.fragment_startup, container, false);
return v;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnStartupFragmentInteractionListener) {
mListener = (OnStartupFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnStartupFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnStartupFragmentInteractionListener {
// TODO: Update argument type and name
void onStartupFragmentInteraction(Uri uri);
} }
} }

View File

@@ -0,0 +1,38 @@
package de.sebse.fuplanner.fragments.moddetails;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
class ModDetailAdapter extends FragmentPagerAdapter {
public ModDetailAdapter(FragmentManager fm) {
super(fm);
}
// Returns total number of pages
@Override
public int getCount() {
return 2;
}
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment
return ModDetailOverviewFragment.newInstance("1", "Page # 1");
case 1: // Fragment # 0 - This will show FirstFragment different title
return ModDetailAnnounceFragment.newInstance("2", "Page # 2");
default:
return null;
}
}
// Returns the page title for the top indicator
@Override
public CharSequence getPageTitle(int position) {
return "Page " + position;
}
}

View File

@@ -0,0 +1,66 @@
package de.sebse.fuplanner.fragments.moddetails;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import de.sebse.fuplanner.R;
/**
* A simple {@link Fragment} subclass.
* Use the {@link ModDetailAnnounceFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class ModDetailAnnounceFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public ModDetailAnnounceFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment ModDetailAnnounceFragment.
*/
// TODO: Rename and change types and number of parameters
public static ModDetailAnnounceFragment newInstance(String param1, String param2) {
ModDetailAnnounceFragment fragment = new ModDetailAnnounceFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_mod_detail_announce, container, false);
}
}

View File

@@ -0,0 +1,112 @@
package de.sebse.fuplanner.fragments.moddetails;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import de.sebse.fuplanner.R;
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link OnModuleDetailFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link ModDetailFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class ModDetailFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_POSITION = "itemPosition";
// TODO: Rename and change types of parameters
private int mItemPos;
private OnModuleDetailFragmentInteractionListener mListener;
private ModDetailAdapter adapterViewPager;
public ModDetailFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param itemPosition Item position in module list.
* @return A new instance of fragment ModDetailFragment.
*/
// TODO: Rename and change types and number of parameters
public static Fragment newInstance(int itemPosition) {
ModDetailFragment fragment = new ModDetailFragment();
Bundle args = new Bundle();
args.putInt(ARG_POSITION, itemPosition);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mItemPos = getArguments().getInt(ARG_POSITION);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_mod_detail, container, false);
ViewPager vpPager = (ViewPager) v.findViewById(R.id.vpPager);
adapterViewPager = new ModDetailAdapter(getFragmentManager());
vpPager.setAdapter(adapterViewPager);
return v;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onModuleDetailFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnModuleDetailFragmentInteractionListener) {
mListener = (OnModuleDetailFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnModuleDetailFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnModuleDetailFragmentInteractionListener {
// TODO: Update argument type and name
void onModuleDetailFragmentInteraction(Uri uri);
}
}

View File

@@ -0,0 +1,66 @@
package de.sebse.fuplanner.fragments.moddetails;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import de.sebse.fuplanner.R;
/**
* A simple {@link Fragment} subclass.
* Use the {@link ModDetailOverviewFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class ModDetailOverviewFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public ModDetailOverviewFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment ModDetailOverviewFragment.
*/
// TODO: Rename and change types and number of parameters
public static ModDetailOverviewFragment newInstance(String param1, String param2) {
ModDetailOverviewFragment fragment = new ModDetailOverviewFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_mod_detail_overview, container, false);
}
}

View File

@@ -4,13 +4,11 @@ import android.content.Context;
import android.util.Log; import android.util.Log;
import com.android.volley.AuthFailureError; import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request; import com.android.volley.Request;
import com.android.volley.RequestQueue; import com.android.volley.RequestQueue;
import com.android.volley.Response; import com.android.volley.Response;
import com.android.volley.VolleyError; import com.android.volley.VolleyError;
import com.android.volley.VolleyLog; import com.android.volley.VolleyLog;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.StringRequest; import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley; import com.android.volley.toolbox.Volley;

View File

@@ -1,41 +0,0 @@
package de.sebse.fuplanner.tools.activity;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
/**
* Created by sebastian on 19.04.18.
*/
public class Logger {
private final String tag;
public Logger(String tag) {
super();
this.tag = tag;
}
public void d(String text) {
Log.d(tag, text);
}
public void d(boolean text) {
Log.d(tag, String.valueOf(text));
}
public void d(int text) {
Log.d(tag, String.valueOf(text));
}
public void e(String text) {
Log.e(tag, text);
}
public void e(boolean text) {
Log.e(tag, String.valueOf(text));
}
public void e(int text) {
Log.e(tag, String.valueOf(text));
}
}

View File

@@ -0,0 +1,29 @@
package de.sebse.fuplanner.tools.logging;
import android.util.Log;
public class Logger {
private final String tag;
public Logger(Object object) {
this.tag = object.getClass().getSimpleName();
}
public void d(Object... msg) {
Log.d(tag, concat(msg));
}
public void e(Object... msg) {
Log.e(tag, concat(msg));
}
private String concat(Object[] msg) {
StringBuilder string = new StringBuilder();
for (Object arg: msg)
if (arg != null)
string.append(arg.toString()).append(" ");
else
string.append("null ");
return string.toString();
}
}

View File

@@ -78,7 +78,7 @@ public class BetterHurlStack extends HurlStack {
public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
throws IOException, AuthFailureError { throws IOException, AuthFailureError {
String url = request.getUrl(); String url = request.getUrl();
HashMap<String, String> map = new HashMap<String, String>(); HashMap<String, String> map = new HashMap<>();
map.putAll(request.getHeaders()); map.putAll(request.getHeaders());
map.putAll(additionalHeaders); map.putAll(additionalHeaders);
if (mUrlRewriter != null) { if (mUrlRewriter != null) {

View File

@@ -5,9 +5,11 @@ import android.support.annotation.Nullable;
import android.util.Log; import android.util.Log;
import com.android.volley.AuthFailureError; import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request; import com.android.volley.Request;
import com.android.volley.RequestQueue; import com.android.volley.RequestQueue;
import com.android.volley.Response; import com.android.volley.Response;
import com.android.volley.TimeoutError;
import com.android.volley.VolleyError; import com.android.volley.VolleyError;
import com.android.volley.toolbox.Volley; import com.android.volley.toolbox.Volley;
@@ -16,6 +18,8 @@ import java.net.URLEncoder;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import de.sebse.fuplanner.tools.logging.Logger;
/** /**
* Created by sebastian on 24.10.17. * Created by sebastian on 24.10.17.
*/ */
@@ -23,6 +27,7 @@ import java.util.Map;
public class HTTPService { public class HTTPService {
protected RequestQueue requestQueue; protected RequestQueue requestQueue;
private boolean followRedirects; private boolean followRedirects;
protected Logger log = new Logger(this);
public HTTPService(Context context) { public HTTPService(Context context) {
this(context, false); this(context, false);
@@ -38,10 +43,17 @@ public class HTTPService {
@Override @Override
public void deliverError(VolleyError error) { public void deliverError(VolleyError error) {
if (error == null) { if (error == null) {
super.deliverError(null); super.deliverError(new VolleyError(new NetworkResponse(500, null, null, true, 0)));
} else if (error.networkResponse == null) {
int statusCode;
if (error instanceof TimeoutError)
statusCode = 408;
else
statusCode = 500;
super.deliverError(new VolleyError(new NetworkResponse(statusCode, null, null, true, error.getNetworkTimeMs())));
} else { } else {
final int status = error.networkResponse.statusCode; final int status = error.networkResponse.statusCode;
if (status == 302 && !followRedirects) { if (status == 302) {
super.deliverResponse(new Result(null, error.networkResponse.headers)); super.deliverResponse(new Result(null, error.networkResponse.headers));
} else { } else {
super.deliverError(error); super.deliverError(error);
@@ -87,7 +99,7 @@ public class HTTPService {
sb.append('&'); sb.append('&');
} }
try { try {
Log.e("Superissimo", e.getKey()+"|||"+e.getValue()); //Log.e("Superissimo", e.getKey()+"|||"+e.getValue());
sb.append(URLEncoder.encode(e.getKey(), "UTF-8")).append('=').append(URLEncoder.encode(e.getValue(), "UTF-8")); sb.append(URLEncoder.encode(e.getKey(), "UTF-8")).append('=').append(URLEncoder.encode(e.getValue(), "UTF-8"));
} catch (UnsupportedEncodingException ignored) { } catch (UnsupportedEncodingException ignored) {
} }
@@ -102,6 +114,16 @@ public class HTTPService {
@Override @Override
public void deliverError(VolleyError error) { public void deliverError(VolleyError error) {
if (error == null) {
super.deliverError(new VolleyError(new NetworkResponse(500, null, null, true, 0)));
} else if (error.networkResponse == null) {
int statusCode;
if (error instanceof TimeoutError)
statusCode = 408;
else
statusCode = 500;
super.deliverError(new VolleyError(new NetworkResponse(statusCode, null, null, true, error.getNetworkTimeMs())));
} else {
final int status = error.networkResponse.statusCode; final int status = error.networkResponse.statusCode;
if (status == 302) { if (status == 302) {
super.deliverResponse(new Result(null, error.networkResponse.headers)); super.deliverResponse(new Result(null, error.networkResponse.headers));
@@ -109,6 +131,7 @@ public class HTTPService {
super.deliverError(error); super.deliverError(error);
} }
} }
}
public Map<String, String> getHeaders() throws AuthFailureError { public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = super.getHeaders(); Map<String, String> params = super.getHeaders();
@@ -130,7 +153,7 @@ public class HTTPService {
requestQueue.add(request); requestQueue.add(request);
} }
public static void largeLog(String tag, String content) { private static void largeLog(String tag, String content) {
if (content==null) { if (content==null) {
Log.d(tag, "null"); Log.d(tag, "null");
} else if (content.length() > 4000) { } else if (content.length() > 4000) {

View File

@@ -1,5 +1,6 @@
package de.sebse.fuplanner.tools.network; package de.sebse.fuplanner.tools.network;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse; import com.android.volley.NetworkResponse;
import com.android.volley.Request; import com.android.volley.Request;
import com.android.volley.Response; import com.android.volley.Response;
@@ -12,12 +13,17 @@ import java.io.UnsupportedEncodingException;
*/ */
public class HttpRequest extends Request<Result> { public class HttpRequest extends Request<Result> {
private static final int MY_SOCKET_TIMEOUT_MS = 15000;
private final Response.Listener<Result> mListener; private final Response.Listener<Result> mListener;
public HttpRequest(int method, String url, Response.Listener<Result> listener, public HttpRequest(int method, String url, Response.Listener<Result> listener,
Response.ErrorListener errorListener) { Response.ErrorListener errorListener) {
super(method, url, errorListener); super(method, url, errorListener);
mListener = listener; mListener = listener;
this.setRetryPolicy(new DefaultRetryPolicy(
MY_SOCKET_TIMEOUT_MS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
} }
@Override @Override

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/vpPager"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v4.view.PagerTabStrip
android:id="@+id/pager_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="4dp"
android:paddingTop="4dp" />
</android.support.v4.view.ViewPager>
</LinearLayout>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.moddetails.ModDetailAnnounceFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Announcement fragment" />
</FrameLayout>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.moddetails.ModDetailOverviewFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Overview Fragment" />
</FrameLayout>

View File

@@ -8,6 +8,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginLeft="16dp" android:layout_marginLeft="16dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager" app:layoutManager="android.support.v7.widget.LinearLayoutManager"
tools:context="de.sebse.fuplanner.fragments.ModulesFragment" tools:context="de.sebse.fuplanner.fragments.ModulesFragment"
tools:listitem="@layout/fragment_modules" /> tools:listitem="@layout/fragment_modules" />

View File

@@ -1,301 +0,0 @@
package de.sebse.fuplanner.services.GoogleAuth;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.credentials.Credential;
import com.google.android.gms.auth.api.credentials.CredentialRequest;
import com.google.android.gms.auth.api.credentials.CredentialRequestResponse;
import com.google.android.gms.auth.api.credentials.CredentialRequestResult;
import com.google.android.gms.auth.api.credentials.CredentialsClient;
import com.google.android.gms.auth.api.credentials.CredentialsOptions;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import static android.app.Activity.RESULT_OK;
/**
* Created by ***REMOVED*** on 06.11.2017.
*/
public class GoogleAuth {
// https://developers.google.com/identity/smartlock-passwords/android/retrieve-credentials
private static final String TAG = "GoogleAuth";
private final FragmentActivity activity;
private CredentialsClient mCredentialsClient;
private boolean mIsResolving;
public GoogleAuth(FragmentActivity activity) {
this.activity = activity;
}
public void connect(final ConnectedListener listener) {
if (!this.isAvailable()) {
Log.d(TAG, "STATUS: Google auth not available!");
listener.connected();
return;
}
this.mCredentialsClient = getClient(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(@Nullable Bundle bundle) {
listener.connected();
}
@Override
public void onConnectionSuspended(int i) {
}
}, new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
});
}
public void getLoginState(final CredentialsListener credentialsListener) {
if (!this.isAvailable()) {
Log.d(TAG, "STATUS: Google auth not available!");
credentialsListener.onCredentials(null);
return;
}
CredentialRequest request = new CredentialRequest.Builder()
.setPasswordLoginSupported(true)
.build();
mCredentialsClient.request(request).addOnCompleteListener(
new OnCompleteListener<CredentialRequestResponse>() {
@Override
public void onComplete(@NonNull Task<CredentialRequestResponse> task) {
if (task.isSuccessful()) {
// Successfully read the credential without any user interaction, this
// means there was only a single credential and the user has auto
// sign-in enabled.
Credential credential = task.getResult().getCredential();
credentialsListener.onCredentials(new Credentials(credential.getId(), credential.getPassword()));
return;
}
Exception e = task.getException();
if (e instanceof ResolvableApiException) {
// This is most likely the case where the user has multiple saved
// credentials and needs to pick one. This requires showing UI to
// resolve the read request.
ResolvableApiException rae = (ResolvableApiException) e;
resolveResult(rae, RequestCode.RC_READ);
return;
}
if (e instanceof ApiException) {
ApiException ae = (ApiException) e;
if (ae.getStatusCode() == CommonStatusCodes.SIGN_IN_REQUIRED) {
// This means only a hint is available, but we are handling that
// elsewhere so no need to act here.
} else {
Log.w(TAG, "Unexpected status code: " + ae.getStatusCode());
}
}
}
});
/*Auth.CredentialsApi.request(this.mCredentialsClient, mCredentialRequest).setResultCallback(
new ResultCallback<CredentialRequestResult>() {
@Override
public void onResult(@NonNull CredentialRequestResult credentialRequestResult) {
if (credentialRequestResult.getStatus().isSuccess()) {
// See "Handle successful credential requests"
Credential credential = credentialRequestResult.getCredential();
credentialsListener.onCredentials(new Credentials(credential.getId(), credential.getPassword()));
} else {
// See "Handle unsuccessful and incomplete credential requests"
credentialsListener.onCredentials(null);
}
}
}
);*/
}
public void setLoginState(String username, String password) {
if (!this.isAvailable()) {
Log.d(TAG, "STATUS: Google auth not available!");
Toast.makeText(activity, "Google auth not available!", Toast.LENGTH_SHORT).show();
return;
}
Credential credential = new Credential.Builder(username)
.setPassword(password)
.build();
mCredentialsClient.save(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
showToast("Credential saved.");
return;
}
Exception e = task.getException();
if (e instanceof ResolvableApiException) {
// The first time a credential is saved, the user is shown UI
// to confirm the action. This requires resolution.
ResolvableApiException rae = (ResolvableApiException) e;
resolveResult(rae, RequestCode.RC_SAVE);
} else {
// Save failure cannot be resolved.
Log.w(TAG, "Save failed.", e);
showToast("Credential Save Failed");
}
}
});
/*Auth.CredentialsApi.save(mCredentialsClient, credential).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(@NonNull Status status) {
if (status.isSuccess()) {
Log.d(TAG, "SAVE: OK");
Toast.makeText(activity, "Credentials saved", Toast.LENGTH_SHORT).show();
} else {
Log.d(TAG, String.valueOf(status.hasResolution()));
Log.d(TAG, String.valueOf(status.getStatus()));
if (status.hasResolution()) {
// Try to resolve the save request. This will prompt the user if
// the credential is new.
try {
status.startResolutionForResult(activity, RC_SAVE);
} catch (IntentSender.SendIntentException e) {
// Could not resolve the request
Log.e(TAG, "STATUS: Failed to send resolution.", e);
Toast.makeText(activity, "Save failed", Toast.LENGTH_SHORT).show();
}
} else {
// Request has no resolution
Toast.makeText(activity, "Save failed", Toast.LENGTH_SHORT).show();
}
}
}
}
);*/
}
public void deleteLoginState(String username, String password) {
if (!this.isAvailable()) {
Log.d(TAG, "STATUS: Google auth not available!");
return;
}
Credential credential = new Credential.Builder(username)
.setPassword(password)
.build();
Auth.CredentialsApi.delete(mCredentialsClient, credential).setResultCallback(
new ResultCallback<Status>() {
@Override
public void onResult(Status status) {
if (status.isSuccess()) {
// Credential was deleted successfully
}
}
}
);
}
private boolean isAvailable() {
return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this.activity) == ConnectionResult.SUCCESS;
}
private CredentialsClient getClient(@NonNull GoogleApiClient.ConnectionCallbacks connectionCallbacks, @NonNull GoogleApiClient.OnConnectionFailedListener failedListener) {
CredentialsOptions options = new CredentialsOptions.Builder()
.forceEnableSaveDialog()
.build();
return com.google.android.gms.auth.api.credentials.Credentials.getClient(this.activity, options);
/*return new GoogleApiClient.Builder(this.activity)
.addConnectionCallbacks(connectionCallbacks)
.enableAutoManage(this.activity, failedListener)
.addApi(Auth.CREDENTIALS_API)
.build();*/
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult:" + requestCode + ":" + resultCode + ":" + data);
switch (requestCode) {
case RequestCode.RC_HINT:
// Drop into handling for RC_READ
case RequestCode.RC_READ:
if (resultCode == RESULT_OK) {
boolean isHint = (requestCode == RequestCode.RC_HINT);
Credential credential = data.getParcelableExtra(Credential.EXTRA_KEY);
processRetrievedCredential(credential, isHint);
} else {
Log.e(TAG, "Credential Read: NOT OK");
showToast("Credential Read Failed");
}
mIsResolving = false;
break;
case RequestCode.RC_SAVE:
if (resultCode == RESULT_OK) {
Log.d(TAG, "Credential Save: OK");
showToast("Credential Save Success");
} else {
Log.e(TAG, "Credential Save: NOT OK");
showToast("Credential Save Failed");
}
mIsResolving = false;
break;
}
}
private void resolveResult(ResolvableApiException rae, int requestCode) {
// We don't want to fire multiple resolutions at once since that can result
// in stacked dialogs after rotation or another similar event.
if (mIsResolving) {
Log.w(TAG, "resolveResult: already resolving.");
return;
}
Log.d(TAG, "Resolving: " + rae);
try {
rae.startResolutionForResult(this.activity, requestCode);
mIsResolving = true;
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "STATUS: Failed to send resolution.", e);
}
}
/** Display a short Toast message **/
private void showToast(String msg) {
Toast.makeText(this.activity, msg, Toast.LENGTH_SHORT).show();
}
}