Tôi tin rằng có thể gọi các phương thức Java từ (PhoneGap) Javascript.
Có ai biết cách làm điều đó không ?? (Tôi biết cách làm điều đó bằng cách thay đổi mã nguồn của PhoneGap, nhưng tôi muốn tránh điều đó)
Câu trả lời:
Cuối cùng tôi đã làm cho nó hoạt động.
Tạo một lớp với các phương thức bạn muốn sử dụng:
public class MyClass {
private WebView mAppView;
private DroidGap mGap;
public MyClass(DroidGap gap, WebView view)
{
mAppView = view;
mGap = gap;
}
public String getTelephoneNumber(){
TelephonyManager tm =
(TelephonyManager) mGap.getSystemService(Context.TELEPHONY_SERVICE);
String number = tm.getLine1Number();
return number;
}
}
Trong hoạt động chính của bạn, hãy thêm giao diện Javascript cho lớp này:
public class Main extends DroidGap
{
private MyClass mc;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.init();
mc = new MyClass(this, appView);
appView.addJavascriptInterface(mc, "MyCls");
super.loadUrl(getString(R.string.url));
}
}
Trong cửa sổ gọi Javascript, các phương thức MyCls:
<script>
$(function(){
$("#phone").text("My telephone number is: " +
window.MyCls.getTelephoneNumber());
});
</script>
Ghi chú:
Như đã đề cập trong nhận xét, đối với Android phiên bản 4.2 trở lên, hãy thêm @JavascriptInterface
vào phương thức bạn muốn truy cập từ trang HTML của mình. Tham khảo .
addJavaScriptInterface(mc, "MyCls")
không có Gap init()
ed có thể khiến ứng dụng bị nghiền nát, bạn nên thêm super.init()
trướcaddJavascriptInterface()
public class Main extends DroidGap
{
private MyClass mc;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.init();
mc = new MyClass(this, appView);
appView.addJavascriptInterface(mc, "MyCls");
super.loadUrl(getString(R.string.url));
}
}
PhoneGap có một API Plugin khá. Bạn sẽ viết plugin bằng Java bằng cách triển khai giao diện IPlugin. Hầu hết phép thuật nằm trong hàm execute ().
public interface IPlugin {
/**
* Executes the request and returns PluginResult.
*
* @param action The action to execute.
* @param args JSONArry of arguments for the plugin.
* @param callbackId The callback id used when calling back into JavaScript.
* @return A PluginResult object with a status and message.
*/
PluginResult execute(String action, JSONArray args, String callbackId);
// ... more ...
}
Cách tốt nhất để bắt đầu viết một plugin là viết API javascript trước. Thông thường, bạn sẽ bắt đầu bằng cách viết một lớp javascript tùy chỉnh và trong mỗi phương thức trên lớp javascript, điều chỉnh các biến và gọi vào plugin mà bạn đã phát triển bằng phương thức Phonegap.exec (). Đây là chữ ký phương pháp để bạn tham khảo.
/* src/com/phonegap/api/PluginManager.java */
/**
* Receives a request for execution and fulfills it by finding the appropriate
* Java class and calling it's execute method.
*
* PluginManager.exec can be used either synchronously or async. In either case, a JSON encoded
* string is returned that will indicate if any errors have occurred when trying to find
* or execute the class denoted by the clazz argument.
*
* @param service String containing the service to run
* @param action String containt the action that the class is supposed to perform. This is
* passed to the plugin execute method and it is up to the plugin developer
* how to deal with it.
* @param callbackId String containing the id of the callback that is execute in JavaScript if
* this is an async plugin call.
* @param args An Array literal string containing any arguments needed in the
* plugin execute method.
* @param async Boolean indicating whether the calling JavaScript code is expecting an
* immediate return value. If true, either PhoneGap.callbackSuccess(...) or
* PhoneGap.callbackError(...) is called once the plugin code has executed.
*
* @return JSON encoded string with a response message and status.
*/
@SuppressWarnings("unchecked")
public String exec(final String service, final String action,
final String callbackId, final String jsonArgs,
final boolean async)
Bạn cũng cần đăng ký Plugin. Bạn thực hiện việc này bằng cách thêm mã đăng ký vào cuối thư viện javascript tùy chỉnh của mình.
Trong ví dụ dưới đây, tác giả đã định nghĩa một lớp BarcodeScanner trong javascript và đăng ký nó bằng phương thức addConstructor.
Hai bước được thực hiện trong addConstructor:
Tạo một phiên bản mới của BarcodeScanner trong javascript và đăng ký nó. Điều này có thể truy cập được bằng javascript dưới dạng window.plugins.barcodeScanner
Đăng ký lớp Plugin tùy chỉnh với tên dịch vụ. Tên dịch vụ này được chuyển vào làm đối số đầu tiên cho PhoneGap.exec để PhoneGap có thể khởi tạo lớp plugin java và gọi phương thức execute () trên đó.
Mã đăng ký mẫu:
PhoneGap.addConstructor(function() {
/* The following registers an instance of BarcodeScanner in window.plugins.barcodeScanner */
PhoneGap.addPlugin('barcodeScanner', new BarcodeScanner());
/* The following associates a service name BarcodeScanner with a class com.beetight.barcodescanner.BarcodeScanner */
/* The service name is the first argument passed into PhoneGap.exec */
PluginManager.addService("BarcodeScanner","com.beetight.barcodescanner.BarcodeScanner");
});
một hình thức đơn giản hơn:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.init();
super.appView.getSettings().setJavaScriptEnabled(true);
super.appView.addJavascriptInterface(this, "MyCls");
super.loadUrl("file:///android_asset/www/login.html");
}
Nếu bất kỳ ai nhận được ngoại lệ nullPointer bằng cách sử dụng mã trên, hãy thực hiện super.oncreate () trước rồi đến super..init ()
super.onCreate(savedInstanceState);
super.init();
Tôi tìm thấy giải pháp này ở đây: Phonegap Google Group
Cảm ơn rất nhiều đến @ zorglub76 về giải pháp ....
Giao tiếp từ JavaScript sang gốc được thực hiện bằng cách ghi đè hàm nhắc JavaScript trong mã gốc của Android và thông báo được truyền giống như được sử dụng trong iOS. Chúng tôi đã từng sử dụng WebView.addJavascriptInterface để thêm các đối tượng Java trực tiếp vào hộp cát JavaScript nhưng điều đó đã khiến một số thiết bị gặp sự cố với Android 2.3. Để gọi JavaScript từ bản gốc, chúng tôi hiện đang sử dụng WebView.loadUrl (”javascript:…”) nhưng điều đó có một số vấn đề nên chúng tôi sẽ sớm chuyển sang bỏ phiếu hàng đợi thông báo Java gọi một máy chủ HTTP cục bộ thông qua kết nối XHR lâu đời.