Maintain navigation history in WebView - android-webview

In my app I have main activity and child activities. An action on main activity opens a child activity. Each child activity loads web page that have various urls all pointing to server locations.
I am able to navigate to all the urls but when I press back, I am not redirected to the previous page. Instead it exists and brings me to main activity. The back button action should navigate to last url location. How to do that?

You need to add each url to a List object and then use that object to navigate back.
private LinkedList<String> navigationHistory;
#Override
protected void onCreate(Bundle savedInstanceState) {
....
mWebView.setWebViewClient(new MyWebViewClient());
....
}
#Override
public void onBackPressed() {
if (navigationHistory.size() > 0) // Check if the url is empty
{
navigationHistory.removeLast(); // Remove the last url
if (navigationHistory.size() > 0) {
// Load the last page
mWebView.loadUrl(navigationHistory.getLast());
} else {
super.onBackPressed();
}
} else {
super.onBackPressed();
}
}
private class MyWebViewClient extends WebViewClient {
#Override
public void onPageFinished(WebView view, String url) {
if (!navigationHistory.contains(url)) // Check for duplicate urls
navigationHistory.add(url); // add each loading url to List
super.onPageFinished(view, url);
}
}

Related

Spotfire Redirecting to home after link click

Ask: Have a button that when clicked downloads a file from a folder on the server and remains on the current page.
Current state and problem: I have a CustomWizardPromptControlPage that writes a simple button to the HTMLTextWriter. The onclick event for the button fires off a window.open(urlToDocument, '_blank'). By doing the button with the onclick it does actually allow me to download the file, however the parent page redirects to the home page.
Already tried: href - didn't download the file and redirected me to the home page. form submit - didn't do anything.
If anyone can give me some insight as to why Spotfire does this and what I can do to stop it from happening it would be greatly appreciated
--Follow up with working code sample for comments request
namespace ACompanyName.SpotFire.ExportWithFilters
{
public class ExportWithFiltersWebPromptControl : CustomWizardPromptControl
{
public ExportWithFiltersWebPromptControl(ExportWithFiltersFileSettings settings)
{
this.AddPage(new ExportWithFiltersPage(settings));
}
private class ExportWithFiltersPage : CustomWizardPromptControlPage
{
private readonly ExportWithFiltersFileSettings _settings;
public ExportWithFiltersPage(ExportWithFiltersFileSettings settings) : base("Export with Filters")
{
_settings = settings;
}
protected override void OnGetContentsCore(HtmlTextWriter writer)
{
var domain = "https://dev.AURL.com";
var filename = _settings.ExportWithFiltersFileInfo.Name;
var fullFilePath = string.Format("{0}/{1}/{2}", domain, "Exports", filename);
writer.WriteLine("Download Export with Filters", fullFilePath);
}
protected override void OnGetScriptsCore(StringBuilder builder)
{
}
protected override void OnLeavePageCore(FormData data)
{
}
protected override bool OnValidatePromptCore(FormData data)
{
return true;
}
}
}
}
Turned out that Spotfire didn't like putting <button> into the page. Swapped it out with an hyperlink with a target of blank and it worked like a charm. If a button is still desired, stylized div should do the trick.

Android WebView in a ViewSwitcher loadUrl loads once

I have in my ViewSwitcher a ListView and a WebView. In my ListView's adapter, I have an onclick listener that writes the clicked url in the list to sharedpreferences. I'm trying to load that url into the WebView using an onSharedPreferencesChangedListener.
This is the code in my adapter:
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewSwitcher.showNext();
Settings.writeSettings(context, "webviewUrl",
urls.get(position));
}
});
return convertView;
And in the preference listener:
#Override
public void onSharedPreferenceChanged(SharedPreferences pref, String key) {
if (key.equals("webviewUrl")) {
Log.d("TAG", pref.getString(key, null));
WebView wv = (WebView) findViewById(R.id.rss_webview);
wv.getSettings().setJavaScriptEnabled(true);
wv.setWebViewClient(new MyWebViewClient());
wv.loadUrl("about:blank");
wv.loadUrl(pref.getString(key, null));
}
}
This works great except it only works once. The preference listener code logs the correct urls, and the code executes each time I want it to, but wv.loadUrl() method seems to do nothing after the first successful call. Can anyone explain to me why this is happening and perhaps offer a solution? Thanks.
I solved the problem by implementing a static ViewHolder on the WebView whose reference I needed to keep longer than its views' lifecycle.
private static final class WebViewHolder {
WebView wv;
}
#Override
public void onSharedPreferenceChanged(SharedPreferences pref, String key) {
WebViewHolder holder = new WebViewHolder();
if (key.equals("webviewUrl")) {
if (wv == null) {
wv = new WebView(this);
holder.wv = (WebView) findViewById(R.id.rss_webview);
holder.wv.getSettings().setJavaScriptEnabled(true);
holder.wv.setWebViewClient(new MyWebViewClient());
wv.setTag(holder);
} else {
holder = (WebViewHolder) wv.getTag();
}
holder.wv.loadUrl("about:blank");
holder.wv.loadUrl(pref.getString(key, null));
}
}

