Communication with embedded (UI)Webviews in existing iOS and Android Apps - android

This app already exists in the Apple App store and Android markets. It is an app that uses a lot of native code and is not a candidate to be fully html5ed.
Longwinded Description
I want to have a Web-based series of settings pages. Some of these pages will live locally on the mobile device, and some will be hosted on a remote server. The native app will need to communicate with the local web pages to get and set information in the webpage using javascript.
For instance, the first page shown in the WebView/UIWebview will be a local index page. If the remote website is down, the links on the index page to the remote pages will be greyed out. On loading the WebView, the native app will need to detect the reachability of that page and send javascript to the page to grey out the buttons. Likewise, some settings changes made in the local web pages need to be sent back to the Native app for processing.
Short and Sweet Requirements Summary
Embed remote and local webpages in a webview
Theses webpages will be the same for both Android and iOS
Local pages use JavaScript to get data from and send data to the Native Mobile App
Potential Solution Pathways
A. PhoneGap
I realize that Phonegap would work well for this if my application was entirely a web app. From my reading it seems like Phonegap doesn't really like to be embedded in a native app for part time work.
What? You say it's really easy and I've been grossly misinformed? Enlighten me oh wise one.
B. Roll My Own
I'm open to rolling my own solution, however the methods for getting and setting information via Javascript from the Webviews to the Native Apps seems quite disparate. More-so the getting than the setting (bogus URLs for iOS, very nice AddJavaScriptInterface for Android). Also, it seems like this path could lead to a severe maintenance headache in the future.
Say what? Your genius programmer friend has made a website describing this process in excruciating detail? Tell me more.
C. 3rd Party Library
The perfect 3rd party library that does everything I want (and more!) exists? Save me from my ignorance.
Decision
In the future, it seems like PhoneGap's 'Cleaver' project will be the best way to do this.
Since it's not ready for Android yet, it seems that the current (Early June '12) best solution for write-once-embedded-HTML is to use a fake URL scheme to communicate from the web page to the native app (both platforms can execute JS on the page directly when going from native app to web page).

