Store website cookies in Android Webview forever - android

I want to store my website cookies permanently in my Android Webview APk so that a user don't have to enter login details every time he starts the app. Please tell me in details as I am beginner. Any help will be appreciated.

This code will help you. Please take a look (you may copy/paste the code too)
public class MessangerMainFragment extends Fragment{
WebView telegram_web;
public MessangerMainFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
View v = inflater.inflate(R.layout.fragment_messanger_main, container, false);
setupUI(v);
init();
return v;
}
public void init() {
telegram_web.getSettings().setJavaScriptEnabled(true);
telegram_web.getSettings().setLoadWithOverviewMode(true);
telegram_web.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
telegram_web.getSettings().setUseWideViewPort(true);
telegram_web.getSettings().setDomStorageEnabled(true);
telegram_web.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, final String url) {
CookieSyncManager.getInstance().sync();
}
});
telegram_web.loadUrl("https://web.telegram.org/#/im");
}
public void setupUI(View v) {
telegram_web = v.findViewById(R.id.telegram_web);
if (!UniversalUtility.isOnline(getContext()))
UniversalUtility.handleFailureResponse("t.getMessage()", "messanger");
}
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CookieSyncManager.createInstance(getContext());
}
#Override
public void onResume() {
super.onResume();
CookieSyncManager.getInstance().startSync();
}
#Override
public void onPause() {
super.onPause();
CookieSyncManager.getInstance().stopSync();
}
#Override
public void onDetach() {
super.onDetach();
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
}
}

Related

WebView save and restore state issue with postUrl

I am using the following components in my application
Activity
Fragment
WebView
Goal - I don't want to reload the webview on orientation change.
Issue - Currently I see the following error on orientation change "Webpage was not available. The webpage at https://fakeurls.org could not be loaded because net::ERR_CACHE_MISS"
Steps to Reproduce
Application was opened in device portrait mode.
Content of given URL was loaded in webview successfully
Device was turned to landscape mode
Webview shows error
Code - Android application makes a post request in a webview to url https://fakeurls.org. Below is the code for MyActivity and MyFragment class
MyFragment.java
public class MyFragment extends Fragment {
private ProgressBar mProgressBar;
private WebView mWebView;
private String mUrl = null;
private String mPostData = null;
public MyFragment() {
// Required empty public constructor
}
public static MyFragment newInstance(#android.support.annotation.NonNull String url, String postData) {
MyFragment MyFragment = new MyFragment();
Bundle bundle = new Bundle();
bundle.putString("URL", url);
bundle.putString("POSTDATA", postData);
MyFragment.setArguments(bundle);
return MyFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.my_fragment, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
instantiateWebView(view);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
mWebView.restoreState(savedInstanceState);
} else {
Bundle args = getArguments();
if (args == null) {
return;
}
mUrl = args.getString("URL");
mPostData = args.getString("POSTDATA");
mWebView.postUrl("https://fakeurls.org/", EncodingUtils.getBytes(mPostData, "BASE64"));
}
}
#Override
public void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
if (mWebView != null) {
mWebView.saveState(outState);
}
}
#Override
public void onDestroy() {
super.onDestroy();
mWebView.destroy();
}
private void instantiateWebView(View view) {
mWebView = (WebView) view.findViewById(R.id.webView);
mWebView.setWebViewClient(new WebViewClient());
mWebView.getSettings().setJavaScriptEnabled(true);
}
}
MyActivity.java
public class MyActivity extends AppCompatActivity {
private MyFragment mMyFragment;
#NonNull
public static Intent createIntent(Context context, String url, String postData) {
return new Intent(context, MyActivity.class).putExtra("URL", url)
.putExtra("POSTDATA", postData);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_link_viewer);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
mMyFragment = (MyFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_frame);
if (mMyFragment == null) {
final String url = getIntent().getStringExtra("URL");
final String postData = getIntent().getStringExtra("POSTDATA");
mMyFragment = MyFragment.newInstance(url, postData);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_frame, mMyFragment)
.commitNow();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void finish() {
mMyFragment.cancelTasks();
super.finish();
}
}
Please let me know how to resolve the issue and not reload the webview but retain display on orientation change. Any help is appreciated.

Menu object is coming null when it is getting called as a callback function

