2010-04-28 39 views
77

Tôi tin rằng có thể gọi các phương thức Java từ (PhoneGap) Javascript.Giao tiếp giữa Android Java và Phonegap Javascript?

Bất kỳ ai cũng biết cách thực hiện điều đó? (Tôi biết làm thế nào để 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 đó)

Trả lời

125

Cuối cùng tôi đã làm cho nó hoạt động.

  • Tạo một lớp học với phương pháp 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 thêm một 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ổ cuộc gọi Javascript. Phương pháp MyCls:

    <script> 
        $(function(){ 
        $("#phone").text("My telephone number is: " + 
          window.MyCls.getTelephoneNumber()); 
        }); 
    </script> 
    

Lưu ý:

Như đã đề cập trong các bình luận, dành cho Android phiên bản 4.2 trở lên, thêm @JavascriptInterface với phương pháp mà bạn muốn truy cập từ trang HTML của bạn. Reference.

+0

hmm, ví dụ này là rất tốt, nhưng tôi nhận được một ngoại lệ nullpointer trên appView, nó có vẻ là null. Nơi nào bạn intialise đối tượng? – dan

+1

Nó không hoạt động trừ khi các phương thức được công khai! lam tôt lăm! – dan

+1

thêm super.init(); như @Karfield được đề cập bên dưới đã sửa ngoại lệ nullpointer cho tôi. –

9

PhoneGap có API plugin phong nha. Bạn sẽ viết plugin trong Java bằng cách triển khai giao diện IPlugin. Hầu hết phép thuật là 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 plugin là viết javascript API trước. Bạn sẽ bắt đầu điển hình 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, sắp xếp các biến và gọi vào plugin bạn đã phát triển bằng cách sử dụng phương thức Phonegap.exec(). Đây là chữ ký phương thức để 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 phải đăng ký Plugin. Bạn làm điều này bằng cách thêm mã đăng ký ở cuối thư viện javascript tùy chỉnh của bạn.

Trong ví dụ bên dưới, tác giả đã xác định lớp BarcodeScanner javascript và đăng ký nó bằng phương thức addConstructor.

Hai bước được thực hiện trong addConstructor:

  1. Tạo một thể hiệ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

  2. Đăng ký lớp Plugin tùy chỉnh có tên dịch vụ. Tên dịch vụ này được chuyển thành đố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ã số đă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"); 
}); 
+0

Phiên bản của phonegap nào, mẫu này dành cho? Tôi nghĩ bạn đang nói về dưới 2.0. Đúng? –

14

addJavaScriptInterface(mc, "MyCls") mà không Gap init() ed có thể gây ra tình cảm của ứng dụng, bạn nên thêm super.init() trước addJavascriptInterface()

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)); 
    } 
} 
+1

FYI, tôi vừa chỉnh sửa các thay đổi của bạn thành câu trả lời của zorglub76. –

+1

Câu trả lời này cần chỉnh sửa thích hợp. Bất kỳ ai? – Rajkiran

5

Nếu người nào bị nullPointer ngoại lệ sử dụng mã ở trên, hãy thực hiện super.oncreate() trước và sau đó là 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 cho các giải pháp ....

6

một hình thức đơn giả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"); 
} 
0

Thông tin từ hoạt Javascript để mẹ đẻ được thực hiện bằng cách ghi đè chức năng nhắc lệnh JavaScript trong mã gốc của Android và thông điệp đượ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ừ nguồn gốc, chúng tôi hiện đang sử dụng WebView.loadUrl (”javascript:…”) ​​nhưng 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áy chủ HTTP cục bộ qua kết nối XHR tồn tại lâu dài.

Description by here

Các vấn đề liên quan