For Android this is simpler to do. Take a look at WebView's addJavascriptInterface method. You can create your own object with methods that can be called directly in the HTML javascript.
iOS requires a bit of trickyness. Best solution for these types of problems is a couple things:
For callbacks to iOS you will need to basically make up your own URL scheme like native://somehost.com/somepath When your javascript wants to inform the iOS code use window.location = 'native://somehost.com/somepath';
Set the UIWebView delegate to an object that defines webView:shouldStartLoadWithRequest:navigationType: it will look something like this
if ([request.URL.scheme isEqualToString:#"native"]){
if([request.URL.host isEqualToString:#"somehost.com"]) {
//Do the code you need to do here, branch off depending
//on the path and/or host, you can parse parameters here too
return NO; //This will keep UIWebView from trying to actually load
//your made up scheme
}
}
return YES; //If the request isn't one you want to intercept return YES/true
//so UIWebView will load the page
To have your iOS code send information or call functions in your javascript you can use WebView's stringByEvaluatingJavaScriptFromString:. This will return the result of a javascript expression so you can also use it to get some information from the page itself. To call a function use something like this
[webview stringByEvaluationgJavaScriptFromString:#"myJavaScriptFunction();"]
You can also handle the made up scheme in Android by creating a custom WebViewClient and overriding the shouldOverrideUrlLoading method similarly to the iOS code above except the return calls are backwards, you return true if you handled the URL and the WebView should do nothing more, and false if you want the WebView to handle loading. Be sure to create and assign the custom WebViewClient to the WebView using setWebViewClient. To call javascript functions on the actual WebView do something like webview.loadUrl("javascript:myJavaScriptFunction();");

PhoneGap iOS has a concept called Cleaver where you can embed the web view into a native iOS app. Randy McMillian has a good example here. On the Android side work is being done to bring the same functionality. So we are not there yet but we will get there.

Related

How to change Wordpress content when accessing using a specific URL

I have a Wordpress webpage working great, now I've been asked to develop an Android application with a simple web view that would load the webpage but when using the app it have to change some web behaviors.
Usually you go to the Home, and you have categories like: Services, last deals, projects...
The idea when using the app is going direct to the login page and change the menú categories, so some pages would be hidden and another ones would appear.
I've seen the #media way to do it, but I don't want to apply all these changes by resolution, but for type of device.
I checked this out: https://wordpress.org/plugins/simple-mobile-url-redirect/ but then when I redirect to the custom URL and I do the changes, I don't know how to preserve them, while navigating to other pages.
Is there any way of preserving that "mobile session"? or would it be a good choice to create a sub domine and replicate the webpage for mobile? (www.mobile.webpage.com)
I understand your situation and the best idea would be to generate screens using your own code. IN order to get the data from WordPress, you can call WP-Rest handles to get the data.
Alternatively if you only want to load webview, your web team will need to do custom code in order to facilitate your request. The idea is to send query variables to the website when calling from mobile app. Once the url is called, the WP code needs to set up transient/session/cookie and display custom result if transient/session/cookie is set.
I am sorry, I can't find the exact code that I used for somewhat similar work but if your web team has ever dealt with transient or custom session, they should be able to do this without any issue.

Response-time measuring apps on tablet: difference in latency between HTML and native Android/iOS?

I am investigating writing an HTML version of a native-tablet app (Android) that a research facility uses to test user response time. That is: a screen is presented for a set time and then the time it takes a user to choose a response is measured.
What would be helpful is to know is whether this is as easily done via HTML as via native code — I need to know exactly the time between the presentation of a screen to a user and the time they touch for a response. Since HTML rendering is under the command of the browser, is there are way to know — very precisely — when the screen is actually rendered to the user, and hence when the timer should start? My thinking is that it might be best to do something like set a div state from 'hidden' to 'visible' — or to use an animation library such as Greensock, but I feel this could be "every problem is a nail when all you've got is a hammer" — that is, these are the tools I know, I don't know whether these are what I should use.
I'm trying to get a sense of whether this is feasible — I've not done any native code tablet development, have done a fair amount of HTML, need to convince them to switch if I'm going to do the work. Thanks for any info you can provide.
Maybe you could use javascript & JQuery in your HTML page to record the exact time of loading?
$(document).ready(function(){ //notice that $(document).ready is JQuery
// Your code here
});
I guess you call native Android methods via javascript in you WebView, but if not you can do so by first injecting your Object containing methods to be called when page is loaded:
WebView webView = (WebView) findViewById(R.id.webview);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
Then, the JQuery code above to notify a Java Object would be:
$(document).ready(function(){
Android.documentReady(); // method to call in Java Object
});
Notice:
This is highly experimental and I do not know whether it is a good idea to load JQuery into your WebApp, but as JQuery is used everywhere it should not be a problem.
Anyway, $(document).ready(function...) is called when the document/html page is fully loaded - doing a similar "listener" in standard javascript is not recommended, but possible. (more info if you want to skip JQuery; https://stackoverflow.com/a/7053197/3911640 )
More info about using JavaScript to call native Android Objects: http://developer.android.com/guide/webapps/webview.html
EDIT:
You could also do this with HTML5:
<body onload="Android.documentReady()">
Notice:
Not my area of expertise and not tested, but practically possible. I'd advice you to research which way is the fastest most reliable, but in theory both should be invoked when everything (images etc included) is loaded and presented to the user.
W3C documentation of the HTML5 functions: http://www.w3schools.com/jsref/dom_obj_event.asp

Execute Javascript in Chrome from AccessibilityService

i want to write an AccessibilityService which should help the user to fill forms. I saw the possibility to call Javascript code via WebView.loadUrl(). But since i've just the AccessibilityNodeInfo i only see that the WebView is on the screen.
After some research, i saw that TalkBackService is able to inject Javascript, and in a different post (Alternative way for communication between WebView and native) i saw its possible if i have a reference to the WebView-object.
Is there a way to execute JavaScript via such an Message or an Broadcast Intent in chromes WebView?
Would be really great if someone could help me!
Thanks a lot!
Chrome doesn't use a WebView, Chrome uses it's own rendering engine. While some of the code ends up being shared with the WebView (as in the two end up being compiled from the same source code) that's where the similarity ends.
I don't think there is a way to inject JavaScript into Chrome via an Intent - that would be a pretty big security hole (otherwise someone could inject a "send me all your money" JavaScript into your bank's page).
Accessibility is not my area of expertise so I can be totally off here but I believe newer versions of Chrome expose the web contents structure to the accessibility layer and therefore you should be able to do your thing without any custom JavaScript. I think you can check this using uiautomatorviewer: for me the tool shows html forms when I grab a dump of Chrome's UI. Is that not the case for you?

Webview load remote url

First, a disclaimer: i'm completely new to iphone, android or any mobile development. In the other side, i've been developing websites (php, javascript) for long time.
I have a website which is adapted for mobile and works great. But, there are some features i need such as prevent the screen from dimming (my site is designed to be used for many hours without user interaction while being permanently visible or for example being able to send notifications (with sound, etc., to attract user attention)).
This has lead me to consider a webview. From what i've seen, it's about creating a native app which just a webview (browser without toolbars) and using html and javascript to operate. It will use some native functions to perform some native actions (such as the ones i want).
I've searched around and i don't have a specific response to this: can i tell a webview to, permanently load the content from a remote site ? i mean, my site is php based (zend), with many jquery content manipulation. Can i tell him something like LOAD htp://www.mysyite.com and let him do everything else from it ? absolutely no local content applies, everything is remote. The webview would just be an "interface" to the website.
And additional question is: can i use jquery on it ? ajax calls ? geolocation ? i mean, in a browser i can, i just wonder if inside a webview i can.
I've read that phonegap does this. But most of the time, when taking about phonegap and about webview i general, i read people talking about loading locally the page not remotely in a permanent basis.
Finally, yes, i will build a native app in the future. But now, i simply don't have time to learn about android, ios and blackberry at the same time. Thanks a lot for your responses.
For Android only:
Can i tell him something like LOAD htp://www.mysyite.com and let him do everything else from it ? absolutely no local content applies, everything is remote. The webview would just be an "interface" to the website.
Yes, of course you can. Suppose you have a webview in an activity (it's really easy), you would load the web page something like:
WebView myWebView = .... // get a reference from XML or if you just created get its ref
myWebView.loadURL("http://www.mysite.com");
I would start with this API Guide article. Also, taken from WebView JavaDoc:
A WebView has several customization points where you can add your own behavior. These are:
Creating and setting a WebChromeClient subclass. This class is called when something that might impact a browser UI happens, for instance, progress updates and JavaScript alerts are sent here (see Debugging Tasks)
Creating and setting a WebViewClient subclass. It will be called when things happen that impact the rendering of the content, eg, errors or form submissions. You can also intercept URL loading here (via shouldOverrideUrlLoading()).
Modifying the WebSettings, such as enabling JavaScript with setJavaScriptEnabled().
Injecting Java objects into the WebView using the addJavascriptInterface(Object, String) method. This method allows you to inject Java objects into a page's JavaScript context, so that they can be accessed by JavaScript in the page.
Please be also aware that the webview is not that powerful as the phone's browser. Here is a SO thread where a friend posted an interesting question. You might find helpful the answers he got.

Android SDK vs. HTML5 for Android non-realtime app

Suppose I want to write an app for Android OS that is not going to be a real-time game; that is, it will be a turn based game (requiring internet access) that is based on forms and pages.
I'd like to use HTML5 to do this, and simply have a WebView on the native app with some bindings to the website's javascript, etc. for more functionality (if needed). Of course, since this is not a realtime game, performance doesn't seem like it would be an issue.
The only real reason I can think of to not use HTML5, is because there would be loading times in between forms e.g. every time a user clicks on a button to perform an action that transitions them to a new form, which is actually a new web page, that web page must be loaded. If I did this natively using the Android SDK, the loading of the forms would be seamless and instantaneous (even though the web up/down will take a small amount of time, but that is expected).
Is this a real issue? Are there ways around it that don't involve using the Android SDK instead of HTML5?
A couple of ideas:
1) Bundle your HTML with the app in the folder called assets and load it from there with an URL like file:///android_asset/your_path.html. This will reduce the time required to load because the content will be on the device.
However, beware of the following webview bug in Android 3.0+ that causes any URL with # or ? to fail to load from the assets folder:
http://code.google.com/p/android/issues/detail?id=17535
2) You can also choose to use AJAX to reduce the page load time. You load the heavy libraries once in the beginning and then use AJAX for subsequent page loads to avoid loading a lot of JS stuff. But beware of the bug above, since AJAX page loads use # in the URL.

Categories

Resources