I'm new to Pact.io and trying to get contract tests set up on our platform. The app is set up in such a way that each customer account has its own database schema which is directly tied to a URL subdomain. When making an API request, that URL subdomain must be provided in addition to the authorization header. I can create a static token to pass in with the consumer tests, but when Pact sends the request, it doesn't know which account to use. I don't see a way to pass in a URL subdomain as part of the consumer test and not sure how to force it to use a specific account on the provider side? Any ideas?
Here is the pact log. We are making a request for users and instead of the JSON body being returned, we get an HTML error page, even though the status code returns 200.
I, [2017-10-25T12:39:24.344559 #91639] INFO -- : Running example 'Verifying a pact between bridge_perform and bridge_learn Given one user a get request for learn users with GET /api/learner/users returns a response which has a matching body'
I, [2017-10-25T12:41:40.962186 #91639] INFO -- : Sending GET request to path: "/api/learner/users" with headers: {"HTTP_AUTHORIZATION"=>"Basic xxxxxxxxxxxxxxxxxxxxx"}, see debug logs for body
D, [2017-10-25T12:41:40.962234 #91639] DEBUG -- : body :
I, [2017-10-25T12:41:40.977995 #91639] INFO -- : Received response with status: 200, headers: {"Content-Type"=>"text/html", "ETag"=>"W/\"1bd857d3e20d3ed50aa6f48b5be15f42\"", "Cache-Control"=>"max-age=0, private, must-revalidate", "X-Request-Id"=>"8dd9a9bf-da21-44b1-8b6b-9de486a7e9ea", "X-Runtime"=>"0.007579", "Content-Length"=>"630"}, see debug logs for body
D, [2017-10-25T12:41:40.978049 #91639] DEBUG -- : body: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Account Not Found</title>
<link rel="stylesheet" href="/stylesheets/application.css" />
</head>
<body class="indigo-bg">
<div role="main" class="large-content-area centered margin-t-xl text-center white">
<h1 class="h1">Oh, snap!</h1>
<p class="large">It looks like you've tried to access App without telling us which
account you belong to.</p>
<p class="large">To log in, try using your account's URL. Usually that looks
something like https://myaccount.app.com.</p>
</div>
</body>
</html>
Here is an example of one of the consumer tests. As you can see, we create a mock provider that has no URL/Path, so no place to provide a subdomain on the URL which specifies the account needed.
public class AdminImportedUserId {
#Rule
public PactProviderRuleMk2 mockProvider = new PactProviderRuleMk2("provider_app", PactSpecVersion.V2, this);
#Pact(provider = "provider_app", consumer = "consumer_app")
public RequestResponsePact createFragment(PactDslWithProvider builder) throws IOException {
return builder
.given("an admin with two imported users")
.uponReceiving("a get request for admin imported user id")
.path("/api/admin/users/imports/1")
.method("GET")
.headers(new ProviderClient().getHeaders())
.willRespondWith()
.status(200)
.body("{\"meta\":{},\"linked\":{\"contexts\":[{\"id\":1,\"class\":\"Domain\"}]},\"imports\":[{\"id\":\"160\","
+ "\"context_id\":\"1\",\"user_name\":\"user10 Royer\",\"context_description\":\"Dev Environment\","
+ "\"context_type\":\"Domain\",\"completed\":17,\"total\":17,\"state\":\"complete\",\"new_user_count\":0,"
+ "\"restored_user_count\":0,\"updated_user_count\":17,\"deleted_user_count\":0,\"ignored_user_count\":0,"
+ "\"deported_user_count\":17,\"invalid_rows\":[],\"created_at\":\"2017-09-23T13:13:21.132-06:00\","
+ "\"user_id\":4078}]}")
.toPact();
}
When you say "URL subdomain" are referring to a separate Host header e.g. someaccount.foo.com or a prefix on the URL e.g. `http://foo.com/someaccount'?
Either way, these would go into your consumer test as either the URL/Path or a specific header.
Related
Everyone, I am asking this because I really can't understand how I can send data from my webservice(vb.net) to my ionic app(android/ios/windows).
I used Firebase Cloud Messaging and it worked perfectly fine, but there's a case I need to handle and I wanted to use FCM but can't because it needs the internet connection.
Basically, I want to send a signal from one app to my localserver and then the localserver sends a post to another app via LAN, so I can't have an internet connection.
How can I achieve this?
Do I really need to use an external service to manage the connections to my devices?
this is what i did in receiving and reading the json from my own wcf.
import http:
import { Http } from '#angular/http';
add this to your constructor:
public http: Http
getting the data from uri:
this.http.get('http://your_url').map(res => res.text()).subscribe(data => {
console.log("XML MO: "+data.toString());
this.DataBind(data);
reading the response:
DataBind(data: any) {
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(data.toString(),"text/xml");
this.customerTitle = xmlDoc.getElementsByTagName("myData")
}
and in your html file:
<ion-item>
<ion-label floating>My Data</ion-label>
<ion-input enabled="false" type="text" [(ngModel)]="myData"></ion-input>
</ion-item>
you should also know that ion-input is a textfield. And it should work already
Latest Update Below at Update #5
I'm trying to implement AppLinks for BOTH my iOS AND Android apps : http://applinks.org
I've done the following:
setup a custom url scheme for my app: inacho://
Setup in my App Delegate: - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
Add meta tags to my website at http://www.nachorater.com :
<meta property="al:ios:app_store_id" content="581815579"/>
<meta property="al:ios:app_name" content="iNacho" />
<meta property="al:ios:url" content="inacho://default" />
I've verified that the url scheme works great by typing in a link like inacho://default into Notes and clicking the link it creates. Wa-la! It opens my app.
But when I try clicking on a link to www.nachorater.com from Facebook or Quip, neither app automatically seems to take any notice that the site has these app links setup and it just loads the website in their browser(s) instead of trying to open my app.
Has anyone got this working?
Update:
I had an issue with some meta tags not being in the < head > portion of my templates and I fixed it.
Now the link: http://www.nachorater.com from the iOS Facebook app adds a nice little popup that lets you open the url in the iNacho app like so:
But my links to my dynamic reviews do not seem to be working, yet the Debug app that Ming pointed out shows that the meta tags look correct for them.
For example, http://www.nachorater.com/getReview?reviewID=6396169718595584
meta tags when debugging with https://developers.facebook.com/tools/debug/og/object?q=http%3A%2F%2Fwww.nachorater.com%2FgetReview%3FreviewID%3D6396169718595584 :
Update #2:
I posted a new nacho review link to my iNacho Facebook timeline and then tried to click on it from the Facebook Mobile app.
It started to load the page and popped up the handy indicator that lets you open the app in iNacho but then once the page loaded, the indicator went away (before I could click it).
Update #3:
From the Facebook app, I can now trigger an inacho URL for my reviews BUT it's ONLY if I click the little popup to open in iNacho before it disappears. If I let the page completely load in Facebook's built-in web view, the little popup disappears still.
Is this a problem with Applinks? Or a problem with the Facebook app? Or by design and why?
Update #4:
I may know what the problem is. The review page in turn loads up a dynamic image for the nacho review. So by loading the page, it has an img src tag that points to a dynamic url that loads the image. Is this being mistaken for a 'redirect' action of some sort?
Example of img tag (rendered): <img width="300" src="/getReviewImage?imageID=6125868501958656"></img>
Note: There are a bunch of other scripts/ajax that gets loaded dynamically too though (Facebook and twitter widgets and the like).
Is this a bug in AppLinks or the Facebook Mobile app? Shouldn't it not care about background loading objects like ajax and dynamic images?
Update #5
7/15/14 - This is still happening with latest Facebook app. When I click a link from my iNacho Facebook page to my iNacho website, it pops up the option to open it in the app for a split second before the page finishes loading. Then it hides it.
As for the twitter app, it does not even give me the popup for a split second. It doesn't seem to recognize the link is appslink enabled at all.
Quip on the other hand, I pasted a nacho link in and the first time I clicked on it, it went to its built-in safari with no option to open in my app. BUT the second time I clicked it, it directly opened my app instead.
Summary: So far, it seems like maybe some apps are implementing the AppLinks Navigation portion incorrectly or something. Quip seems to work but even Facebook's own app seems like it's not working.
I was having the same problem with AppLinks and decided to just forego them altogether and just use facebook's app link host: https://developers.facebook.com/docs/applinks/hosting-api
My app is really mobile only, and I misunderstood how AppLinks worked at first. I thought I could just put the al_ios_* meta tags on a single, universal web page but this is wrong. There would need to be a separate page for every piece of content on my site, and each one of those pages needs to have its own AppLinks meta tags to send a URL for that specific content back to my app.
When I was doing it wrong, when I tapped on my OpenGraph story in facebook, it would open my site in the web browser and there was an action icon in the bottom toolbar that I could tap and have the option to open my app. Or I would have to precision-tap the name of my app in the OpenGraph story. Either of those fast-switch to my app, but the URL would not be specific to the content I want my app to navigate to. Also, both of those options suck -- I just want to tap anywhere on the story and go straight to my app, which is why we're all here.
The solution
I am going to use an OpenGraph story with the share dialog as an example.
First, you need to create a hosted app link on your server, not in the app. Before creating your OpenGraph story or whatever is being shared, make a call to your server to accomplish 2 things:
1.) Make an API call to create a new facebook app link, which will give you back an ID
2.) Use that ID to make a 2nd API call to get the URL to your hosted app link
This has to be done on the server because these API calls require an app access token, not a user access token. This token has app level permissions, not user level permissions. You cannot and should not store your facebook app secret anywhere in your mobile application because someone could decompile your app and make changes to your facebook app. No good. Use your server because it can safely know your app secret.
My server side is in PHP so here is an example of how to accomplish this. Dealing with the API wasn't a particularly pleasant experience, so I'll share in hopes that it helps someone else with formatting the requests:
# create a new facebook app link using cURL
$metadata = <what to handle in AppDelegate application:openURL:sourceApplication:annotation>;
$url = "https://graph.facebook.com/v2.1/app/app_link_hosts";
$ch = curl_init($url);
# create form post data
$deepLinkURL = "<myApp>://" . $metadata;
$iosArray = json_encode(array(array("url" => $deepLinkURL,
"app_store_id" => <appStoreId (number)>,
"app_name" => "<myAppName>")
)
);
$webFallbackArray = json_encode(array("should_fallback" => false));
$formQuery = http_build_query(array("access_token" => "<appId>|<appSecret>",
"name" => $metadata,
"ios" => $iosArray,
"web" => $webFallbackArray)
);
# options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $formQuery);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
# get response
$responseJson = curl_exec($ch);
curl_close($ch);
# decode response from facebook
$jsonResponse = json_decode($responseJson, true);
$appLinkId = "";
# get appLinkId
foreach ($jsonResponse as $key => $val) {
# get status
if($key == "id") {
$appLinkId = $val;
}
}
# if response is good, need to request canonical URL from appLinkId
$errorMessage = "";
$canonicalUrl = "";
if(!empty($appLinkId)) {
# create another instance of cURL to get the appLink object from facebook using the ID generated by the previous post request
$getAppLinkUrl = "https://graph.facebook.com/" . $appLinkId;
$ch2 = curl_init();
# cURL options
$queryString = http_build_query(array("access_token" => "<appId>|<appSecret>",
"fields" => "canonical_url",
"pretty" => true)
);
curl_setopt($ch2, CURLOPT_URL, $getAppLinkUrl . "?" . $queryString);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
# get response
$urlResponseJson = curl_exec($ch2);
curl_close($ch2);
# decode response from facebook
$urlJsonResponse = json_decode($urlResponseJson, true);
# parse response to get canonical URL
foreach ($urlJsonResponse as $key => $val) {
# get canonical URL
if($key == "canonical_url") {
$canonicalUrl = $val;
}
}
# check for result
if(empty($canonicalUrl)) {
$errorMessage = "Unable to retreive URL.";
}
} else {
$errorMessage = "Unable to publish appLink.";
}
# encode response back to your app
if(empty($errorMessage)) {
$response = json_encode(array("result" => "success",
"canonical_url" => $canonicalUrl));
} else {
$response = json_encode(array("result" => "failed",
"errorMessage" => $errorMessage));
}
#send response back to your app
Back in your app, once you confirm a good response, put the canonical URL you get back as the url parameter in [FBGraphObject openGraphObjectForPostWithType: below. Now when you click on your story in the facebook app, it will go straight to your app. No web nonsense.
// Create an action
id<FBOpenGraphAction> action = (id<FBOpenGraphAction>)[FBGraphObject graphObject];
// Create an object
id<FBGraphObject> object;
// set shareDialog parameters
FBOpenGraphActionParams *params = [[FBOpenGraphActionParams alloc] init];
params.action = action;
params.actionType = #"<myApp>:<myAction>";
params.previewPropertyName = #"<key>";
object = [FBGraphObject openGraphObjectForPostWithType:#"<myApp>:<myObject>"
title:<title>
image:<urlToPic>
url:<fb.me/xyz canonical URL>
description:<someDescription>];
[action setObject:object forKey:#"<key>"];
etc...
When I was working on my app, Sweep, I put a pay/share wall after a certain amount of time spent in the app. I faced the same problem where AppLinks really sucked at actually linking off of Facebook, despite the promise. Based on this problem, I built a service called branch.io that hosts the links for me, plus automatically inserts the correct AppLinks metatags for Android/iOS. The links actually work as expected, as crazy as that is. It uses a combination of client side JS with the AppLinks to make them properly redirect in every webview and native browser
Here's a high level guide to creating the share links on iOS:
To get started, you just need to configure the location of your app in either store on the dashboard at dashboard.branch.io. Once it's all setup, you get your Branch app key.
pod "Branch" or you can clone the open source repo here:
https://github.com/BranchMetrics/Branch-iOS-SDK
Add the Branch key to your plist file as a String with the key 'branch_key'
Add the following code to your AppDelegate in the appropriate methods
In the didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// your other init code
Branch *branch = [Branch getInstance];
[branch initSessionWithLaunchOptions:launchOptions andRegisterDeepLinkHandler:^(NSDictionary *params, NSError *error) { // previously initUserSessionWithCallback:withLaunchOptions:
if (!error) {
// params are the deep linked params associated with the link that the user clicked before showing up
// params will be empty if no data found
// here is the data from the example below if a new user clicked on Joe's link and installed the app
NSString *name = [params objectForKey:#"user"]; // returns Joe
NSString *profileUrl = [params objectForKey:#"profile_pic"]; // returns https://s3-us-west-1.amazonaws.com/myapp/joes_pic.jpg
NSString *description = [params objectForKey:#"description"]; // returns Joe likes long walks on the beach...
// route to a profile page in the app for Joe
// show a customer welcome
}
}];
}
In the openUrl for handling URI calls:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
// pass the url to the handle deep link call
// if handleDeepLink returns YES, and you registered a callback in initSessionAndRegisterDeepLinkHandler, the callback will be called with the data associated with the deep link
if (![[Branch getInstance] handleDeepLink:url]) {
// do other deep link routing for the Facebook SDK, Pinterest SDK, etc
}
return YES;
}
Lastly, to create the hosted links, it's very simple. You just need to call getShortUrl to dynamically create one. You can put as many keys and values in the links as possible (to be retrieved in the initSession callback)
You can put this snippet anywhere you want to create a link:
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
[params setObject:#"Joe" forKey:#"user"];
[params setObject:#"url.to.picture/mypic.png" forKey:#"profile_pic"];
[params setObject:#"Joe likes long walks on the beach..." forKey:#"description"];
// Customize the display of the link
[params setObject:#"Joe's MyApp Referral" forKey:#"$og_title"];
[params setObject:#"url.to.picture/mypic.png" forKey:#"$og_image_url"];
[params setObject:#"Join Joe in MyApp - it's awesome" forKey:#"$og_description"];
// Customize the redirect performance
[params setObject:#"http://myapp.com/desktop_splash" forKey:#"$desktop_url"];
Branch *branch = [Branch getInstance];
[branch getShortURLWithParams:params andCallback:^(NSString *url, NSError *error) {
// show the link to the user or share it immediately
}];
Android is very similar in method calls and functionality and can be found on the site.
sorry if my answer is not exactly what you expect but just to share what we did on our websites and apps.
For instance, I know we had to add more tags to make it works with twitter cards and here is the list of the meta properties we have in our pages:
meta property="twitter:card" content=""
meta property="twitter:title" content=""
meta property="twitter:description" content=""
meta property="twitter:image:src" content=""
meta property="twitter:app:id:iphone" content=""
meta property="twitter:app:name:iphone" content="Marmiton"
meta property="twitter:app:url:iphone" content=""
meta property="twitter:app:id:googleplay" content=""
meta property="twitter:app:name:googleplay" content=""
meta property="twitter:app:url:googleplay" content=""
and the metha you also have:
meta property="al:iphone:app_store_id" content=""
meta property="al:iphone:app_name" content=""
meta property="al:iphone:url" content=""
meta property="al:android:package" content=""
meta property="al:android:app_name" content=""
meta property="al:android:url" content=""
we also have the facebook opengraph meta defined such as fb:app_id. I mention that because when you receive the deeplink in your app, you also have the facebook app id in the applinks link.
And from what we tested:
facebook does not open the deeplink directly on iOS whereas Android gives you the app choice. It sometimes shows up the blue popup at the bottom of the screen and sometimes you just have a link added in the actionsheet you have when you tap on the share button in the facebook (safari) webview (only at first load)-> this presentation of the link depends on how the content was shared on facebook.
twitter add a link to the app inside the card on iOS.
Don't know what I can add more.
Hope it helps a bit.
I put this add action in my spoutnik controller like the REST doc of cakephp :
public function add() {
$this->layout = null;
$this->autoRender = false;
if ($this->Spoutnik->save($this->request->data)) {
$message = array(
'text' => __('Saved'),
'type' => 'success'
);
} else {
$message = array(
'text' => __('Error'),
'type' => 'error'
);
}
$this->set(array(
'message' => $message,
'_serialize' => array('message')
));
}
I put this JS part in my angularjs app (actually in a other domain than the cakephp site):
<form ng-controller="MessageController" ng-submit="createMessage()">
<legend>Create Message</legend>
<label>Title</label>
<input type="text" id="name" name="name" ng-model="message.name" placeholder="Title">
<label>Message</label>
<input type="text" id="email" name="email" ng-model="message.email" placeholder="ur message here">
<button class="btn btn-primary">Add</button>
</form>
and
function MessageController($scope, $http) {
$scope.message = {};
$scope.createMessage = function() {
$http({
method : 'POST',
url : 'http://www.mycakephpdomain.com/spoutnik/add',
data : $scope.message
})
}
}
Nothing work... i have no errors in chrome console, i'm totally lost :/ I just want to build an android app in angularjs with no java or PHP, and post to my cakephp website. For the moment, i try to post form an other domain (i can't touch apache configuration).
What is wrong in my code ?
Just for the record and debugging purposes:
I did not find the reason to this same problem, but looking the AJAX request done by AngularJS I found that message data from the form was no being sent as regular form data. Instead it was being sent as REQUEST PAYLOAD.
Indeed, the response from the server contained this error just before the JSON response from my view:
Warning (4096): Argument 1 passed to Hash::get() must be of the type
array, null given, called in
/var/www/test/lib/Cake/Network/CakeRequest.php on line 866 and defined
[CORE/Cake/Utility/Hash.php, line 44]
Of course, i checked that there was nothing strange by my side executed, I even tried disabling all security component and allowing AUTH *.
If you set the core.debug in php to 0, the error wont be shown and
everything will be ok, but thats not what you want for your awesome
app.*
I changed query data from $scope.message to just $('form').serialize(), but still no way.
So finally, the only solution I found was to remove the $http.post and replace it by a very know $.ajax() which just did its job as always...
So thats my suggestion, remove the $http.post and user common jQuery.ajax();
There is much confusion among newcomers to AngularJS as to why the $http service shorthand functions ($http.post(), etc.) don’t appear to be swappable with the jQuery equivalents (jQuery.post(), etc.) The difference is in how jQuery and AngularJS serialize and transmit the data. Fundamentally, the problem lies with your server language of choice being unable to understand AngularJS’s transmission natively ... By default, jQuery transmits data using Content-Type: x-www-form-urlencoded and the familiar foo=bar&baz=moe serialization. AngularJS, however, transmits data using Content-Type: application/json and { "foo": "bar", "baz": "moe" } JSON serialization, which unfortunately some Web server languages—notably PHP—do not unserialize natively.
So concretely, your $_POST variable is empty !
To go through this problem there're 2 solutions:
Change the data format in Angular config
Change the way to get the datas with PHP(Deprecated but works)
I haven't invented anything here, just linking...
Hope it'll help.
Ive been scratching my head with this for a few days now.
I have written a mobile specific website using plain old html and jquery.
It used ajax with json responses to get data from a service written using service stack.
all works perfectly fine from desktop and lots of different mobile i have tried (android, iphone, bb etc)
However there seems to be a specific issue with my handset (Samsung Galaxy S2 on vodafone)
When the handset is on wifi the ajax works perfectly and the json object is received from the service and processed correctly.
However when on mobile data the response does not come back as json but as the service stack web page (it looks like its not being told to return json correctly)
Im wondering if the headers could be being stripped out by vodafone or someting?
this is the ajax call being used
$.ajax({
url: sgee.ApiUrl + "/api/GetRegionId/" + sgee.App.postcode,
type: 'GET',
dataTye: 'json',
contentType: "application/json;charset=utf-8",
cache: false,
success: function (data) {
if (data.success) {
sgee.App.EnquiryId = data.enquiryId;
sgee.App.RegionId = data.regionId;
sgee.App.RegionName = data.regionName;
$("#regionTxt").html("We have identified that you live in the " + sgee.App.RegionName + " supply region.");
sgee.EndLoading(250);
sgee.HideStep(2);
} else {
sgee.SetValidationError("#pcodeControl", "Please enter a valid UK postcode");
}
},
error: function () {
sgee.SetValidationError("#pcodeControl", "Please enter a valid UK postcode");
sgee.SendError("Error on /api/GetRegionId/", "sgee.Step1");
},
complete: function () {
}
});
This is the data expected
{"postCode":"s63","regionId":14,"regionName":"YORKSHIRE","enquiryId":578106,"success":true,"returnedId":0}
and when running on mobile this is what i am receiving (ill not include the whole as it is long but it is just the html response as if i hadnt set the response type or browsed to the page)
<!doctype html>
<html lang="en-us">
<head>
<title>GetRegionId Snapshot of 03/08/2012 13:59:50</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
This really is driving me mad as it is impossible to debug (at least i cant find a way) i am using the android chrome remote developer tools to step through code but i cant capture the http request and response as it is on the mobile network.
Just guessing... But you're expecting json content right? If so, why is your response "text/html" instead of "application/json"?
You have a typo in there... "dataTye: 'json',". Could this be it?
I think is due to type of form submission. use post instead of get...
I wanted to know the answer to a simple question but i have'nt found a good one
(i've google it for hours :) )
I'm playing with the sl4a with python and i can send events from js to the python script, but the js is not catching the eventPost i put in the code below from python to js.
Anyone knows how is this been done or if there is another way without the registerCallback?
HTML CODE :
<html>
<head>
<script>
var droid = new Android();
function doit(){
droid.makeToast("Text send :=>"+document.getElementById("msg").value);
droid.eventPost("doit",document.getElementById("msg").value);
}
function alert_me(data){
droid.makeToast("All done!");
document.getElementById("msg").value = '';
}
droid.registerCallback("done",alert_me);
</script>
</head>
<body>
<input type="text" name="boton" id="msg" value="" />
<input type="button" name="boton" value="Go!" onclick="javascript:doit()" />
</body>
</html>
PYTHON CODE:
import android,time
if __name__ == '__main__' :
droid = android.Android()
droid.webViewShow("file:///sdcard/sl4a/scripts/sample.html")
while True:
event = droid.eventWait().result
if event["name"] == 'doit':
droid.makeToast("Event catched! %s" % event['data'])
droid.eventPost("done","Done message")
time.sleep(2)
droid.exit()
This is simple to get working, but isn't obvious or well documented.
First you want to get a hook to the Android object inside the webview. Then you can use it to register one or more callbacks. For a simple example, we'll just do one that pops an alert with a message from Python.
var droid = new Android();
droid.registerCallback("echo", function(msg) {
alert(msg.data)
});
In this case, echo is the name of the event type you want this callback to handle. So this will handle 'echo events'. The event names are arbitrary strings, just call them whatever makes sense.
In the Python script that launched the webview, you can now post events to the registered handler whenever you like.
droid.eventPost("echo", "hello world")
The second argument here is the message you want to pass to the JavaScript callback.
Note that although you pass the message back as a string, it arrives in the JavaScript function as an object. That object, we're calling it msg above, has an attribute called data which contains the string you passed from the Python side.
Unfortunately I have never personally been able to get this working, using both registerCallback() and eventWaitFor(). However, if you are still keen on getting this working, I strongly recommend you head on over and download sl4a_r5x – an unofficial but newer and updated release of SL4A. In it is support for using FullScreenUi's based off the same xml code that native Android apps use. With this you can do what you're after and examples can be found on the page.Hopefully this has been helpful and you're still interested in SL4A!