News Show Notification on Sidebar
This commit is contained in:
@@ -2,7 +2,6 @@ package de.sebse.fuplanner;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -16,6 +15,8 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.zip.Inflater;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
@@ -44,14 +45,17 @@ import de.sebse.fuplanner.services.KVV.KVV;
|
|||||||
import de.sebse.fuplanner.services.KVV.KVVListener;
|
import de.sebse.fuplanner.services.KVV.KVVListener;
|
||||||
import de.sebse.fuplanner.services.KVV.types.LoginToken;
|
import de.sebse.fuplanner.services.KVV.types.LoginToken;
|
||||||
import de.sebse.fuplanner.services.KVV.types.Modules;
|
import de.sebse.fuplanner.services.KVV.types.Modules;
|
||||||
|
import de.sebse.fuplanner.services.News.NewsManager;
|
||||||
import de.sebse.fuplanner.tools.MainActivityListener;
|
import de.sebse.fuplanner.tools.MainActivityListener;
|
||||||
import de.sebse.fuplanner.tools.NewAsyncQueue;
|
import de.sebse.fuplanner.tools.NewAsyncQueue;
|
||||||
|
import de.sebse.fuplanner.tools.Preferences;
|
||||||
import de.sebse.fuplanner.tools.Regex;
|
import de.sebse.fuplanner.tools.Regex;
|
||||||
import de.sebse.fuplanner.tools.RequestPermissionsResultListener;
|
import de.sebse.fuplanner.tools.RequestPermissionsResultListener;
|
||||||
import de.sebse.fuplanner.tools.logging.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;
|
||||||
|
import de.sebse.fuplanner.tools.types.News;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity
|
public class MainActivity extends AppCompatActivity
|
||||||
implements MainActivityListener, KVVListener,
|
implements MainActivityListener, KVVListener,
|
||||||
@@ -77,13 +81,14 @@ public class MainActivity extends AppCompatActivity
|
|||||||
private FragmentManager mFragmentManager;
|
private FragmentManager mFragmentManager;
|
||||||
private GoogleAuth mGoogleAuth;
|
private GoogleAuth mGoogleAuth;
|
||||||
private KVV mKVV;
|
private KVV mKVV;
|
||||||
|
private NewsManager mNewsManager;
|
||||||
|
private CanteenBrowser mCanteenBrowser;
|
||||||
private final Logger log = new Logger(this);
|
private final Logger log = new Logger(this);
|
||||||
private NavigationView mNavigationView;
|
private NavigationView mNavigationView;
|
||||||
|
|
||||||
private int mFragmentPage = FRAGMENT_NONE;
|
private int mFragmentPage = FRAGMENT_NONE;
|
||||||
@NotNull
|
@NotNull
|
||||||
private String mFragmentData = "";
|
private String mFragmentData = "";
|
||||||
private CanteenBrowser mCanteenBrowser;
|
|
||||||
private final HashMap<String, RequestPermissionsResultListener> permissionListeners = new HashMap<>();
|
private final HashMap<String, RequestPermissionsResultListener> permissionListeners = new HashMap<>();
|
||||||
private boolean mOfflineBanner;
|
private boolean mOfflineBanner;
|
||||||
private final NewAsyncQueue mQueue = new NewAsyncQueue();
|
private final NewAsyncQueue mQueue = new NewAsyncQueue();
|
||||||
@@ -117,7 +122,6 @@ public class MainActivity extends AppCompatActivity
|
|||||||
desiredPage = FRAGMENT_LOGIN;
|
desiredPage = FRAGMENT_LOGIN;
|
||||||
desiredData = "";
|
desiredData = "";
|
||||||
}
|
}
|
||||||
log.d("desired", desiredPage, desiredData);
|
|
||||||
updateNavigation();
|
updateNavigation();
|
||||||
changeFragment(desiredPage, desiredData);
|
changeFragment(desiredPage, desiredData);
|
||||||
}
|
}
|
||||||
@@ -283,13 +287,12 @@ public class MainActivity extends AppCompatActivity
|
|||||||
return this.mGoogleAuth;
|
return this.mGoogleAuth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@Deprecated
|
public NewsManager getNewsManager() {
|
||||||
public de.sebse.fuplanner.services.KVV.KVV getKVV() {
|
if (this.mNewsManager == null) {
|
||||||
if (this.mKVV == null) {
|
this.mNewsManager = new NewsManager(this);
|
||||||
this.mKVV = new de.sebse.fuplanner.services.KVV.KVV(this);
|
|
||||||
}
|
}
|
||||||
return this.mKVV;
|
return this.mNewsManager;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
public KVV getKVV() {
|
public KVV getKVV() {
|
||||||
if (this.mKVV == null) {
|
if (this.mKVV == null) {
|
||||||
@@ -361,6 +364,8 @@ public class MainActivity extends AppCompatActivity
|
|||||||
fragment = CanteensFragment.newInstance();
|
fragment = CanteensFragment.newInstance();
|
||||||
break;
|
break;
|
||||||
case FRAGMENT_NEWS:
|
case FRAGMENT_NEWS:
|
||||||
|
Preferences.setLong(this, R.string.pref_last_visited_news, System.currentTimeMillis());
|
||||||
|
updateNavigation();
|
||||||
fragment = NewsFragment.newInstance();
|
fragment = NewsFragment.newInstance();
|
||||||
break;
|
break;
|
||||||
case FRAGMENT_PREFERENCES:
|
case FRAGMENT_PREFERENCES:
|
||||||
@@ -469,7 +474,7 @@ public class MainActivity extends AppCompatActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void afterAnyMenuInflate(boolean isLoggedIn, Runnable done) {
|
private void afterAnyMenuInflate(boolean isLoggedIn, Runnable done) {
|
||||||
int MAX_COUNT = isLoggedIn ? 2 : 1;
|
int MAX_COUNT = isLoggedIn ? 3 : 2;
|
||||||
final int[] count = {0};
|
final int[] count = {0};
|
||||||
if (isLoggedIn) {
|
if (isLoggedIn) {
|
||||||
getKVV().modules().list().recv(success -> {
|
getKVV().modules().list().recv(success -> {
|
||||||
@@ -484,9 +489,9 @@ public class MainActivity extends AppCompatActivity
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (++count[0] == MAX_COUNT) done.run();
|
if (++count[0] == MAX_COUNT) done.run();
|
||||||
}, msg -> {
|
}, error -> {
|
||||||
if (++count[0] == MAX_COUNT) done.run();
|
if (++count[0] == MAX_COUNT) done.run();
|
||||||
log.e(msg);
|
log.e(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
getCanteenBrowser().getCanteens(success -> {
|
getCanteenBrowser().getCanteens(success -> {
|
||||||
@@ -500,9 +505,28 @@ public class MainActivity extends AppCompatActivity
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (++count[0] == MAX_COUNT) done.run();
|
if (++count[0] == MAX_COUNT) done.run();
|
||||||
}, msg -> {
|
}, error -> {
|
||||||
if (++count[0] == MAX_COUNT) done.run();
|
if (++count[0] == MAX_COUNT) done.run();
|
||||||
log.e(msg);
|
log.e(error);
|
||||||
|
});
|
||||||
|
getNewsManager().recv(success -> {
|
||||||
|
long lastVisited = Preferences.getLong(this, R.string.pref_last_visited_news);
|
||||||
|
int i = 0;
|
||||||
|
for (News news: success) {
|
||||||
|
if (news.getDate() > lastVisited) i++;
|
||||||
|
}
|
||||||
|
if (i > 0) {
|
||||||
|
MenuItem menuItem = mNavigationView.getMenu().findItem(R.id.nav_news);
|
||||||
|
menuItem.setIcon(R.drawable.ic_sms_failed);
|
||||||
|
View view = View.inflate(this, R.layout.action_icon_number, null);
|
||||||
|
TextView v = view.findViewById(R.id.number);
|
||||||
|
((TextView) view.findViewById(R.id.number)).setText(String.format(Locale.getDefault(), "%d", i));
|
||||||
|
menuItem.setActionView(view);
|
||||||
|
}
|
||||||
|
if (++count[0] == MAX_COUNT) done.run();
|
||||||
|
}, error -> {
|
||||||
|
if (++count[0] == MAX_COUNT) done.run();
|
||||||
|
log.e(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class NewsFragment extends Fragment {
|
|||||||
private Logger log = new Logger(this);
|
private Logger log = new Logger(this);
|
||||||
private MainActivityListener mListener;
|
private MainActivityListener mListener;
|
||||||
private NewsAdapter mAdapter;
|
private NewsAdapter mAdapter;
|
||||||
|
private NewsList dates = new NewsList();
|
||||||
// TODO: Rename parameter arguments, choose names that match
|
// TODO: Rename parameter arguments, choose names that match
|
||||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ public class NewsFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new RuntimeException(context.toString() + " must implement MainActivityListener");
|
throw new RuntimeException(context.toString() + " must implement MainActivityListener");
|
||||||
refresh();
|
refresh(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -80,24 +81,6 @@ public class NewsFragment extends Fragment {
|
|||||||
mListener = null;
|
mListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadJSONFromAsset() {
|
|
||||||
if (getActivity() == null)
|
|
||||||
return null;
|
|
||||||
String json = null;
|
|
||||||
try {
|
|
||||||
InputStream is = getActivity().getResources().openRawResource(R.raw.news);
|
|
||||||
int size = is.available();
|
|
||||||
byte[] buffer = new byte[size];
|
|
||||||
is.read(buffer);
|
|
||||||
is.close();
|
|
||||||
json = new String(buffer, "UTF-8");
|
|
||||||
} catch (IOException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
@@ -108,45 +91,18 @@ public class NewsFragment extends Fragment {
|
|||||||
recyclerView.setLayoutManager(new LinearLayoutManager(context));
|
recyclerView.setLayoutManager(new LinearLayoutManager(context));
|
||||||
mAdapter = new NewsAdapter();
|
mAdapter = new NewsAdapter();
|
||||||
recyclerView.setAdapter(mAdapter);
|
recyclerView.setAdapter(mAdapter);
|
||||||
|
refresh(false);
|
||||||
refresh();
|
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refresh() {
|
private void refresh(boolean forceRefresh) {
|
||||||
if (mAdapter == null)
|
if (mListener == null)
|
||||||
return;
|
return;
|
||||||
String fromAsset = loadJSONFromAsset();
|
mListener.getNewsManager().recv(success -> {
|
||||||
if (fromAsset == null)
|
if (mAdapter != null)
|
||||||
return;
|
mAdapter.setNews(success);
|
||||||
String language = Locale.getDefault().getLanguage();
|
}, log::e, forceRefresh);
|
||||||
try {
|
|
||||||
JSONObject json = new JSONObject(fromAsset);
|
|
||||||
JSONArray news = json.getJSONArray("news");
|
|
||||||
NewsList dates = new NewsList();
|
|
||||||
for (int i = news.length() - 1; i >= 0; i--) {
|
|
||||||
String title = news.getJSONObject(i).optString("title_"+language, null);
|
|
||||||
if (title == null)
|
|
||||||
title = news.getJSONObject(i).getString("title");
|
|
||||||
String categoryString = news.getJSONObject(i).getString("category");
|
|
||||||
int category;
|
|
||||||
if (categoryString.equals("CATEGORY_TRICKS"))
|
|
||||||
category = News.CATEGORY_TRICKS;
|
|
||||||
else
|
|
||||||
category = News.CATEGORY_UPDATE;
|
|
||||||
String dateString = news.getJSONObject(i).getString("date");
|
|
||||||
long date = UtilsDate.stringToMillis(dateString, "dd.MM.yyyy");
|
|
||||||
String text = news.getJSONObject(i).optString("text_"+language, null);
|
|
||||||
if (text == null)
|
|
||||||
text = news.getJSONObject(i).getString("text");
|
|
||||||
News event = new News(title, category, date, text);
|
|
||||||
dates.add(event);
|
|
||||||
}
|
|
||||||
mAdapter.setNews(dates);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class GoogleAuth {
|
|||||||
|
|
||||||
private void connect() {
|
private void connect() {
|
||||||
if (this.isUnavailable()) {
|
if (this.isUnavailable()) {
|
||||||
Log.d(TAG, "STATUS: Google auth not available!");
|
Log.w(TAG, "STATUS: Google auth not available!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.mCredentialsClient = getClient();
|
this.mCredentialsClient = getClient();
|
||||||
@@ -54,7 +54,7 @@ public class GoogleAuth {
|
|||||||
|
|
||||||
public void getLoginState(final CredentialsListener credentialsListener) {
|
public void getLoginState(final CredentialsListener credentialsListener) {
|
||||||
if (this.isUnavailable()) {
|
if (this.isUnavailable()) {
|
||||||
Log.d(TAG, "STATUS: Google auth not available!");
|
Log.w(TAG, "STATUS: Google auth not available!");
|
||||||
credentialsListener.onCredentials(null);
|
credentialsListener.onCredentials(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ public class GoogleAuth {
|
|||||||
|
|
||||||
public void setLoginState(String username, String password) {
|
public void setLoginState(String username, String password) {
|
||||||
if (this.isUnavailable()) {
|
if (this.isUnavailable()) {
|
||||||
Log.d(TAG, "STATUS: Google auth not available!");
|
Log.w(TAG, "STATUS: Google auth not available!");
|
||||||
Toast.makeText(activity, "Google auth not available!", Toast.LENGTH_SHORT).show();
|
Toast.makeText(activity, "Google auth not available!", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ public class GoogleAuth {
|
|||||||
|
|
||||||
public void deleteLoginState(String username, String password) {
|
public void deleteLoginState(String username, String password) {
|
||||||
if (this.isUnavailable()) {
|
if (this.isUnavailable()) {
|
||||||
Log.d(TAG, "STATUS: Google auth not available!");
|
Log.w(TAG, "STATUS: Google auth not available!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!this.isConnected)
|
if (!this.isConnected)
|
||||||
@@ -161,7 +161,7 @@ public class GoogleAuth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
Log.d(TAG, "onActivityResult:" + requestCode + ":" + resultCode + ":" + data);
|
Log.w(TAG, "onActivityResult:" + requestCode + ":" + resultCode + ":" + data);
|
||||||
|
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case RequestCode.RC_HINT:
|
case RequestCode.RC_HINT:
|
||||||
@@ -173,12 +173,12 @@ public class GoogleAuth {
|
|||||||
if (mCredentialsListener != null)
|
if (mCredentialsListener != null)
|
||||||
this.mCredentialsListener.onCredentials(new Credentials(credential.getId(), credential.getPassword()));
|
this.mCredentialsListener.onCredentials(new Credentials(credential.getId(), credential.getPassword()));
|
||||||
else
|
else
|
||||||
Log.d(TAG, "No Credentials Listener");
|
Log.w(TAG, "No Credentials Listener");
|
||||||
} else {
|
} else {
|
||||||
if (mCredentialsListener != null)
|
if (mCredentialsListener != null)
|
||||||
this.mCredentialsListener.onCredentials(null);
|
this.mCredentialsListener.onCredentials(null);
|
||||||
else
|
else
|
||||||
Log.d(TAG, "No Credentials Listener");
|
Log.w(TAG, "No Credentials Listener");
|
||||||
Log.e(TAG, "Credential Read: NOT OK");
|
Log.e(TAG, "Credential Read: NOT OK");
|
||||||
showToast("Credential Read Failed");
|
showToast("Credential Read Failed");
|
||||||
}
|
}
|
||||||
@@ -187,7 +187,7 @@ public class GoogleAuth {
|
|||||||
break;
|
break;
|
||||||
case RequestCode.RC_SAVE:
|
case RequestCode.RC_SAVE:
|
||||||
if (resultCode == RESULT_OK) {
|
if (resultCode == RESULT_OK) {
|
||||||
Log.d(TAG, "Credential Save: OK");
|
Log.w(TAG, "Credential Save: OK");
|
||||||
showToast("Credential Save Success");
|
showToast("Credential Save Success");
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Credential Save: NOT OK");
|
Log.e(TAG, "Credential Save: NOT OK");
|
||||||
@@ -208,7 +208,7 @@ public class GoogleAuth {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Resolving: " + rae);
|
Log.w(TAG, "Resolving: " + rae);
|
||||||
try {
|
try {
|
||||||
rae.startResolutionForResult(this.activity, requestCode);
|
rae.startResolutionForResult(this.activity, requestCode);
|
||||||
mIsResolving = true;
|
mIsResolving = true;
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ final public class ModulesDetails extends Part<Pair<Modules.Module, Boolean>> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void recv(final Modules.Module module, final NetworkCallback<Pair<Modules.Module, Boolean>> callback, final NetworkErrorCallback errorCallback, final boolean forceRefresh, final int retries) {
|
protected void recv(final Modules.Module module, final NetworkCallback<Pair<Modules.Module, Boolean>> callback, final NetworkErrorCallback errorCallback, final boolean forceRefresh, final int retries) {
|
||||||
log.d(mLogin.getLoginToken());
|
|
||||||
final int[] returned = {0};
|
final int[] returned = {0};
|
||||||
AtomicReference<NetworkError> lastError = new AtomicReference<>(null);
|
AtomicReference<NetworkError> lastError = new AtomicReference<>(null);
|
||||||
NetworkCallback<Modules.Module> successCb = success -> {
|
NetworkCallback<Modules.Module> successCb = success -> {
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package de.sebse.fuplanner.services.News;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import de.sebse.fuplanner.R;
|
||||||
|
import de.sebse.fuplanner.tools.UtilsDate;
|
||||||
|
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
||||||
|
import de.sebse.fuplanner.tools.network.NetworkError;
|
||||||
|
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||||
|
import de.sebse.fuplanner.tools.types.NewsList;
|
||||||
|
|
||||||
|
public class NewsManager {
|
||||||
|
private NewsList mNewsList;
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
public NewsManager(Context context) {
|
||||||
|
this.mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void recv(final NetworkCallback<NewsList> callback, final NetworkErrorCallback errorCallback) {
|
||||||
|
recv(callback, errorCallback, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void recv(final NetworkCallback<NewsList> callback, final NetworkErrorCallback errorCallback, final boolean forceRefresh) {
|
||||||
|
if (!forceRefresh && mNewsList != null) {
|
||||||
|
callback.onResponse(mNewsList);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String fromAsset = loadJSONFromAsset();
|
||||||
|
if (fromAsset == null)
|
||||||
|
return;
|
||||||
|
String language = Locale.getDefault().getLanguage();
|
||||||
|
JSONArray news;
|
||||||
|
NewsList dates = new NewsList();
|
||||||
|
try {
|
||||||
|
JSONObject json = new JSONObject(fromAsset);
|
||||||
|
news = json.getJSONArray("news");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
errorCallback.onError(new NetworkError(300100, 500, "Parsing news list failed!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = news.length() - 1; i >= 0; i--) {
|
||||||
|
try {
|
||||||
|
String title = news.getJSONObject(i).optString("title_" + language, null);
|
||||||
|
if (title == null)
|
||||||
|
title = news.getJSONObject(i).getString("title");
|
||||||
|
String categoryString = news.getJSONObject(i).getString("category");
|
||||||
|
int category;
|
||||||
|
if (categoryString.equals("CATEGORY_TRICKS"))
|
||||||
|
category = de.sebse.fuplanner.tools.types.News.CATEGORY_TRICKS;
|
||||||
|
else
|
||||||
|
category = de.sebse.fuplanner.tools.types.News.CATEGORY_UPDATE;
|
||||||
|
String dateString = news.getJSONObject(i).getString("date");
|
||||||
|
long date = UtilsDate.stringToMillis(dateString, "dd.MM.yyyy");
|
||||||
|
String text = news.getJSONObject(i).optString("text_" + language, null);
|
||||||
|
if (text == null)
|
||||||
|
text = news.getJSONObject(i).getString("text");
|
||||||
|
de.sebse.fuplanner.tools.types.News event = new de.sebse.fuplanner.tools.types.News(title, category, date, text);
|
||||||
|
dates.add(event);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mNewsList = dates;
|
||||||
|
callback.onResponse(mNewsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String loadJSONFromAsset() {
|
||||||
|
try {
|
||||||
|
InputStream is = mContext.getResources().openRawResource(R.raw.news);
|
||||||
|
int size = is.available();
|
||||||
|
byte[] buffer = new byte[size];
|
||||||
|
is.read(buffer);
|
||||||
|
is.close();
|
||||||
|
return new String(buffer, "UTF-8");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import androidx.annotation.StringRes;
|
|||||||
import de.sebse.fuplanner.services.Canteen.CanteenBrowser;
|
import de.sebse.fuplanner.services.Canteen.CanteenBrowser;
|
||||||
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.News.NewsManager;
|
||||||
|
|
||||||
public interface MainActivityListener {
|
public interface MainActivityListener {
|
||||||
void onTitleTextChange(String newTitle);
|
void onTitleTextChange(String newTitle);
|
||||||
@@ -21,6 +22,8 @@ public interface MainActivityListener {
|
|||||||
|
|
||||||
CanteenBrowser getCanteenBrowser();
|
CanteenBrowser getCanteenBrowser();
|
||||||
|
|
||||||
|
NewsManager getNewsManager();
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
void onRefreshCompleted(boolean isFailed);
|
void onRefreshCompleted(boolean isFailed);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package de.sebse.fuplanner.tools;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import androidx.annotation.ArrayRes;
|
import androidx.annotation.ArrayRes;
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
|
||||||
public class Preferences {
|
public class Preferences {
|
||||||
@@ -9,4 +10,14 @@ public class Preferences {
|
|||||||
String[] strings = context.getResources().getStringArray(key);
|
String[] strings = context.getResources().getStringArray(key);
|
||||||
return PreferenceManager.getDefaultSharedPreferences(context).getString(strings[0], strings[1]);
|
return PreferenceManager.getDefaultSharedPreferences(context).getString(strings[0], strings[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long getLong(Context context, @StringRes int key) {
|
||||||
|
String string = context.getResources().getString(key);
|
||||||
|
return PreferenceManager.getDefaultSharedPreferences(context).getLong(string, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setLong(Context context, @StringRes int key, long value) {
|
||||||
|
String string = context.getResources().getString(key);
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(string, value).apply();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,5 @@
|
|||||||
android:viewportHeight="24.0">
|
android:viewportHeight="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FF000000"
|
android:fillColor="#FF000000"
|
||||||
android:pathData="M20,2H4c-1.1,0 -2,0.9 -2,2v18l4,-4h14c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2z"/>
|
android:pathData="M20,2L4,2c-1.1,0 -2,0.9 -2,2v18l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,16L6,16l-2,2L4,4h16v12z"/>
|
||||||
</vector>
|
</vector>
|
||||||
9
app/src/main/res/drawable/ic_sms_failed.xml
Normal file
9
app/src/main/res/drawable/ic_sms_failed.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM13,14h-2v-2h2v2zM13,10h-2L11,6h2v4z"/>
|
||||||
|
</vector>
|
||||||
21
app/src/main/res/drawable/rounded_blue_filled.xml
Normal file
21
app/src/main/res/drawable/rounded_blue_filled.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke
|
||||||
|
android:width="4dp"
|
||||||
|
android:color="@color/colorFUBlue" />
|
||||||
|
|
||||||
|
<solid
|
||||||
|
android:color="@color/colorFUBlue"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<corners android:radius="360dp" />
|
||||||
|
|
||||||
|
<padding
|
||||||
|
android:left="10dp"
|
||||||
|
android:top="5dp"
|
||||||
|
android:right="10dp"
|
||||||
|
android:bottom="5dp">
|
||||||
|
</padding>
|
||||||
|
|
||||||
|
</shape>
|
||||||
15
app/src/main/res/layout/action_icon_number.xml
Normal file
15
app/src/main/res/layout/action_icon_number.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/number"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/rounded_blue_filled"
|
||||||
|
android:textColor="@color/colorFUWhite"
|
||||||
|
tools:text="4"/>
|
||||||
|
</LinearLayout>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
android:orderInCategory="200" />
|
android:orderInCategory="200" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_news"
|
android:id="@+id/nav_news"
|
||||||
android:icon="@drawable/ic_chat_bubble"
|
android:icon="@drawable/ic_chat_bubble_outline"
|
||||||
android:title="@string/news"
|
android:title="@string/news"
|
||||||
android:orderInCategory="400"/>
|
android:orderInCategory="400"/>
|
||||||
</group>
|
</group>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
android:orderInCategory="300"/>
|
android:orderInCategory="300"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_news"
|
android:id="@+id/nav_news"
|
||||||
android:icon="@drawable/ic_chat_bubble"
|
android:icon="@drawable/ic_chat_bubble_outline"
|
||||||
android:title="@string/news"
|
android:title="@string/news"
|
||||||
android:orderInCategory="400"/>
|
android:orderInCategory="400"/>
|
||||||
</group>
|
</group>
|
||||||
|
|||||||
@@ -12,7 +12,4 @@
|
|||||||
<item>employee</item>
|
<item>employee</item>
|
||||||
<item>other</item>
|
<item>other</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -6,4 +6,6 @@
|
|||||||
</string-array>
|
</string-array>
|
||||||
<string name="pref_price_group" translatable="false">pref_price_group</string>
|
<string name="pref_price_group" translatable="false">pref_price_group</string>
|
||||||
<string name="pref_price_group_default" translatable="false">all</string>
|
<string name="pref_price_group_default" translatable="false">all</string>
|
||||||
|
|
||||||
|
<string name="pref_last_visited_news" translatable="false">pref_last_visited_news</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1,178 +0,0 @@
|
|||||||
package de.sebse.fuplanner.services.GoogleAuth;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.IntentSender;
|
|
||||||
import android.os.Bundle;
|
|
||||||
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.CredentialRequestResult;
|
|
||||||
import com.google.android.gms.common.ConnectionResult;
|
|
||||||
import com.google.android.gms.common.GoogleApiAvailability;
|
|
||||||
import com.google.android.gms.common.api.GoogleApiClient;
|
|
||||||
import com.google.android.gms.common.api.ResultCallback;
|
|
||||||
import com.google.android.gms.common.api.Status;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.core.app.FragmentActivity;
|
|
||||||
|
|
||||||
import static android.app.Activity.RESULT_OK;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Sebastian 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 GoogleApiClient mCredentialsClient;
|
|
||||||
|
|
||||||
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 mCredentialRequest = new CredentialRequest.Builder()
|
|
||||||
.setPasswordLoginSupported(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 {
|
|
||||||
if (status.hasResolution()) {
|
|
||||||
// Try to resolve the save request. This will prompt the user if
|
|
||||||
// the credential is new.
|
|
||||||
try {
|
|
||||||
status.startResolutionForResult(activity, RequestCode.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 GoogleApiClient getClient(@NonNull GoogleApiClient.ConnectionCallbacks connectionCallbacks, @NonNull GoogleApiClient.OnConnectionFailedListener failedListener) {
|
|
||||||
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) {
|
|
||||||
if (requestCode == RequestCode.RC_SAVE) {
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
Log.d(TAG, "SAVE: OK");
|
|
||||||
Toast.makeText(activity, "Credentials saved", Toast.LENGTH_SHORT).show();
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "SAVE: Canceled by user");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user