I have a requirement of placing a progressbar in the actionbar/toolbar. I am able to do it by following this link(http://www.michenux.net/android-refresh-item-action-bar-circular-progressbar-578.html).
However I am facing an issue in order to show and hide the progressbar, following the callback design pattern which I have used here. Below is code snippet -
public interface ICallBack {
void setRefreshActionButtonState(boolean b);
}
public class MyFragment extends Fragment implements View.OnClickListener, ICallBack {
private Menu optionsMenu;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
webView = (WebView) findViewById(R.id.main_web);
webView.setWebViewClient(new MyWebViewClient());
webView.loadUrl("http://stackoverflow.com/");
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
this.optionsMenu = menu;
getActivity().getMenuInflater().inflate(R.menu.menu_home_base, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_refresh) {
// Logic to load the webview again
}
return super.onOptionsItemSelected(item);
}
#Override
public void setRefreshActionButtonState(boolean refreshing) {
if (optionsMenu != null) {
final MenuItem refreshItem = optionsMenu.findItem(R.id.action_refresh);
if (refreshItem != null) {
if (refreshing) {
refreshItem.setActionView(R.layout.toolbar_indeterminate_progress);
} else {
refreshItem.setActionView(null);
}
}
}
}
}
public class MyWebViewClient extends WebViewClient {
ICallBack callBack;
public MyWebViewClient(Activity context) {
callBack = new MyFragment();
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
callBack.setRefreshActionButtonState(true);//Showing the progressbar
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
callBack.setRefreshActionButtonState(false);//Hiding the progressbar
}
}
When setRefreshActionButtonState() gets call then I am getting optionsMenu value as null, resulting not able to show and hide the progressbar.
Can someone help me to figure out that where I am doing wrong.
Thanks,
Can you upload the xml where the item action_refresh is. The problem could be in findItem(R.id.action_refresh);

Adding ProgressBar into WebView Fragment

i'm finishing my app, is a simple app that contains some WebView Fragments and a Navigation Drawer, everything is OK, but I don't know how to add a progress bar while the WebView is loading a page, all I got is a blank screen before the page loads.
Here is my code...
HomeFragment.java
public class HomeFragment extends Fragment {
private WebView webView;
public HomeFragment() {
// Required empty public constructor
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mainView = (View) inflater.inflate(R.layout.fragment_my_fragment1, container, false);
WebView webView = (WebView)mainView.findViewById(R.id.webview);
webView.setWebViewClient(new MantenerDominioWeb());
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(false);
webView.getSettings().setSupportZoom(false);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setDomStorageEnabled(true);
webView.canGoBack();
webView.goBack();
webView.loadUrl("http://www.lfcchile.com/");
return mainView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onDetach() {
super.onDetach();
}
}
My WebViewClient class
public class MantenerDominioWeb extends WebViewClient {
private WebView webView;
public ProgressBar progressBarT4;
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getHost().endsWith("lfcchile.com") || (Uri.parse(url).getHost().endsWith("thisisanfield.com")) || (Uri.parse(url).getHost().endsWith("liverpoolecho.co.uk")) || (Uri.parse(url).getHost().endsWith("liverpoolfc.com"))) {
return false;
}
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
view.getContext().startActivity(intent);
return true;
}
}
And my Frame XML
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context="com.lfcchile.MyFragment1">
<!-- TODO: Update blank fragment layout -->
<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:gravity="center"
android:text="#string/homefrag" />
<WebView
android:id="#+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ProgressBar
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:id="#+id/progressBar1"/>
</FrameLayout>
Any ideas please? I tried to put the progressBar "in front" of the WebView, but when the page is loaded the icon doesn't dissapear...
I believe it is not possible to put a progressbar because each site has a certain size, it would be difficult to measure it before finalizing the download page.
But you can place a pre-loader (loading) while the page is loaded and after the end you remove access for the user.
Use ProgressDialog:
public class HomeFragment extends Fragment {
private ProgressDialog progress;
private WebView webView;
public HomeFragment() {
// Required empty public constructor
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mainView = (View) inflater.inflate(R.layout.fragment_my_fragment1, container, false);
WebView webView = (WebView)mainView.findViewById(R.id.webview);
webView.setWebViewClient(new MantenerDominioWeb());
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(false);
webView.getSettings().setSupportZoom(false);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setDomStorageEnabled(true);
webView.canGoBack();
webView.goBack();
webView.loadUrl("http://www.lfcchile.com/");
progress = ProgressDialog.show(this, "Aguarde...",
"Processando sua solicitação.", true);
webView.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
if (progress != null)
progress.dismiss();
}
});
return mainView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onDetach() {
super.onDetach();
}
}
Set your ProgressBar to visibility="gone" to start
In your WebViewClient subclass, override onPageStarted() to set the visibility of the ProgressBar to VISIBLE
In your WebViewClient subclass, override onPageFinished() to set the visibility of the ProgressBar to GONE
Create a WebChromeClient subclass overriding onProgressChanged() to update the progress value of the ProgressBar
Add the WebChromeClient subclass to the WebView by calling WebView.setWebChromeClient()

