News Show Notification on Sidebar
This commit is contained in:
@@ -2,7 +2,6 @@ package de.sebse.fuplanner;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
@@ -16,6 +15,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.zip.Inflater;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
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.types.LoginToken;
|
||||
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.NewAsyncQueue;
|
||||
import de.sebse.fuplanner.tools.Preferences;
|
||||
import de.sebse.fuplanner.tools.Regex;
|
||||
import de.sebse.fuplanner.tools.RequestPermissionsResultListener;
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
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.News;
|
||||
|
||||
public class MainActivity extends AppCompatActivity
|
||||
implements MainActivityListener, KVVListener,
|
||||
@@ -77,13 +81,14 @@ public class MainActivity extends AppCompatActivity
|
||||
private FragmentManager mFragmentManager;
|
||||
private GoogleAuth mGoogleAuth;
|
||||
private KVV mKVV;
|
||||
private NewsManager mNewsManager;
|
||||
private CanteenBrowser mCanteenBrowser;
|
||||
private final Logger log = new Logger(this);
|
||||
private NavigationView mNavigationView;
|
||||
|
||||
private int mFragmentPage = FRAGMENT_NONE;
|
||||
@NotNull
|
||||
private String mFragmentData = "";
|
||||
private CanteenBrowser mCanteenBrowser;
|
||||
private final HashMap<String, RequestPermissionsResultListener> permissionListeners = new HashMap<>();
|
||||
private boolean mOfflineBanner;
|
||||
private final NewAsyncQueue mQueue = new NewAsyncQueue();
|
||||
@@ -117,7 +122,6 @@ public class MainActivity extends AppCompatActivity
|
||||
desiredPage = FRAGMENT_LOGIN;
|
||||
desiredData = "";
|
||||
}
|
||||
log.d("desired", desiredPage, desiredData);
|
||||
updateNavigation();
|
||||
changeFragment(desiredPage, desiredData);
|
||||
}
|
||||
@@ -283,13 +287,12 @@ public class MainActivity extends AppCompatActivity
|
||||
return this.mGoogleAuth;
|
||||
}
|
||||
|
||||
/*@Deprecated
|
||||
public de.sebse.fuplanner.services.KVV.KVV getKVV() {
|
||||
if (this.mKVV == null) {
|
||||
this.mKVV = new de.sebse.fuplanner.services.KVV.KVV(this);
|
||||
public NewsManager getNewsManager() {
|
||||
if (this.mNewsManager == null) {
|
||||
this.mNewsManager = new NewsManager(this);
|
||||
}
|
||||
return this.mNewsManager;
|
||||
}
|
||||
return this.mKVV;
|
||||
}*/
|
||||
|
||||
public KVV getKVV() {
|
||||
if (this.mKVV == null) {
|
||||
@@ -361,6 +364,8 @@ public class MainActivity extends AppCompatActivity
|
||||
fragment = CanteensFragment.newInstance();
|
||||
break;
|
||||
case FRAGMENT_NEWS:
|
||||
Preferences.setLong(this, R.string.pref_last_visited_news, System.currentTimeMillis());
|
||||
updateNavigation();
|
||||
fragment = NewsFragment.newInstance();
|
||||
break;
|
||||
case FRAGMENT_PREFERENCES:
|
||||
@@ -469,7 +474,7 @@ public class MainActivity extends AppCompatActivity
|
||||
}
|
||||
|
||||
private void afterAnyMenuInflate(boolean isLoggedIn, Runnable done) {
|
||||
int MAX_COUNT = isLoggedIn ? 2 : 1;
|
||||
int MAX_COUNT = isLoggedIn ? 3 : 2;
|
||||
final int[] count = {0};
|
||||
if (isLoggedIn) {
|
||||
getKVV().modules().list().recv(success -> {
|
||||
@@ -484,9 +489,9 @@ public class MainActivity extends AppCompatActivity
|
||||
i++;
|
||||
}
|
||||
if (++count[0] == MAX_COUNT) done.run();
|
||||
}, msg -> {
|
||||
}, error -> {
|
||||
if (++count[0] == MAX_COUNT) done.run();
|
||||
log.e(msg);
|
||||
log.e(error);
|
||||
});
|
||||
}
|
||||
getCanteenBrowser().getCanteens(success -> {
|
||||
@@ -500,9 +505,28 @@ public class MainActivity extends AppCompatActivity
|
||||
i++;
|
||||
}
|
||||
if (++count[0] == MAX_COUNT) done.run();
|
||||
}, msg -> {
|
||||
}, error -> {
|
||||
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 MainActivityListener mListener;
|
||||
private NewsAdapter mAdapter;
|
||||
private NewsList dates = new NewsList();
|
||||
// TODO: Rename parameter arguments, choose names that match
|
||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||
|
||||
@@ -71,7 +72,7 @@ public class NewsFragment extends Fragment {
|
||||
}
|
||||
else
|
||||
throw new RuntimeException(context.toString() + " must implement MainActivityListener");
|
||||
refresh();
|
||||
refresh(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,24 +81,6 @@ public class NewsFragment extends Fragment {
|
||||
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
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
@@ -108,45 +91,18 @@ public class NewsFragment extends Fragment {
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(context));
|
||||
mAdapter = new NewsAdapter();
|
||||
recyclerView.setAdapter(mAdapter);
|
||||
|
||||
refresh();
|
||||
refresh(false);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
if (mAdapter == null)
|
||||
private void refresh(boolean forceRefresh) {
|
||||
if (mListener == null)
|
||||
return;
|
||||
String fromAsset = loadJSONFromAsset();
|
||||
if (fromAsset == null)
|
||||
return;
|
||||
String language = Locale.getDefault().getLanguage();
|
||||
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();
|
||||
}
|
||||
mListener.getNewsManager().recv(success -> {
|
||||
if (mAdapter != null)
|
||||
mAdapter.setNews(success);
|
||||
}, log::e, forceRefresh);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class GoogleAuth {
|
||||
|
||||
private void connect() {
|
||||
if (this.isUnavailable()) {
|
||||
Log.d(TAG, "STATUS: Google auth not available!");
|
||||
Log.w(TAG, "STATUS: Google auth not available!");
|
||||
return;
|
||||
}
|
||||
this.mCredentialsClient = getClient();
|
||||
@@ -54,7 +54,7 @@ public class GoogleAuth {
|
||||
|
||||
public void getLoginState(final CredentialsListener credentialsListener) {
|
||||
if (this.isUnavailable()) {
|
||||
Log.d(TAG, "STATUS: Google auth not available!");
|
||||
Log.w(TAG, "STATUS: Google auth not available!");
|
||||
credentialsListener.onCredentials(null);
|
||||
return;
|
||||
}
|
||||
@@ -102,7 +102,7 @@ public class GoogleAuth {
|
||||
|
||||
public void setLoginState(String username, String password) {
|
||||
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();
|
||||
return;
|
||||
}
|
||||
@@ -133,7 +133,7 @@ public class GoogleAuth {
|
||||
|
||||
public void deleteLoginState(String username, String password) {
|
||||
if (this.isUnavailable()) {
|
||||
Log.d(TAG, "STATUS: Google auth not available!");
|
||||
Log.w(TAG, "STATUS: Google auth not available!");
|
||||
return;
|
||||
}
|
||||
if (!this.isConnected)
|
||||
@@ -161,7 +161,7 @@ public class GoogleAuth {
|
||||
}
|
||||
|
||||
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) {
|
||||
case RequestCode.RC_HINT:
|
||||
@@ -173,12 +173,12 @@ public class GoogleAuth {
|
||||
if (mCredentialsListener != null)
|
||||
this.mCredentialsListener.onCredentials(new Credentials(credential.getId(), credential.getPassword()));
|
||||
else
|
||||
Log.d(TAG, "No Credentials Listener");
|
||||
Log.w(TAG, "No Credentials Listener");
|
||||
} else {
|
||||
if (mCredentialsListener != null)
|
||||
this.mCredentialsListener.onCredentials(null);
|
||||
else
|
||||
Log.d(TAG, "No Credentials Listener");
|
||||
Log.w(TAG, "No Credentials Listener");
|
||||
Log.e(TAG, "Credential Read: NOT OK");
|
||||
showToast("Credential Read Failed");
|
||||
}
|
||||
@@ -187,7 +187,7 @@ public class GoogleAuth {
|
||||
break;
|
||||
case RequestCode.RC_SAVE:
|
||||
if (resultCode == RESULT_OK) {
|
||||
Log.d(TAG, "Credential Save: OK");
|
||||
Log.w(TAG, "Credential Save: OK");
|
||||
showToast("Credential Save Success");
|
||||
} else {
|
||||
Log.e(TAG, "Credential Save: NOT OK");
|
||||
@@ -208,7 +208,7 @@ public class GoogleAuth {
|
||||
return;
|
||||
}
|
||||
|
||||
Log.d(TAG, "Resolving: " + rae);
|
||||
Log.w(TAG, "Resolving: " + rae);
|
||||
try {
|
||||
rae.startResolutionForResult(this.activity, requestCode);
|
||||
mIsResolving = true;
|
||||
|
||||
@@ -20,7 +20,6 @@ final public class ModulesDetails extends Part<Pair<Modules.Module, Boolean>> {
|
||||
|
||||
@Override
|
||||
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};
|
||||
AtomicReference<NetworkError> lastError = new AtomicReference<>(null);
|
||||
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.GoogleAuth.GoogleAuth;
|
||||
import de.sebse.fuplanner.services.KVV.KVV;
|
||||
import de.sebse.fuplanner.services.News.NewsManager;
|
||||
|
||||
public interface MainActivityListener {
|
||||
void onTitleTextChange(String newTitle);
|
||||
@@ -21,6 +22,8 @@ public interface MainActivityListener {
|
||||
|
||||
CanteenBrowser getCanteenBrowser();
|
||||
|
||||
NewsManager getNewsManager();
|
||||
|
||||
@Deprecated
|
||||
void onRefreshCompleted(boolean isFailed);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package de.sebse.fuplanner.tools;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.ArrayRes;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
public class Preferences {
|
||||
@@ -9,4 +10,14 @@ public class Preferences {
|
||||
String[] strings = context.getResources().getStringArray(key);
|
||||
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">
|
||||
<path
|
||||
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>
|
||||
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" />
|
||||
<item
|
||||
android:id="@+id/nav_news"
|
||||
android:icon="@drawable/ic_chat_bubble"
|
||||
android:icon="@drawable/ic_chat_bubble_outline"
|
||||
android:title="@string/news"
|
||||
android:orderInCategory="400"/>
|
||||
</group>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
android:orderInCategory="300"/>
|
||||
<item
|
||||
android:id="@+id/nav_news"
|
||||
android:icon="@drawable/ic_chat_bubble"
|
||||
android:icon="@drawable/ic_chat_bubble_outline"
|
||||
android:title="@string/news"
|
||||
android:orderInCategory="400"/>
|
||||
</group>
|
||||
|
||||
@@ -12,7 +12,4 @@
|
||||
<item>employee</item>
|
||||
<item>other</item>
|
||||
</string-array>
|
||||
|
||||
|
||||
|
||||
</resources>
|
||||
@@ -6,4 +6,6 @@
|
||||
</string-array>
|
||||
<string name="pref_price_group" translatable="false">pref_price_group</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>
|
||||
@@ -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