Page is not being loaded in GWT

I am using activities and places to develop my application. When I click on the link on the left, my page is loaded, and I put the values in the fields. After I put the values, I send a RPC to the server, and get response back. This is also shown. Now the problem is that even if I click on the link on the left, I am getting the result page again. I am not getting the input page.
Impl code
#UiHandler("entInvoiceCompare")
void onClickSubmit(ClickEvent e) {
GWT.log("Going to enterprise compare place");
//listener.goTo(new EnterpriseInvoiceCompareViewPlace());
NewEBRM.getClientFactory().getPlaceController().goTo(new EnterpriseInvoiceCompareViewPlace());
}
Place
public class EnterpriseInvoiceCompareViewPlace extends Place{
public EnterpriseInvoiceCompareViewPlace() {
GWT.log("EnterpriseInvoiceCompareViewPlace: constructor");
}
public static class Tokenizer implements PlaceTokenizer<EnterpriseInvoiceCompareViewPlace> {
#Override
public String getToken(EnterpriseInvoiceCompareViewPlace place {
GWT.log("EnterpriseInvoiceCompareViewPlace: getToken: call");
return "EntInvoiceCompare";
}
#Override
public EnterpriseInvoiceCompareViewPlace getPlace(String token) {
GWT.log("EnterpriseInvoiceCompareViewPlace: getPlace: call");
return new EnterpriseInvoiceCompareViewPlace();
}
}
}
Activity
#Override
public void start(AcceptsOneWidget containerWidget, EventBus eventBus) {
// TODO Auto-generated method stub
GWT.log("EnterpriseInvoiceCompareActivity: start: starting activity");
EnterpriseInvoiceCompareView entInvoiceCompareView = clientFactory.getEnterpriseInvoiceCompareView();
entInvoiceCompareView.setPresenter(this);
containerWidget.setWidget(entInvoiceCompareView.asWidget());
GWT.log("EnterpriseInvoiceCompareActivity: start: ending activity");
}

Link to last version of stateful page

I have a number of stateful pages with some state for each page. For example each page has a form that was submitted.
How can I organize a menu with links to last versions of these stateful pages? Should I store anywhere (may be in the session) reference to appropriate object for each page? If I use
onClick() { setResponsePage(MyPage.class); }
than I lose the previous state of the page. I want to link to last state of the page.
Each time the page is rendered store the page's id in the session.
int pageId = pageInstance.getPageId();
A list or stack data structure could be used to hold the identifiers.
You can implement the navigation menu using a repeater (RepeatingView or such) that creates a new link for each page id in the session.
In the link's click handler you can redirect the user as follows:
Page pageInstance = (Page) new PageProvider(pageId, null).getPageInstance();
setResponsePage(pageInstance);
pageId = this.getPageId(); // get current version of lets say a HomePage
//OnClick for Link
public void onClick()
{
WebPage homePageInstance =
(WebPage) new PageProvider(HomePage.pageId, null).getPageInstance();
setResponsePage(homePageInstance);
}
});
I make it passing int previousId parameter via constructor :
#MountPath(value = "editSomethingPage")
public class TestPage extends WebPage {
int previousPageId = 0;
public TestPage(int previousPage) {
super();
this.previousPageId = previousPage;
}
#Override
protected void onInitialize() {
super.onInitialize();
add(new Link("goBack") {
#Override
public void onClick() {
if (previousPageId != 0) {
setResponsePage((Page) AuthenticatedWebSession.get().getPageManager().getPage(previousPageId));
} else {
setResponsePage(PreviousPage.class);
}
}
});
}
}
It prevents creation of new page instance and keeps all states of page made by user.

How to create a simple android browser?

I simply want to create an apk that will take a url, and open a window and simply run like a browser
so far I have:
public class Browser extends Activity {
WebView mWebView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.loadUrl("http://www.google.com");
}
}
This works fine, except when i open a link it'll take me to the actual browser, I'm having trouble where to place this code to override links opening in a new browser:
private class HelloWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
WebView has a setWebViewClient method.
so you'd do something like
mWebView.setWebViewClient(new HelloWebViewClient());
Check out my project called FriarFramework, which is an ebook app publisher.
It basically takes a collection of HTML files locally and packages them up into a WebView.
https://github.com/hanchang/Friar-Framework
Try this
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
progressBar.setVisibility(View.GONE);
}
});
mWebView.setWebViewClient(new HelloWebViewClient());
This should be enough.
for more see the official doc about Building web apps in WebView
You have to implement WebViewClient.
You can detect URL inside shouldOverrideUrlLoading() method:
browser.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// You can have URL here
}
});