Login Improved; Still Bug when re-login
This commit is contained in:
@@ -69,8 +69,6 @@ public class MainActivity extends AppCompatActivity
|
||||
private static final int FRAGMENT_STARTUP = 0;
|
||||
private static final int FRAGMENT_MODULES = 1;
|
||||
private static final int FRAGMENT_MODULES_DETAILS = 2;
|
||||
@Deprecated
|
||||
private static final int FRAGMENT_LOGIN = 3;
|
||||
private static final int FRAGMENT_SCHEDULE = 4;
|
||||
private static final int FRAGMENT_CANTEENS = 5;
|
||||
private static final int FRAGMENT_CANTEENS_DETAILS = 6;
|
||||
@@ -129,7 +127,7 @@ public class MainActivity extends AppCompatActivity
|
||||
if (!mAccountManager.hasAccounts(AccountGeneral.ACCOUNT_TYPE)) {
|
||||
desiredPage = getDefaultFragmentAfterLogout();
|
||||
desiredData = "";
|
||||
mAccountManager.getTokenForAccountCreateIfNeeded(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV);
|
||||
mAccountManager.getTokenByType(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV, null);
|
||||
updateNavigation();
|
||||
changeFragment(desiredPage, desiredData);
|
||||
} else {
|
||||
@@ -367,7 +365,7 @@ public class MainActivity extends AppCompatActivity
|
||||
setRefreshFailedBanner(false);
|
||||
updateNavigation();
|
||||
changeFragment(getDefaultFragmentAfterLogout());
|
||||
mAccountManager.getTokenForAccountCreateIfNeeded(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV);
|
||||
mAccountManager.getTokenByType(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV, null);
|
||||
}
|
||||
|
||||
private void toLoginState(String fullName, String email, int newFragment, boolean onlineMode) {
|
||||
@@ -526,7 +524,7 @@ public class MainActivity extends AppCompatActivity
|
||||
if (drawer.isDrawerOpen(GravityCompat.START)) {
|
||||
drawer.closeDrawer(GravityCompat.START);
|
||||
}
|
||||
mAccountManager.getTokenForAccountCreateIfNeeded(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV);
|
||||
mAccountManager.getTokenByType(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV, null);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
package de.sebse.fuplanner.fragments;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import de.sebse.fuplanner.R;
|
||||
import de.sebse.fuplanner.tools.MainActivityListener;
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
* Use the {@link LoginFragment#newInstance} factory method to
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
public class LoginFragment extends Fragment {
|
||||
private final Logger log = new Logger(this);
|
||||
@Nullable private MainActivityListener mActivityListener;
|
||||
|
||||
public LoginFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this factory method to create a new instance of
|
||||
* this fragment using the provided parameters.
|
||||
*
|
||||
* @return A new instance of fragment LoginFragment.
|
||||
*/
|
||||
public static LoginFragment newInstance() {
|
||||
LoginFragment fragment = new LoginFragment();
|
||||
Bundle args = new Bundle();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
View v = inflater.inflate(R.layout.fragment_login, container, false);
|
||||
//if (mActivityListener != null && mActivityListener.getKVV().account().isOfflineStoredAvailable()) {
|
||||
// Button offline_btn = v.findViewById(R.id.btn_offline);
|
||||
// offline_btn.setVisibility(View.VISIBLE);
|
||||
// offline_btn.setText(v.getResources().getString(R.string.enter_offline_mode, mActivityListener.getKVV().modules().list().getUsername()));
|
||||
//offline_btn.setOnClickListener(v1 -> mActivityListener.getKVV().account().doOfflineLogin());
|
||||
//}
|
||||
|
||||
View btn_login = v.findViewById(R.id.btn_login);
|
||||
btn_login.setOnClickListener(view -> {
|
||||
final ProgressDialog progressDialog = new ProgressDialog(LoginFragment.this.getContext(),
|
||||
R.style.FUTheme_Dialog);
|
||||
progressDialog.setIndeterminate(true);
|
||||
progressDialog.setMessage("Authenticating...");
|
||||
progressDialog.show();
|
||||
|
||||
EditText input_usr = ((View) view.getParent()).findViewById(R.id.input_username);
|
||||
EditText input_pwd = ((View) view.getParent()).findViewById(R.id.input_password);
|
||||
|
||||
String username = input_usr.getText().toString();
|
||||
String password = input_pwd.getText().toString();
|
||||
|
||||
mActivityListener.getKVV().account().doOnlineLogin(username, password, success -> {
|
||||
progressDialog.dismiss();
|
||||
mActivityListener.getGoogleAuth().setLoginState(username, password);
|
||||
input_usr.setError(null);
|
||||
input_pwd.setError(null);
|
||||
}, error -> {
|
||||
progressDialog.dismiss();
|
||||
// Invalid password
|
||||
if (mActivityListener != null) {
|
||||
if (error.getCode() == 100131) {
|
||||
mActivityListener.showToast(R.string.invalid_credentials);
|
||||
input_usr.setError(input_usr.getResources().getString(R.string.invalid_credentials));
|
||||
input_pwd.setError(input_pwd.getResources().getString(R.string.invalid_credentials));
|
||||
} else {
|
||||
mActivityListener.showToast(v.getResources().getString(R.string.error_occurred_code, error.getCode()));
|
||||
}
|
||||
}
|
||||
log.e("Error on KVV login!", error);
|
||||
});
|
||||
});
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
if (context instanceof MainActivityListener) {
|
||||
mActivityListener = (MainActivityListener) context;
|
||||
mActivityListener.onTitleTextChange(R.string.log_in);
|
||||
} else
|
||||
throw new RuntimeException(context.toString() + " must implement MainActivityListener");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
mActivityListener = null;
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,7 @@ public class Login extends HTTPService {
|
||||
LoginToken.load(mListener.getAccountManager(), token -> {
|
||||
boolean result = setToken(token, true);
|
||||
mLoginPending = false;
|
||||
log.d("loginToken", token != null ? token.toString() : null);
|
||||
callback.run(result);
|
||||
});
|
||||
}
|
||||
@@ -129,9 +130,11 @@ public class Login extends HTTPService {
|
||||
if (!isFirst)
|
||||
return;
|
||||
CustomAccountManager manager = mListener.getAccountManager();
|
||||
manager.invalidate(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV);
|
||||
manager.doInvalidateToken(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV, ignored -> {
|
||||
reset();
|
||||
log.d("try restore", ignored);
|
||||
restoreOnlineLogin(isRestored -> {
|
||||
log.d("restore", isRestored, mToken);
|
||||
if (isRestored)
|
||||
testLoginToken(mRefreshCallbacks::responseResponse, mRefreshCallbacks::responseError);
|
||||
else {
|
||||
@@ -139,6 +142,7 @@ public class Login extends HTTPService {
|
||||
mRefreshCallbacks.responseError(new NetworkError(100180, 403, "Re-login failed!"));
|
||||
}
|
||||
});
|
||||
});
|
||||
/* mListener.getCredentials(credentials -> {
|
||||
doOnlineLogin(credentials.getUsername(), credentials.getPassword(),
|
||||
mRefreshCallbacks::responseResponse,
|
||||
|
||||
@@ -17,18 +17,10 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.text.TextUtils;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import de.sebse.fuplanner.R;
|
||||
@@ -51,7 +43,7 @@ public class FUAuthenticatorActivity extends AccountAuthenticatorActivity implem
|
||||
UserLoginTask mAuthTask = null;
|
||||
|
||||
// UI references.
|
||||
private AutoCompleteTextView mEmailView;
|
||||
private EditText mEmailView;
|
||||
EditText mPasswordView;
|
||||
private View mProgressView;
|
||||
private View mLoginFormView;
|
||||
@@ -76,28 +68,20 @@ public class FUAuthenticatorActivity extends AccountAuthenticatorActivity implem
|
||||
|
||||
setContentView(R.layout.activity_fu_authenticator);
|
||||
// Set up the login form.
|
||||
mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
|
||||
mEmailView = findViewById(R.id.input_username);
|
||||
populateAutoComplete();
|
||||
|
||||
mPasswordView = (EditText) findViewById(R.id.password);
|
||||
mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
|
||||
mPasswordView = findViewById(R.id.input_password);
|
||||
mPasswordView.setOnEditorActionListener((textView, id, keyEvent) -> {
|
||||
if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) {
|
||||
attemptLogin();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
|
||||
mEmailSignInButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
attemptLogin();
|
||||
}
|
||||
});
|
||||
Button mEmailSignInButton = findViewById(R.id.btn_login);
|
||||
mEmailSignInButton.setOnClickListener(view -> attemptLogin());
|
||||
|
||||
mLoginFormView = findViewById(R.id.login_form);
|
||||
mProgressView = findViewById(R.id.login_progress);
|
||||
@@ -217,7 +201,6 @@ public class FUAuthenticatorActivity extends AccountAuthenticatorActivity implem
|
||||
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
|
||||
// for very easy animations. If available, use these APIs to fade-in
|
||||
// the progress spinner.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
|
||||
int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
|
||||
|
||||
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
|
||||
@@ -237,12 +220,6 @@ public class FUAuthenticatorActivity extends AccountAuthenticatorActivity implem
|
||||
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// The ViewPropertyAnimator APIs are not available, so simply show
|
||||
// and hide the relevant UI components.
|
||||
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -264,14 +241,6 @@ public class FUAuthenticatorActivity extends AccountAuthenticatorActivity implem
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
|
||||
List<String> emails = new ArrayList<>();
|
||||
cursor.moveToFirst();
|
||||
while (!cursor.isAfterLast()) {
|
||||
emails.add(cursor.getString(ProfileQuery.ADDRESS));
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
addEmailsToAutoComplete(emails);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -279,15 +248,6 @@ public class FUAuthenticatorActivity extends AccountAuthenticatorActivity implem
|
||||
|
||||
}
|
||||
|
||||
private void addEmailsToAutoComplete(List<String> emailAddressCollection) {
|
||||
//Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.
|
||||
ArrayAdapter<String> adapter =
|
||||
new ArrayAdapter<>(FUAuthenticatorActivity.this,
|
||||
android.R.layout.simple_dropdown_item_1line, emailAddressCollection);
|
||||
|
||||
mEmailView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
|
||||
private interface ProfileQuery {
|
||||
String[] PROJECTION = {
|
||||
|
||||
@@ -2,7 +2,6 @@ package de.sebse.fuplanner.tools;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AccountManagerFuture;
|
||||
import android.accounts.AuthenticatorException;
|
||||
import android.accounts.OperationCanceledException;
|
||||
import android.os.Build;
|
||||
@@ -12,6 +11,7 @@ import java.io.IOException;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import de.sebse.fuplanner.MainActivity;
|
||||
import de.sebse.fuplanner.services.KVV.Login;
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
|
||||
public class CustomAccountManager {
|
||||
@@ -28,13 +28,10 @@ public class CustomAccountManager {
|
||||
|
||||
|
||||
|
||||
private void doInvalidateToken(String accountType, String authTokenType) {
|
||||
//String token = mAccountManager.blockingGetAuthToken();
|
||||
public void doInvalidateTokenSync(String accountType, String authTokenType) {
|
||||
Account account = mAccountManager.getAccountsByType(accountType)[0];
|
||||
String token = null;
|
||||
try {
|
||||
token = mAccountManager.blockingGetAuthToken(account, authTokenType, true);
|
||||
//log.d("hihihi", accountType, authTokenType, token);
|
||||
String token = mAccountManager.blockingGetAuthToken(account, authTokenType, true);
|
||||
mAccountManager.invalidateAuthToken(accountType, token);
|
||||
} catch (AuthenticatorException e) {
|
||||
e.printStackTrace();
|
||||
@@ -45,6 +42,28 @@ public class CustomAccountManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void doInvalidateToken(String accountType, String authTokenType, Login.BooleanInterface callback) {
|
||||
Account account = mAccountManager.getAccountsByType(accountType)[0];
|
||||
mAccountManager.getAuthToken(account, authTokenType, null, true, accountManagerFuture -> {
|
||||
try {
|
||||
Bundle bnd = accountManagerFuture.getResult();
|
||||
String token = bnd.getString(AccountManager.KEY_AUTHTOKEN);
|
||||
mAccountManager.invalidateAuthToken(accountType, token);
|
||||
if (callback != null)
|
||||
callback.run(true);
|
||||
return;
|
||||
} catch (AuthenticatorException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (OperationCanceledException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (callback != null)
|
||||
callback.run(false);
|
||||
}, null);
|
||||
}
|
||||
|
||||
public void deleteAccount(String accountType) {
|
||||
Account[] accounts = mAccountManager.getAccountsByType(accountType);
|
||||
int[] count = {accounts.length};
|
||||
@@ -57,33 +76,13 @@ public class CustomAccountManager {
|
||||
}
|
||||
}
|
||||
|
||||
public void getTokenForAccountCreateIfNeeded(String accountType, String authTokenType) {
|
||||
MainActivity activity = this.mActivityInterface.get();
|
||||
if (activity != null) {
|
||||
final AccountManagerFuture<Bundle> future = mAccountManager.getAuthTokenByFeatures(accountType, authTokenType, null, activity, null, null,
|
||||
future1 -> {
|
||||
Bundle bnd = null;
|
||||
try {
|
||||
bnd = future1.getResult();
|
||||
final String authtoken = bnd.getString(AccountManager.KEY_AUTHTOKEN);
|
||||
//showToast(((authtoken != null) ? "SUCCESS!\ntoken: " + authtoken : "FAIL"));
|
||||
//log.d("udinic", "GetTokenForAccount Bundle is " + bnd);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
//showToast(e.getMessage());
|
||||
}
|
||||
}
|
||||
, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void getTokenByType(String accountType, String authTokenType, StringInterface callback) {
|
||||
public void getTokenByType(String accountType, String authTokenType, @Nullable StringInterface callback) {
|
||||
Account account = mAccountManager.getAccountsByType(accountType)[0];
|
||||
mAccountManager.getAuthToken(account, authTokenType, null, true, accountManagerFuture -> {
|
||||
try {
|
||||
Bundle bnd = accountManagerFuture.getResult();
|
||||
final String authtoken = bnd.getString(AccountManager.KEY_AUTHTOKEN);
|
||||
if (callback != null)
|
||||
callback.run(authtoken);
|
||||
return;
|
||||
} catch (AuthenticatorException e) {
|
||||
@@ -93,6 +92,7 @@ public class CustomAccountManager {
|
||||
} catch (OperationCanceledException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (callback != null)
|
||||
callback.run(null);
|
||||
}, null);
|
||||
}
|
||||
@@ -127,8 +127,4 @@ public class CustomAccountManager {
|
||||
public interface StringInterface {
|
||||
void run(@Nullable String string);
|
||||
}
|
||||
|
||||
public void invalidate(String accountType, String authTokenType) {
|
||||
mAccountManager.invalidateAuthToken(accountType, authTokenType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,60 +19,79 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/login_form"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:id="@+id/login_form"
|
||||
tools:context="de.sebse.fuplanner.services.newkvv.FUAuthenticatorActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/email_login_form"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
android:paddingTop="56dp"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp">
|
||||
|
||||
<ImageView android:src="@mipmap/ic_launcher"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:contentDescription="@string/cd_ic_launcher"/>
|
||||
|
||||
<!-- Email Label -->
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/email"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp">
|
||||
<EditText android:id="@+id/input_username"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/prompt_email"
|
||||
android:inputType="textEmailAddress"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true" />
|
||||
|
||||
android:hint="@string/username"
|
||||
android:autofillHints="username"
|
||||
tools:targetApi="o" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<!-- Password Label -->
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/password"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp">
|
||||
<EditText android:id="@+id/input_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/prompt_password"
|
||||
android:imeActionId="6"
|
||||
android:imeActionLabel="@string/action_sign_in_short"
|
||||
android:imeOptions="actionUnspecified"
|
||||
android:inputType="textPassword"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true" />
|
||||
|
||||
android:hint="@string/password"
|
||||
android:autofillHints="password"
|
||||
tools:targetApi="o"/>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/email_sign_in_button"
|
||||
style="?android:textAppearanceSmall"
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/btn_login"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/action_sign_in"
|
||||
android:textStyle="bold" />
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:padding="12dp"
|
||||
android:text="@string/log_in"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/btn_offline"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:padding="12dp"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context="de.sebse.fuplanner.fragments.LoginFragment">
|
||||
tools:context="de.sebse.fuplanner.services.newkvv.FUAuthenticatorActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
|
||||
Reference in New Issue
Block a user