Non-static method 'onResume' Android Studio

I want to use a WebView for Youtube. When I try to compile it, I get this error "non-static method onResume & onPause cannot be referenced from a static context".
I have tried to use a rootView, but it didn't work ='(
public class vod extends Fragment {
public static final String TAG = "vod";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.vod, container, false);
WebView wv = (WebView)rootView.findViewById(R.id.webView2);
wv.getSettings().setJavaScriptEnabled(true);
wv.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
}
});
wv.setWebViewClient(
new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return false;
}
});
wv.loadUrl("https://www.youtube.com/user/XX");
wv.addJavascriptInterface(new WebSocketFactory(wv), "WebSocketFactory");
return rootView;
}
#Override
public void onResume()
{
super.onResume();
WebView.onResume();
}
#Override
public void onPause()
{
super.onPause();
WebView.onPause();
}
}
I don't know how to resolve this. I need your help =)
Thank you =)
Make your wv variable as class member and use it then like this:
private WebView wv;
// onCreateView ...
#Override
public void onResume()
{
super.onResume();
wv.onResume();
}
And same with onPause...
You are trying to call the non-static methods onResume and onPause from WebView, but are accessing them in a static way. Either way, what you are doing makes no sense. Calling lifecycle methods manually is unnecessary and should be avoided. You can get rid of your onResume and onPause methods if you are only calling super.
If you want to call onResume and onPause from the Fragment, then use
wv.onResume and wv.onPause.
I modified your code below to solve your problem:
public class vod extends Fragment {
public static final String TAG = "vod";
private WebView wv;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.vod, container, false);
wv = (WebView)rootView.findViewById(R.id.webView2);
wv.getSettings().setJavaScriptEnabled(true);
wv.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
}
});
wv.setWebViewClient(
new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return false;
}
});
wv.loadUrl("https://www.youtube.com/user/XX");
wv.addJavascriptInterface(new WebSocketFactory(wv), "WebSocketFactory");
return rootView;
}
#Override
public void onResume()
{
super.onResume();
wv.onResume();
}
#Override
public void onPause()
{
super.onPause();
wv.onPause();
}
}
Also, class names should start with a capital letter, by convention. So call your Fragment Vod instead of vod.

Preventing WebView from closing when clicked outside the webview

In my app, I load a WebView where users enter username/password and I don't want the webview to close should the users accidentally click outside of the webview since the page will have to make another network call to load this webview.
I know this can be done for Dialog (like so: dialog.setCanceledOnTouchOutside(true);) but couldn't find similar mechanism for webview.
Thanks!
Here is the code:
#SuppressLint("SetJavaScriptEnabled")
public class LoginDialogFragment extends DialogFragment {
private static final String TAG = LoginDialogFragment.class.getSimpleName();
View mainView = null;
WebView webView = null;
OnLoginSucceeded loginSucceeded = null;
ProgressBar progressBar = null;
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mainView = inflater.inflate(R.layout.webview, container, false);
if (getDialog() != null)
getDialog().setTitle(getString(R.string.login));
webView = (WebView) mainView.findViewById(R.id.webview);
//display the progress bar
progressBar = (ProgressBar) mainView.findViewById(R.id.user_profile_loading_progress);
progressBar.setVisibility(View.VISIBLE);
//turn caching off
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setPluginsEnabled(true);
webView.setWebChromeClient(new WebChromeClient() {
});
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
Log.i(TAG, "URL received in onCreateView's onPageStarted is: " + url);
new HandleRequest().execute(url);
}
#Override
public void onPageFinished(WebView view, String url) {
}
});
new FetchLoginFormTask().execute();
return mainView;
}
I found my answer here and I just used getDialog().setCanceledOnTouchOutside(false); ensuring that when back key is clicked, the webview is dismissed.
Try with override the method:
#Override
public void setCancelable(boolean cancelable) {
super.setCancelable(false);
}
If your issue is not getting solved by this then please put some code so i can help you.
Feel free for comment.

Categories

Resources