Reputation: 704
I am trying to use an Android Webview to display some "active" content (sets of images that vary depending on some input settings). The content will be local (offline).
I would like to use Angular.js to control the media that will be displayed on the page.
So, to the problem... how can my Angular app receive JSON data on startup? The problem that I see is that the webview does not allow angular to lazy load additional files (I already ran into this while trying to use html templates for a custom directive. This required enclosing the HTML templates into the single HTML file).
My Android activity can write out the options somewhere, but how is Angular going to be able to read them? In other words, is there a way around the security settings of the webview which does not allow Angular.js to lazy load additional files?
Upvotes: 4
Views: 4020
Reputation: 704
I think that I've figured this one out. I realized that I can create a method in my Android Java code that is exposed to JavaScript (via @JavascriptInterface). This would allow me to call this method from my AngularJS app to get the JSON in a string (see this link for info on JavascriptInterface: http://developer.android.com/guide/webapps/webview.html). I'll post some code once I've proven that this works.
Here is the code. It works great.
MainActivity.java
public class MainActivity extends Activity {
private String MY_JSON_EXAMPLE = "{\"name\":\"John Doe\",\"email\":\"[email protected]\"}";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView wv = (WebView) findViewById(R.id.myWebView);
wv.getSettings().setJavaScriptEnabled(true);
wv.addJavascriptInterface(this, "AndroidMainAct");
wv.loadUrl("file:///android_asset/mypage.html");
}
@JavascriptInterface
public String getMyJSONData() {
return MY_JSON_EXAMPLE;
}
}
mypage.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Hello World, AngularJS</title>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body>
<h3>Load Test</h3>
<div ng-controller="MyController">
<div id="dataWaiting" ng-show="!myData.length">
Loading JSON...
</div>
<div id="dataLoaded" ng-show="myData.length">
Data Loaded: {{myData}}
</div>
</div>
</body>
</html>
app.js
var myApp=angular.module('myApp',[]);
myApp.controller('MyController', ['$scope', function($scope) {
$scope.myData = '';
this.loadData = function() {
// get the data from android
return AndroidMainAct.getMyJSONData();
};
$scope.myData = this.loadData(); // load data on instantiation
}]);
Exposing the data through the android JavascriptInterface method works great.
Upvotes: 5