Steps to repro
Log in to FB with new FB account I can see the webdialog showing me
current goals and other stuff, but I can not see Authorize OK cancel
buttons(probably moved down). I can not scroll to see those buttons
Can any one suggest me quick fix, without necessarily updating FB SDK
I can confirm this is affecting Facebook SDK 2 and 3 in Android. I can't speak to iOS. For some reason, scrollbars are disabled in their WebDialog.java code so I tried enabling scrollbars in setUpWebView. Scrollbars now appear in this prompt but the OK and Cancel buttons aren't there. So, it's not a case of the buttons being off-screen and unreachable but rather the buttons aren't part of the content at all when the Current Goals section is included.
It looks like this is a problem Facebook will need to resolve on their side.
I just posted this workaround to: webDialog "CURRENT GOALS" header but no button to authorize or cancel
In the FaceBookSDK I modified com/facebook/widget/WebDialog.java, so that once the web dialog was loaded it would look for the block that contains "Current Goals" and hide it (if it exists). Once you do that, the buttons are visible again (at least they were for me).
In com/facebook/widget/WebDialog.java:
private class DialogWebViewClient extends WebViewClient {
// ... other methods ...
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (!isDetached) {
spinner.dismiss();
}
/*
* Once web view is fully loaded, set the contentFrameLayout background to be transparent
* and make visible the 'x' image.
*/
contentFrameLayout.setBackgroundColor(Color.TRANSPARENT);
webView.setVisibility(View.VISIBLE);
crossImageView.setVisibility(View.VISIBLE);
// I don't know how to highlight in the code block
// So I just add this extra long comment to make it obvious
// Add a javascript call to hide that element, if it exists
webView.loadUrl("javascript:try{ document.getElementById('nux-missions-bar').style.display='none'; } catch (e) {}");
// End changes
}
This should help, at least until FaceBook fixes the API.
I was facing the same problem which is solved. I just changed my app permission which was running in sandbox mode> I just changed it to live mode and suddenly everything started working fine. I think there was a problem with fb sdk which is solved by now.....
Related
Masters,
I have a question. I've been building an Android App using WebView. Inside the app are links that navigates to external pages(I don't have any control with the WebSite that is loaded inside webview). I have an issue when I clicked a link and logCat returns : I/chromium: [INFO:CONSOLE(10)] "Uncaught TypeError: Cannot read property 'appendChild' of null" App displays white screen only. Have you experienced this issue before? Are there any possible solutions? TIA
To clarify the extent of the problem
What you currently have problem is with
Inside the app are links that navigates to external pages.
I have an
issue when I clicked a link and logCat returns
As you haven't shared your code both for webview(Android) or html code.
As I am faced similar type of problem, So these are method which solved my problems
Method 1:
public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
view.loadUrl(urlNewString); // you are using siteView here instead of view
return true;
}
Method 2: use http in url
Make sure the url starts with http://.
Without http it will just show white screen.
Would like to ask for some advice on what's best way to implement on enabling and disabling the web view on Android?
I have this app wherein it can open urls within (by using web views) which then popups up and covers 80% of the UI, when the user navigates to another page of the app it should hide/close the web view but can be re-opened again when needed.
Here's a snippet of the code
private WebViewInterface webViewInterface = new WebViewInterface() {
#Override
public void onOpenURL(String url) {
navBrowserWV.setVisibility(View.VISIBLE);
navBrowserWV.getSettings().setJavaScriptEnabled(true);
navBrowserWV.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
handler.proceed();
}
});
navBrowserWV.loadUrl(url);
}
};
then this is how I close it
private void closeWebView() {
Log.d(LOGTAG, "closing webview...");
// Destroy WebView if it exists
if (this.navBrowserWV != null) {
this.navBrowserWV.stopLoading();
this.navBrowserWV.loadUrl("about:blank");
this.navBrowserWV.clearHistory();
this.navBrowserWV.clearCache(true);
this.navBrowserWV.pauseTimers();
this.navBrowserWV.setVisibility(View.GONE);
}
}
The problem with this implementation is that it displays the page properly at first but when I close it and then open the web view again with a url, it does not load the page anymore just a white background (no errors on the logger btw).
Would like to ask for help on how to resolve this one. Thanks
Finally, after a long time of digging up answers on the internet I found this old post regarding killing Android webview [link].
There's no real way to kill the WebView (it will always run in your process and you can't do anything about it ATM). So you only have to tell the WebView to load a bogus page, for me I did:
this.navBrowserWV.loadUrl("about:blank");
And it works now!
Quote from the website
4.1 .getSettings().setJavaScriptEnabled() Inhalt
Well, you would think that disabling JavaScript in the WebView’s settings would have an instant effect, in short: it does not. Only after reloading the page would there be no javascript any more, and this is not nice by design, since the page is still more or less well rendered.
4.2 .stopLoading() Inhalt
Since XHR „loads“ something from another server, you might think that calling „webview.stopLoading()“ would have an effect. In short: it does not. Works only on ressources contained within the HTML-file. Pity, is it not… Well, maybe not, since there is no „startLoading()“ method to resume XHR after resuming the activity anyway.
4.3 .destroy() Inhalt
As a last resort one might think about „destroy()“ing that thing, and true enough, the WebView itself is not accessible after that. Its threads however continue to exist as zombies somewhere in the vast RAM space and also continue to send XHR requests…
4.4 .pauseTimers() / resumeTimers() Inhalt
In short: Nope, does not work. I even don’t know what these methods are good for if not for controlling JavaScript timers. There aren’t any in plain HTML, AFAIK.
Update: When it comes to timers only, these functions seem to work on 2.3.5 and upwards, however, when there is no timer active at the time of calling the function, all in vain. With my use case: When pausing the app while there is an XHR active (instead of the running timer that schedules the next XHR call), nothing happens and the next timer continues unhindered.
I hope this will help someone who has the same problem as mine.
I will try to explain this as clearly as possible. I have an android app using web view to basically load a webpage as my app. I have everything working great, however the back button seems to be an issue. I have set this page up all on one html page, it will load in a div when certain buttons are clicked to give the feel of a new page without actually having one. I basically want the back button (on the android tablet or smartphone) to load the previously loaded div, but I have no idea where to start with this. Here is what the content switching jquery looks like -
function contentSwitcher(settings){
var settings = {
contentClass : '.contentToLoad',
navigationId : '#sideMenu',
servFront : '#clickHomeHome'
};
//Hide all of the content except the first one on the nav
$(settings.contentClass).not(':first').hide();
$(settings.navigationId).find('li:first').addClass('active');
//onClick set the active state,
//hide the content panels and show the correct one
$(settings.navigationId).find('a').click(function(e){
var contentToShow = $(this).attr('href');
contentToShow = $(contentToShow);
//dissable normal link behaviour
e.preventDefault();
//set the proper active class for active state css
$(settings.navigationId).find('li').removeClass('active');
$(this).parent('li').addClass('active');
//hide the old content and show the new
$(settings.contentClass).hide();
contentToShow.show("slow");
});
}
contentSwitcher();
});
note: I've cropped out a bunch of it just to show how it works on a basic level.
Does anyone have any suggestions as to where to begin. I'd just like the back button function to be able to maybe check a started previous div name stored somewhere and load that.
thanks!
You can try using the History API. There are numerous tutorials on the web e.g. this one is quite good:
http://diveintohtml5.info/history.html
Basically this is how it works. When the user clicks the link for the div to show you push the state to the history stack.
history.pushState({<object with any information about state>}, pageTitle, newUrl);
This will push the state to the history stack meaning that when the user presses the back button on any modern browser like webkit it will take that state into consideration. When back action is taken it will then pop the state from the history stack. This action you have to listen to and handle in any way you see fit:
window.addEventListener("popstate", function(event) {
// event object contains the information from the pushed state
// do whatever needed to load the previous page here
});
The History API requires you to structure your code in a certain way for it to work well. For this I would recommend to use some existing framework that handle the back events for you e.g. Backbone.js. Hope this helps.
I have a webview that shows ads (not my ads), the problem is when user clicks the "x" button to exit the ad, the ad still directs them to a site. What I wonder is since I can't control the ads, can I instead Disable page directing/forwarding inside webview? that means even if user clicks a link inside my webview nothing should happen.
You are looking for WebClient.shouldOverrideUrlLoading method.
webview.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading (WebView view, String url){
//True if the host application wants to leave the current WebView and handle the url itself, otherwise return false.
return true;
}
});
I tried using shouldOverrideUrlLoading, but it didn't work. It looks like that this method is called only once when the html is loaded. After that, you click a link but the method is no more invoked.
I am also making a WebView embedding Youtube Player. Instead of forwarding ads redirect from the WebView, I prefer to open ads in a browser. So I override onLoadResource method:
#Override
public void onLoadResource(final WebView view, final String url) {
if(url.indexOf("googleadservices.")>-1){
view.getSettings().setJavaScriptEnabled(false);
view.stopLoading();
view.postDelayed(
new Runnable(){
#Override
public void run(){
Uri uri=Uri.parse(url);
Intent i=new Intent(Intent.ACTION_VIEW,uri);
i.setClassName("com.android.browser","com.android.browser.BrowserActivity");
startActivity(i);
}
}
,100
);
}
}
It worked. When I clicked the ads link, a new browser is opened in which ads site is displayed well, and the WebView was not redirected. When I push the return button, WebView show up again and I can continue watching video.
But there were still problems. If I repeat opening browser and returning to WebView for many times, the WebView might fail to block redirecting to the ads site. It is just redirected to the ads site. If I am lucky I could repeat opening and returning for 100 times. But sometimes It failed just when I repeat several times. I don't know why.
Does anyboday have any idea about how to improve it? Or is there another way to disable ads redirect?
You can build undetected webview build-id adblocker
I know it is too late for answering this question, however, for the sake of others who have the same question.
Well, you can build webview build-id adblocker, if you wish to prevent ads from loading, and provide smooth experience to the users, I am confident, because I have already implemented it in may app.
The Idea
Is to have a black list of all possible ad-serves domain name, then while webview load resources, you will prevent loading from black list domains. so it depends on how many ads-serves domain you have in the black list, fortunately, there is one website (pgl.yoyo.org/as/) which provide you with a very long list of ad-serves domai names, and listed them in many flavoures.
you can read this article for:
how to implement webview build-id adblocker
, you will build it %100 as long as you follow step by step instructions.
A summary of what we need to do:
Get the list of ad hostnames from pgl.yoyo.org.
Save the list somewhere, load it when application starts.
UseWebViewClient.shouldInterceptRequest(WebView, String) to intercept
requests.
Check if the request URL belongs to one of the hostnames in
the list and override it, returning a dummy resource instead of the
actual one, which is supposed to be ads
I have a small phonegap application with jquery mobile and backbone.
I'm trying to show popup to user by manually calling .popup() method.
Everything works fine on iOS but on android I got strange issue: popup is showing for few moments and than disappear.
Here the actual code:
var PostView = Backbone.View.extend({
events: {
'touchend .add-comment-button': 'addComment'
},
addComment: function() {
this.$(".comment-popup").popup('open', { history: false });
return false; // Stop bubbling.
}
});
I'm using history: false because this popup is actualy part of subpage.
The code looks very simple, I'm just can't understand why it can disappear, and why this happen only on android devices.
Thanks, and sorry for my bad english.
I spent hours trying to fix this problem.
Finally I ended up doing the following two things that seemed to fix the problem.
1 - Use the uncompressed jqm file. i.e jquery.mobile.1.2.0.js
2 - I was triggering the popup programatically using the 'tap' option - once changed to the 'click' option it worked.
$('.option').live('click', function() {
$('#popup-div').popup('open');
});
I spent hours trying to fix this problem.
Finally I ended up doing the following two things that seemed to fix the problem.
this code snippet may help you ->
$('#testBtn').on('tap',function(e){
console.log("button clicked");
e.preventDefault();
$('#testPOPUP').popup("open");
});
Please note i have used e.perventDefault().
I didn't feel like changing my .tap() events to the click event and I didn't have a case where I could use preventDefault()so I just added a timeout to the popup('open') line. My hoverdelay in jqm is set to 150 so I set this timeout to 600 just to be on the safe side. Works fine, doesn't feel sluggish for the user.
One way to 'fix' it is by setting data-history="false" on the popup div
See also this question
JQuery Mobile popup with history=false autocloses
I have the exact same problem when trying to use popup('open') on an android 2.3 device (both in native browser and in firefox) and it works just fine on browsers on other devices. I'm also using backbone event management to open my popup (used the tap event and no aditionnal options to popup).
What I did to 'correct' the problem is that I removed the backbone event management for this event and added a listener in the render function. In your case this would look something like this :
events: {
// 'touchend .add-comment-button': 'addComment'
},
render: function() {
$(this.el).html(this.template(this.model));
$(this.el).find('.add-comment-button').tap(function(el){
this.addComment(el);
return false;
}.bind(this));
}
I have no idea where the problem comes from (must be some incompatibility between backbone and jquery mobile) and why we only see it on android but for the moment with this workaround my app seems to work fine on any device.
Edit: oops, it turns out that in my case the problem was I was missing "return false;" in the function dealing with the event.
Now that I added it, it works correctly with the backbone event management.
Sadly that doesn't explain why you have the issue and why I was seeing it only on android.
In case it helps anyone, I had the same problem occurring with Bing Maps, with the Microsoft.Maps.Events.addHandler(pin, 'click', callback) method.
Not particularly nice, but instead I stored an ID in pushpin._id and did the following:
$("#page").on('vclick', function (event) {
if (event.target.parentElement.className === "MapPushpinBase") {
$("#stopPopup").popup('open');
}
});
One brute force option is to check whether popup was hidden and reopen it.
In a loop, because the exact time the popup becomes hidden seems to be varied.
var hidden = $('#' + id + '-popup') .hasClass ('ui-popup-hidden')
if (hidden) $('#' + id) .popup ('open')
A working example: http://jsfiddle.net/ArtemGr/hgbdv9s7/
Another option could be to bind to popupafterclose:
var reopener = function() {$('#' + id) .popup ('open')}
$('#' + id) .on ('popupafterclose', reopener)
$('#' + id) .popup ('open')
Like here: http://jsfiddle.net/ArtemGr/gmpczrdm/
But for some reason the popupafterclose binding fails to fire on iPhone 4 half of the time.