I am wanting to delete my authToken that was set on the LoginActivity but I cannot from my LogoutFragment which is part of the the MainActivity. Wondering where I could be going wrong. I seen a few threads about this but none seem to work. I am able to easily clear the shared pref when in the LoginActivity
Thanks
package com.mpl.mpl.ui.logout;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import com.mpl.mpl.LoginActivity;
import com.mpl.mpl.databinding.FragmentLogoutBinding;
import com.mpl.mpl.ui.logout.LogoutViewModel;
public class LogoutFragment extends Fragment {
private LogoutViewModel logoutViewModel;
private FragmentLogoutBinding binding;
private WebView webView;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
logoutViewModel =
new ViewModelProvider(this).get(LogoutViewModel.class);
binding = FragmentLogoutBinding.inflate(inflater, container, false);
View root = binding.getRoot();
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(getActivity());
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
Intent intent = new Intent(getActivity(), LoginActivity.class);
SharedPreferences preferences = getContext().getSharedPreferences("authToken", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.clear();
editor.apply();
startActivity(intent);
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
The LoginFragment:
package com.mpl.mpl.ui.login;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.mpl.mpl.MainActivity;
import com.mpl.mpl.R;
import com.mpl.mpl.databinding.FragmentLoginBinding;
import com.mpl.mpl.restClient.MplRestClient;
import org.json.JSONException;
import org.json.JSONObject;
public class LoginFragment extends Fragment implements View.OnClickListener {
private LoginViewModel loginViewModel;
private FragmentLoginBinding binding;
private WebView webView;
private Button button;
private Button forgottenPasswordBtn;
private Button registerBtn;
private EditText email;
private EditText password;
private EditText errorMessageField;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
loginViewModel =
new ViewModelProvider(this).get(LoginViewModel.class);
binding = FragmentLoginBinding.inflate(inflater, container, false);
View root = binding.getRoot();
webView = (WebView) root.findViewById(R.id.loginWebView);
webView.setWebChromeClient(new WebChromeClient());
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
SharedPreferences pref;
pref = getActivity().getPreferences(Context.MODE_PRIVATE);
String token = pref.getString("authToken", null);
if (token != null) {
webView.loadUrl("javascript:testFunction('" + token + "');");
}
try {
getLoginStatus();
} catch (JSONException e) {
e.printStackTrace();
}
}
});
webView.loadUrl("hidden");
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.addJavascriptInterface(new IJavascriptHandler(), "cpjs");
password = (EditText) root.findViewById(R.id.passwordField);
email = (EditText) root.findViewById(R.id.emailField);
errorMessageField = (EditText) root.findViewById(R.id.statusMessage);
button = (Button) root.findViewById(R.id.buttonTest);
button.setOnClickListener(this);
registerBtn = root.findViewById(R.id.registerBtn);
registerBtn.setOnClickListener(this);
forgottenPasswordBtn = (Button) root.findViewById(R.id.forgottenPasswordBtn);
forgottenPasswordBtn.setOnClickListener(this);
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
@Override
public void onClick(View v) {
//do what you want to do when button is clicked
switch (v.getId()) {
case R.id.buttonTest:
try {
getLoginStatus();
} catch (JSONException e) {
e.printStackTrace();
}
break;
case R.id.forgottenPasswordBtn:
Uri uri = Uri.parse("hidden"); // missing 'http://' will cause crashed
Intent forgottenIntent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(forgottenIntent);
break;
case R.id.registerBtn:
NavController navController = Navigation.findNavController(getActivity(), R.id.nav_host_fragment_login_content_main);
navController.navigate(R.id.nav_register);
break;
}
}
public void getLoginStatus() throws JSONException {
MplRestClient.post("ajax/logintest.php?eml=" + email.getText().toString() + "&pwdr=" + password.getText().toString(), null, new JsonHttpResponseHandler() {
@SuppressLint("SetTextI18n")
@Override
public void onSuccess(int statusCode, cz.msebera.android.httpclient.Header[] headers, JSONObject response) {
// If the response is JSONObject instead of expected JSONArray
try {
String message = response.getString("status");
switch (message) {
case "verify":
errorMessageField.setText("Please Verify Your Email");
errorMessageField.setVisibility(View.VISIBLE);
break;
case "success":
String token = response.getString("token");
errorMessageField.setText("");
errorMessageField.setVisibility(View.GONE);
webView.loadUrl("javascript:testFunction('" + token + "');");
break;
default:
errorMessageField.setText("Please Check Your Details");
errorMessageField.setVisibility(View.VISIBLE);
break;
}
} catch (Exception e) {
Toast.makeText(getActivity(), "fail",
Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(int statusCode, cz.msebera.android.httpclient.Header[] headers, String responseString, Throwable throwable) {
super.onFailure(statusCode, headers, responseString, throwable);
}
});
}
final class IJavascriptHandler {
IJavascriptHandler() {
}
@JavascriptInterface
public void sendToAndroid(String text) {
if (text.length() > 11) {
SharedPreferences pref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor edt = pref.edit();
edt.putString("authToken", text);
edt.commit();
pref = getActivity().getPreferences(Context.MODE_PRIVATE);
String id = pref.getString("authToken", null);
Intent intent = new Intent(getActivity(), MainActivity.class);
startActivity(intent);
}
}
}
}
The LoginFragment is part of the LoginActivity, the shared preference is set in the IJavascriptHandler part
Your Problem
This is how you're setting the preference:
SharedPreferences pref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor edt = pref.edit();
edt.putString("authToken", text);
edt.commit();
This is how you're clearing:
SharedPreferences preferences = getContext().getSharedPreferences("authToken", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.clear();
editor.apply();
See the difference?
When you set the preferences with getActivity().getPreferences(Context.MODE_PRIVATE)
you're setting it to an Activity-specific file named after the activity: see the documentation.
When you get the preferences with getContext().getSharedPreferences("authToken", Context.MODE_PRIVATE)
you're trying to access an app-wide set of preferences named "authToken": see the documentation.
So you're writing to one place and reading from another so of course it's not going to match up.
A Solution
Be consistent in how you get and set preferences. The easiest way to go about that is to use PreferenceManager.getDefaultSharedPreferences for app-wide preferences.
To set:
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getActivity())
SharedPreferences.Editor edt = pref.edit();
edt.putString("authToken", text);
edt.apply();
To clear:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getContext())
SharedPreferences.Editor editor = preferences.edit();
editor.remove("authToken")
editor.apply();